inversion 1.3.1 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/Examples.md +134 -0
  4. data/GettingStarted.md +50 -0
  5. data/Guide.md +14 -0
  6. data/{History.rdoc → History.md} +59 -43
  7. data/{README.rdoc → README.md} +43 -34
  8. data/Tags.md +555 -0
  9. data/bin/inversion +4 -8
  10. data/lib/inversion/cli/api.rb +75 -0
  11. data/lib/inversion/cli/tagtokens.rb +34 -0
  12. data/lib/inversion/cli/tree.rb +70 -0
  13. data/lib/inversion/cli.rb +406 -0
  14. data/lib/inversion/exceptions.rb +0 -1
  15. data/lib/inversion/mixins.rb +10 -11
  16. data/lib/inversion/parser.rb +5 -6
  17. data/lib/inversion/refinements.rb +18 -0
  18. data/lib/inversion/renderstate.rb +24 -25
  19. data/lib/inversion/sinatra.rb +0 -1
  20. data/lib/inversion/template/attrtag.rb +7 -5
  21. data/lib/inversion/template/begintag.rb +0 -1
  22. data/lib/inversion/template/calltag.rb +0 -1
  23. data/lib/inversion/template/codetag.rb +37 -28
  24. data/lib/inversion/template/commenttag.rb +0 -1
  25. data/lib/inversion/template/configtag.rb +3 -4
  26. data/lib/inversion/template/containertag.rb +1 -2
  27. data/lib/inversion/template/defaulttag.rb +1 -2
  28. data/lib/inversion/template/elsetag.rb +0 -1
  29. data/lib/inversion/template/elsiftag.rb +0 -1
  30. data/lib/inversion/template/endtag.rb +2 -3
  31. data/lib/inversion/template/escapetag.rb +1 -2
  32. data/lib/inversion/template/fortag.rb +2 -3
  33. data/lib/inversion/template/fragmenttag.rb +1 -2
  34. data/lib/inversion/template/iftag.rb +3 -1
  35. data/lib/inversion/template/importtag.rb +2 -3
  36. data/lib/inversion/template/includetag.rb +1 -2
  37. data/lib/inversion/template/node.rb +4 -5
  38. data/lib/inversion/template/pptag.rb +1 -2
  39. data/lib/inversion/template/publishtag.rb +2 -3
  40. data/lib/inversion/template/rescuetag.rb +1 -2
  41. data/lib/inversion/template/subscribetag.rb +3 -4
  42. data/lib/inversion/template/tag.rb +3 -4
  43. data/lib/inversion/template/textnode.rb +1 -2
  44. data/lib/inversion/template/timedeltatag.rb +1 -2
  45. data/lib/inversion/template/unlesstag.rb +0 -1
  46. data/lib/inversion/template/uriencodetag.rb +1 -2
  47. data/lib/inversion/template/yieldtag.rb +0 -1
  48. data/lib/inversion/template.rb +18 -22
  49. data/lib/inversion/tilt.rb +1 -2
  50. data/lib/inversion.rb +2 -3
  51. data/lib/roda/plugins/inversion.rb +225 -0
  52. data/spec/helpers.rb +19 -13
  53. data/spec/inversion/mixins_spec.rb +1 -1
  54. data/spec/inversion/parser_spec.rb +1 -1
  55. data/spec/inversion/refinements_spec.rb +22 -0
  56. data/spec/inversion/renderstate_spec.rb +1 -1
  57. data/spec/inversion/sinatra_spec.rb +1 -1
  58. data/spec/inversion/template/attrtag_spec.rb +1 -1
  59. data/spec/inversion/template/begintag_spec.rb +1 -1
  60. data/spec/inversion/template/calltag_spec.rb +1 -1
  61. data/spec/inversion/template/codetag_spec.rb +24 -1
  62. data/spec/inversion/template/commenttag_spec.rb +1 -1
  63. data/spec/inversion/template/configtag_spec.rb +1 -1
  64. data/spec/inversion/template/containertag_spec.rb +1 -1
  65. data/spec/inversion/template/defaulttag_spec.rb +1 -1
  66. data/spec/inversion/template/elsetag_spec.rb +1 -1
  67. data/spec/inversion/template/elsiftag_spec.rb +1 -1
  68. data/spec/inversion/template/endtag_spec.rb +1 -1
  69. data/spec/inversion/template/escapetag_spec.rb +1 -1
  70. data/spec/inversion/template/fortag_spec.rb +1 -1
  71. data/spec/inversion/template/fragmenttag_spec.rb +1 -1
  72. data/spec/inversion/template/iftag_spec.rb +1 -1
  73. data/spec/inversion/template/importtag_spec.rb +1 -1
  74. data/spec/inversion/template/includetag_spec.rb +1 -1
  75. data/spec/inversion/template/node_spec.rb +1 -1
  76. data/spec/inversion/template/pptag_spec.rb +1 -1
  77. data/spec/inversion/template/publishtag_spec.rb +1 -1
  78. data/spec/inversion/template/rescuetag_spec.rb +1 -1
  79. data/spec/inversion/template/subscribetag_spec.rb +1 -1
  80. data/spec/inversion/template/tag_spec.rb +1 -1
  81. data/spec/inversion/template/textnode_spec.rb +1 -1
  82. data/spec/inversion/template/timedeltatag_spec.rb +1 -1
  83. data/spec/inversion/template/unlesstag_spec.rb +1 -1
  84. data/spec/inversion/template/uriencodetag_spec.rb +1 -1
  85. data/spec/inversion/template/yieldtag_spec.rb +1 -1
  86. data/spec/inversion/template_spec.rb +1 -1
  87. data/spec/inversion/tilt_spec.rb +1 -1
  88. data/spec/inversion_spec.rb +1 -1
  89. data/spec/roda/plugins/inversion_spec.rb +91 -0
  90. data.tar.gz.sig +0 -0
  91. metadata +90 -58
  92. metadata.gz.sig +0 -0
  93. data/Examples.rdoc +0 -134
  94. data/GettingStarted.rdoc +0 -44
  95. data/Guide.rdoc +0 -47
  96. data/Manifest.txt +0 -86
  97. data/Rakefile +0 -7
  98. data/Tags.rdoc +0 -560
  99. data/lib/inversion/command.rb +0 -278
  100. data/lib/inversion/monkeypatches.rb +0 -21
  101. data/spec/inversion/monkeypatches_spec.rb +0 -25
@@ -1,278 +0,0 @@
1
- # -*- ruby -*-
2
- # frozen_string_literal: true
3
- # vim: set noet nosta sw=4 ts=4 :
4
-
5
- require 'logger'
6
- require 'trollop'
7
- require 'highline'
8
- require 'sysexits'
9
- require 'shellwords'
10
-
11
- require 'inversion' unless defined?( Inversion )
12
-
13
-
14
- # Command class for the 'inversion' command-line tool.
15
- class Inversion::Command
16
- extend Sysexits
17
-
18
- # The list of valid subcommands
19
- SUBCOMMANDS = %w[api tagtokens tree]
20
-
21
- # Class-instance variable for the HighLine prompt object
22
- @prompt = nil
23
-
24
-
25
- ### Run the command
26
- def self::run( args )
27
- opts, args = self.parse_options( args )
28
- subcommand = args.shift
29
-
30
- command = self.new( opts )
31
- command.run( subcommand, args )
32
- rescue => err
33
- $stderr.puts "%p: %s" % [ err.class, err.message ]
34
- $stderr.puts( err.backtrace.join("\n ") ) if opts && opts.debug
35
- end
36
-
37
-
38
- ### Fetch the HighLine instance for the command, creating it if necessary.
39
- def self::prompt
40
- unless @prompt
41
- @prompt = HighLine.new
42
- @prompt.page_at = @prompt.output_rows - 5
43
- @prompt.wrap_at = @prompt.output_cols - 2
44
- end
45
-
46
- @prompt
47
- end
48
-
49
-
50
- ### Create an option parser for the command and return it
51
- def self::create_option_parser
52
- pr = self.prompt
53
- progname = pr.color( File.basename($0), :bold, :yellow )
54
-
55
- return Trollop::Parser.new do
56
- version Inversion.version_string( true )
57
-
58
- banner (<<-END_BANNER).gsub(/^\t+/, '')
59
- #{progname} OPTIONS SUBCOMMAND ARGS
60
-
61
- Run the specified SUBCOMMAND with the given ARGS.
62
- END_BANNER
63
- text ''
64
-
65
- stop_on( *SUBCOMMANDS )
66
- text pr.color('Subcommands', :bold, :white)
67
- text pr.list( SUBCOMMANDS, :columns_across )
68
- text ''
69
-
70
- text pr.color('Inversion Config', :bold, :white)
71
- opt :ignore_unknown_tags, "Ignore unknown tags instead of displaying an error"
72
- opt :path, "Add one or more directories to the template search path",
73
- :type => :string, :multi => true
74
- text ''
75
-
76
-
77
- text pr.color('Other Options', :bold, :white)
78
- opt :debug, "Enable debugging output"
79
- end
80
- end
81
-
82
-
83
- ### Parse the given command line +args+, returning a populated options struct
84
- ### and any remaining arguments.
85
- def self::parse_options( args )
86
- oparser = self.create_option_parser
87
- opts = oparser.parse( args )
88
-
89
- if oparser.leftovers.empty?
90
- $stderr.puts "No subcommand given.\nUsage: "
91
- oparser.educate( $stderr )
92
- exit :usage
93
- end
94
- args.replace( oparser.leftovers )
95
-
96
- return opts, args
97
- rescue Trollop::HelpNeeded
98
- oparser.educate( $stderr )
99
- exit :ok
100
- rescue Trollop::VersionNeeded
101
- $stderr.puts( oparser.version )
102
- exit :ok
103
- end
104
-
105
-
106
- ### Create a new instance of the command that will use the specified +opts+
107
- ### to parse and dump info about the given +templates+.
108
- def initialize( opts )
109
- @opts = opts
110
- @prompt = self.class.prompt
111
-
112
- # Configure logging
113
- Loggability.level = opts.debug ? :debug : :error
114
- Loggability.format_with( :color ) if $stdin.tty?
115
-
116
- # Configure Inversion's strictness
117
- Inversion::Template.configure(
118
- :ignore_unknown_tags => opts.ignore_unknown_tags,
119
- :template_paths => opts.path,
120
- )
121
- end
122
-
123
-
124
- ######
125
- public
126
- ######
127
-
128
- # The command-line options
129
- attr_reader :opts
130
-
131
- # The command's prompt object (HighLine)
132
- attr_reader :prompt
133
-
134
-
135
- ### Run the given +subcommand+ with the specified +args+.
136
- def run( subcommand, args )
137
- case subcommand.to_sym
138
- when :tree
139
- self.dump_node_trees( args )
140
- when :api
141
- self.describe_templates( args )
142
- when :tagtokens
143
- self.dump_tokens( args )
144
- else
145
- self.output_error( "No such command #{subcommand.dump}" )
146
- end
147
- end
148
-
149
-
150
- ### Load the Inversion::Template from the specified +tmplpath+ and return it. If there
151
- ### is an error loading the template, output the error and return +nil+.
152
- def load_template( tmplpath )
153
- template = Inversion::Template.load( tmplpath )
154
- return template
155
- rescue Errno => err
156
- self.prompt.say "Failed to load %s: %s" % [ tmplpath, err.message ]
157
- rescue Inversion::ParseError => err
158
- self.prompt.say "%s: Invalid template: %p: %s" %
159
- [ tmplpath, err.class, err.message ]
160
- self.prompt.say( err.backtrace.join("\n ") ) if self.opts.debug
161
- end
162
-
163
-
164
- ### Dump the node tree of the given +templates+.
165
- def dump_node_trees( templates )
166
- templates.each do |path|
167
- template = self.load_template( path )
168
- self.output_blank_line
169
- self.output_template_header( template )
170
- self.output_template_nodes( template.node_tree )
171
- end
172
- end
173
-
174
-
175
- ### Output the given +tree+ of nodes at the specified +indent+ level.
176
- def output_template_nodes( tree, indent=0 )
177
- indenttxt = ' ' * indent
178
- tree.each do |node|
179
- self.prompt.say( indenttxt + node.as_comment_body )
180
- self.output_template_nodes( node.subnodes, indent+4 ) if node.is_container?
181
- end
182
- end
183
-
184
-
185
- ### Output a description of the templates.
186
- def describe_templates( templates )
187
- templates.each do |path|
188
- template = self.load_template( path )
189
- self.output_blank_line
190
- self.output_template_header( template )
191
- self.describe_template_api( template )
192
- self.describe_publications( template )
193
- self.describe_subscriptions( template )
194
- end
195
- end
196
-
197
-
198
- ### Output a header between each template.
199
- def output_template_header( template )
200
- header_info = "%s (%0.2fK, %s)" %
201
- [ template.source_file, template.source.bytesize/1024.0, template.source.encoding ]
202
- header_line = "-- %s" % [ header_info ]
203
- self.prompt.say( self.prompt.color(header_line, :bold, :white) )
204
- end
205
-
206
-
207
- ### Output a description of the +template+'s attributes, subscriptions, etc.
208
- def describe_template_api( template )
209
- attrs = template.attributes.keys.map( &:to_s )
210
- return if attrs.empty?
211
-
212
- self.output_subheader "%d Attribute/s" % [ attrs.length ]
213
- self.output_list( attrs.sort )
214
- self.output_blank_line
215
- end
216
-
217
-
218
- ### Output a list of sections the template publishes.
219
- def describe_publications( template )
220
- ptags = template.node_tree.find_all {|node| node.is_a?(Inversion::Template::PublishTag) }
221
- return if ptags.empty?
222
-
223
- pubnames = ptags.map( &:key ).map( &:to_s ).uniq.sort
224
- self.output_subheader "%d Publication/s" % [ pubnames.length ]
225
- self.output_list( pubnames )
226
- self.output_blank_line
227
- end
228
-
229
-
230
- ### Output a list of sections the template subscribes to.
231
- def describe_subscriptions( template )
232
- stags = template.node_tree.find_all {|node| node.is_a?(Inversion::Template::SubscribeTag) }
233
- return if stags.empty?
234
-
235
- subnames = stags.map( &:key ).map( &:to_s ).uniq.sort
236
- self.output_subheader "%d Subscription/s" % [ subnames.length ]
237
- self.output_list( subnames )
238
- self.output_blank_line
239
- end
240
-
241
-
242
- ### Attempt to parse the given +code+ and dump its tokens as a tagpattern.
243
- def dump_tokens( args )
244
- code = args.join(' ')
245
-
246
- require 'ripper'
247
- tokens = Ripper.lex( code ).collect do |(pos, tok, text)|
248
- "%s<%p>" % [ tok.to_s.sub(/^on_/,''), text ]
249
- end.join(' ')
250
-
251
- self.prompt.say( tokens )
252
- end
253
-
254
-
255
- ### Display a columnar list.
256
- def output_list( columns )
257
- self.prompt.say( self.prompt.list(columns, :columns_down) )
258
- end
259
-
260
-
261
- ### Display an error message.
262
- def output_error( message )
263
- self.prompt.say( self.prompt.color(message, :red) )
264
- end
265
-
266
-
267
- ### Output a subheader with the given +caption+.
268
- def output_subheader( caption )
269
- self.prompt.say( self.prompt.color(caption, :cyan) )
270
- end
271
-
272
-
273
- ### Output a blank line
274
- def output_blank_line
275
- self.prompt.say( "\n" )
276
- end
277
-
278
- end # class Inversion::Command
@@ -1,21 +0,0 @@
1
- # -*- ruby -*-
2
- # frozen_string_literal: true
3
- # vim: set noet nosta sw=4 ts=4 :
4
-
5
- require 'inversion' unless defined?( Inversion )
6
- require 'ripper'
7
-
8
- # Monkeypatch mixin to expose the 'tokens' instance variable of
9
- # Ripper::TokenPattern::MatchData. Included in Ripper::TokenPattern::MatchData.
10
- module Inversion::RipperAdditions
11
-
12
- # the array of token tuples
13
- attr_reader :tokens
14
-
15
- end
16
-
17
- # :stopdoc:
18
- class Ripper::TokenPattern::MatchData
19
- include Inversion::RipperAdditions
20
- end
21
-
@@ -1,25 +0,0 @@
1
- #!/usr/bin/env rspec -cfd -b
2
- # vim: set noet nosta sw=4 ts=4 :
3
-
4
-
5
- require_relative '../helpers'
6
-
7
- require 'ripper'
8
- require 'inversion/monkeypatches'
9
-
10
-
11
- describe Inversion, "monkeypatches" do
12
-
13
- describe Inversion::RipperAdditions do
14
-
15
- it "exposes the Ripper::TokenPattern::MatchData's #tokens array" do
16
- tagpattern = Ripper::TokenPattern.compile( '$(ident) $(sp) $(ident)' )
17
- matchdata = tagpattern.match( "foo bar" )
18
- expect( matchdata.tokens.map {|tok| tok[1]} ).to eq([ :on_ident, :on_sp, :on_ident ])
19
- end
20
-
21
- end
22
-
23
-
24
- end
25
-