mustermann 1.0.2.rc1 → 1.0.2.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +799 -230
  3. data/{mustermann/bench → bench}/capturing.rb +0 -0
  4. data/{mustermann/bench → bench}/regexp.rb +0 -0
  5. data/{mustermann/bench → bench}/simple_vs_sinatra.rb +0 -0
  6. data/{mustermann/bench → bench}/template_vs_addressable.rb +0 -0
  7. data/{mustermann/lib → lib}/mustermann.rb +0 -0
  8. data/{mustermann/lib → lib}/mustermann/ast/boundaries.rb +0 -0
  9. data/{mustermann/lib → lib}/mustermann/ast/compiler.rb +0 -0
  10. data/{mustermann/lib → lib}/mustermann/ast/expander.rb +0 -0
  11. data/{mustermann/lib → lib}/mustermann/ast/node.rb +0 -0
  12. data/{mustermann/lib → lib}/mustermann/ast/param_scanner.rb +0 -0
  13. data/{mustermann/lib → lib}/mustermann/ast/parser.rb +0 -0
  14. data/{mustermann/lib → lib}/mustermann/ast/pattern.rb +0 -0
  15. data/{mustermann/lib → lib}/mustermann/ast/template_generator.rb +0 -0
  16. data/{mustermann/lib → lib}/mustermann/ast/transformer.rb +0 -0
  17. data/{mustermann/lib → lib}/mustermann/ast/translator.rb +0 -0
  18. data/{mustermann/lib → lib}/mustermann/ast/validation.rb +0 -0
  19. data/{mustermann/lib → lib}/mustermann/caster.rb +0 -0
  20. data/{mustermann/lib → lib}/mustermann/composite.rb +0 -0
  21. data/{mustermann/lib → lib}/mustermann/concat.rb +0 -0
  22. data/{mustermann/lib → lib}/mustermann/equality_map.rb +0 -0
  23. data/{mustermann/lib → lib}/mustermann/error.rb +0 -0
  24. data/{mustermann/lib → lib}/mustermann/expander.rb +0 -0
  25. data/{mustermann/lib → lib}/mustermann/extension.rb +0 -0
  26. data/{mustermann/lib → lib}/mustermann/identity.rb +0 -0
  27. data/{mustermann/lib → lib}/mustermann/mapper.rb +0 -0
  28. data/{mustermann/lib → lib}/mustermann/pattern.rb +0 -0
  29. data/{mustermann/lib → lib}/mustermann/pattern_cache.rb +0 -0
  30. data/{mustermann/lib → lib}/mustermann/regexp.rb +0 -0
  31. data/{mustermann/lib → lib}/mustermann/regexp_based.rb +0 -0
  32. data/{mustermann/lib → lib}/mustermann/regular.rb +0 -0
  33. data/{mustermann/lib → lib}/mustermann/simple_match.rb +0 -0
  34. data/{mustermann/lib → lib}/mustermann/sinatra.rb +0 -0
  35. data/{mustermann/lib → lib}/mustermann/sinatra/parser.rb +0 -0
  36. data/{mustermann/lib → lib}/mustermann/sinatra/safe_renderer.rb +0 -0
  37. data/{mustermann/lib → lib}/mustermann/sinatra/try_convert.rb +0 -0
  38. data/{mustermann/lib → lib}/mustermann/to_pattern.rb +0 -0
  39. data/{mustermann/lib → lib}/mustermann/version.rb +1 -1
  40. data/{mustermann/mustermann.gemspec → mustermann.gemspec} +0 -0
  41. data/{mustermann/spec → spec}/ast_spec.rb +0 -0
  42. data/{mustermann/spec → spec}/composite_spec.rb +0 -0
  43. data/{mustermann/spec → spec}/concat_spec.rb +0 -0
  44. data/{mustermann/spec → spec}/equality_map_spec.rb +0 -0
  45. data/{mustermann/spec → spec}/expander_spec.rb +0 -0
  46. data/{mustermann/spec → spec}/extension_spec.rb +0 -0
  47. data/{mustermann/spec → spec}/identity_spec.rb +0 -0
  48. data/{mustermann/spec → spec}/mapper_spec.rb +0 -0
  49. data/{mustermann/spec → spec}/mustermann_spec.rb +0 -0
  50. data/{mustermann/spec → spec}/pattern_spec.rb +0 -0
  51. data/{mustermann/spec → spec}/regexp_based_spec.rb +0 -0
  52. data/{mustermann/spec → spec}/regular_spec.rb +0 -0
  53. data/{mustermann/spec → spec}/simple_match_spec.rb +0 -0
  54. data/{mustermann/spec → spec}/sinatra_spec.rb +0 -0
  55. data/{mustermann/spec → spec}/to_pattern_spec.rb +0 -0
  56. metadata +71 -126
  57. data/.gitignore +0 -18
  58. data/.rspec +0 -5
  59. data/.travis.yml +0 -25
  60. data/.yardopts +0 -3
  61. data/Gemfile +0 -7
  62. data/Rakefile +0 -27
  63. data/mustermann-contrib/LICENSE +0 -23
  64. data/mustermann-contrib/README.md +0 -1155
  65. data/mustermann-contrib/examples/highlighting.rb +0 -35
  66. data/mustermann-contrib/highlighting.png +0 -0
  67. data/mustermann-contrib/irb.png +0 -0
  68. data/mustermann-contrib/lib/mustermann/cake.rb +0 -19
  69. data/mustermann-contrib/lib/mustermann/express.rb +0 -38
  70. data/mustermann-contrib/lib/mustermann/file_utils.rb +0 -218
  71. data/mustermann-contrib/lib/mustermann/file_utils/glob_pattern.rb +0 -40
  72. data/mustermann-contrib/lib/mustermann/fileutils.rb +0 -1
  73. data/mustermann-contrib/lib/mustermann/flask.rb +0 -199
  74. data/mustermann-contrib/lib/mustermann/pyramid.rb +0 -29
  75. data/mustermann-contrib/lib/mustermann/rails.rb +0 -47
  76. data/mustermann-contrib/lib/mustermann/shell.rb +0 -57
  77. data/mustermann-contrib/lib/mustermann/simple.rb +0 -51
  78. data/mustermann-contrib/lib/mustermann/string_scanner.rb +0 -314
  79. data/mustermann-contrib/lib/mustermann/strscan.rb +0 -1
  80. data/mustermann-contrib/lib/mustermann/template.rb +0 -63
  81. data/mustermann-contrib/lib/mustermann/uri_template.rb +0 -1
  82. data/mustermann-contrib/lib/mustermann/versions.rb +0 -47
  83. data/mustermann-contrib/lib/mustermann/visualizer.rb +0 -39
  84. data/mustermann-contrib/lib/mustermann/visualizer/highlight.rb +0 -138
  85. data/mustermann-contrib/lib/mustermann/visualizer/highlighter.rb +0 -38
  86. data/mustermann-contrib/lib/mustermann/visualizer/highlighter/ad_hoc.rb +0 -95
  87. data/mustermann-contrib/lib/mustermann/visualizer/highlighter/ast.rb +0 -103
  88. data/mustermann-contrib/lib/mustermann/visualizer/highlighter/composite.rb +0 -46
  89. data/mustermann-contrib/lib/mustermann/visualizer/highlighter/dummy.rb +0 -19
  90. data/mustermann-contrib/lib/mustermann/visualizer/highlighter/regular.rb +0 -105
  91. data/mustermann-contrib/lib/mustermann/visualizer/pattern_extension.rb +0 -69
  92. data/mustermann-contrib/lib/mustermann/visualizer/renderer/ansi.rb +0 -24
  93. data/mustermann-contrib/lib/mustermann/visualizer/renderer/generic.rb +0 -47
  94. data/mustermann-contrib/lib/mustermann/visualizer/renderer/hansi_template.rb +0 -35
  95. data/mustermann-contrib/lib/mustermann/visualizer/renderer/html.rb +0 -51
  96. data/mustermann-contrib/lib/mustermann/visualizer/renderer/sexp.rb +0 -38
  97. data/mustermann-contrib/lib/mustermann/visualizer/tree.rb +0 -64
  98. data/mustermann-contrib/lib/mustermann/visualizer/tree_renderer.rb +0 -79
  99. data/mustermann-contrib/mustermann-contrib.gemspec +0 -19
  100. data/mustermann-contrib/spec/cake_spec.rb +0 -91
  101. data/mustermann-contrib/spec/express_spec.rb +0 -210
  102. data/mustermann-contrib/spec/file_utils_spec.rb +0 -120
  103. data/mustermann-contrib/spec/flask_spec.rb +0 -362
  104. data/mustermann-contrib/spec/flask_subclass_spec.rb +0 -369
  105. data/mustermann-contrib/spec/pattern_extension_spec.rb +0 -50
  106. data/mustermann-contrib/spec/pyramid_spec.rb +0 -102
  107. data/mustermann-contrib/spec/rails_spec.rb +0 -648
  108. data/mustermann-contrib/spec/shell_spec.rb +0 -148
  109. data/mustermann-contrib/spec/simple_spec.rb +0 -269
  110. data/mustermann-contrib/spec/string_scanner_spec.rb +0 -272
  111. data/mustermann-contrib/spec/template_spec.rb +0 -842
  112. data/mustermann-contrib/spec/visualizer_spec.rb +0 -199
  113. data/mustermann-contrib/theme.png +0 -0
  114. data/mustermann-contrib/tree.png +0 -0
  115. data/mustermann/LICENSE +0 -23
  116. data/mustermann/README.md +0 -853
  117. data/support/lib/support.rb +0 -7
  118. data/support/lib/support/coverage.rb +0 -23
  119. data/support/lib/support/env.rb +0 -19
  120. data/support/lib/support/expand_matcher.rb +0 -28
  121. data/support/lib/support/generate_template_matcher.rb +0 -27
  122. data/support/lib/support/match_matcher.rb +0 -39
  123. data/support/lib/support/pattern.rb +0 -42
  124. data/support/lib/support/projects.rb +0 -20
  125. data/support/lib/support/scan_matcher.rb +0 -63
  126. data/support/support.gemspec +0 -27
@@ -1,1155 +0,0 @@
1
- # The Amazing Mustermann - Contrib Edition
2
-
3
- This is a meta gem that depends on all mustermann gems.
4
-
5
- ``` console
6
- $ gem install mustermann-contrib
7
- Successfully installed mustermann-1.0.0
8
- Successfully installed mustermann-contrib-1.0.0
9
- ...
10
- ```
11
-
12
- Also handy for your `Gemfile`:
13
-
14
- ``` ruby
15
- gem 'mustermann-contrib'
16
- ```
17
-
18
- Alternatively, you can use latest HEAD from github:
19
-
20
- ```ruby
21
- github 'sinatra/mustermann' do
22
- gem 'mustermann'
23
- gem 'mustermann-contrib'
24
- end
25
- ```
26
-
27
- <a name="-mustermann-cake"></a>
28
- # CakePHP Syntax for Mustermann
29
-
30
- This gem implements the `cake` pattern type for Mustermann. It is compatible with [CakePHP](http://cakephp.org/) 2.x and 3.x.
31
-
32
- ## Overview
33
-
34
- **Supported options:**
35
- `capture`, `except`, `greedy`, `space_matches_plus`, `uri_decode`, and `ignore_unknown_options`.
36
-
37
- **External documentation:**
38
- [CakePHP 2.0 Routing](http://book.cakephp.org/2.0/en/development/routing.html),
39
- [CakePHP 3.0 Routing](http://book.cakephp.org/3.0/en/development/routing.html)
40
-
41
- CakePHP patterns feature captures and unnamed splats. Captures are prefixed with a colon and splats are either a single asterisk (parsing segments into an array) or a double asterisk (parsing segments as a single string).
42
-
43
- ``` ruby
44
- require 'mustermann/cake'
45
-
46
- Mustermann.new('/:name/*', type: :cake).params('/a/b/c') # => { name: 'a', splat: ['b', 'c'] }
47
- Mustermann.new('/:name/**', type: :cake).params('/a/b/c') # => { name: 'a', splat: 'b/c' }
48
-
49
- pattern = Mustermann.new('/:name')
50
-
51
- pattern.respond_to? :expand # => true
52
- pattern.expand(name: 'foo') # => '/foo'
53
-
54
- pattern.respond_to? :to_templates # => true
55
- pattern.to_templates # => ['/{name}']
56
- ```
57
-
58
- ## Syntax
59
-
60
- <table>
61
- <thead>
62
- <tr>
63
- <th>Syntax Element</th>
64
- <th>Description</th>
65
- </tr>
66
- </thead>
67
- <tbody>
68
- <tr>
69
- <td><b>:</b><i>name</i></td>
70
- <td>
71
- Captures anything but a forward slash in a semi-greedy fashion. Capture is named <i>name</i>.
72
- Capture behavior can be modified with <tt>capture</tt> and <tt>greedy</tt> option.
73
- </td>
74
- </tr>
75
- <tr>
76
- <td><b>*</b></td>
77
- <td>
78
- Captures anything in a non-greedy fashion. Capture is named splat.
79
- It is always an array of captures, as you can use it more than once in a pattern.
80
- </td>
81
- </tr>
82
- <tr>
83
- <td><b>**</b></td>
84
- <td>
85
- Captures anything in a non-greedy fashion. Capture is named splat.
86
- It is always an array of captures, as you can use it more than once in a pattern.
87
- The value matching a single <tt>**</tt> will be split at slashes when parsed into <tt>params</tt>.
88
- </td>
89
- </tr>
90
- <tr>
91
- <td><b>/</b></td>
92
- <td>
93
- Matches forward slash. Does not match URI encoded version of forward slash.
94
- </td>
95
- </tr>
96
- <tr>
97
- <td><i>any other character</i></td>
98
- <td>Matches exactly that character or a URI encoded version of it.</td>
99
- </tr>
100
- </tbody>
101
- </table>
102
-
103
-
104
- <a name="-mustermann-express"></a>
105
- # Express Syntax for Mustermann
106
-
107
- This gem implements the `express` pattern type for Mustermann. It is compatible with [Express](http://expressjs.com/) and [pillar.js](https://pillarjs.github.io/).
108
-
109
- ## Overview
110
-
111
- **Supported options:**
112
- `capture`, `except`, `greedy`, `space_matches_plus`, `uri_decode`, and `ignore_unknown_options`.
113
-
114
- **External documentation:**
115
- [path-to-regexp](https://github.com/pillarjs/path-to-regexp#path-to-regexp),
116
- [live demo](http://forbeslindesay.github.io/express-route-tester/)
117
-
118
- Express patterns feature named captures (with repetition support via suffixes) that start with a colon and can have an optional regular expression constraint or unnamed captures that require a constraint.
119
-
120
- ``` ruby
121
- require 'mustermann/express'
122
-
123
- Mustermann.new('/:name/:rest+', type: :express).params('/a/b/c') # => { name: 'a', rest: 'b/c' }
124
-
125
- pattern = Mustermann.new('/:name', type: :express)
126
-
127
- pattern.respond_to? :expand # => true
128
- pattern.expand(name: 'foo') # => '/foo'
129
-
130
- pattern.respond_to? :to_templates # => true
131
- pattern.to_templates # => ['/{name}']
132
- ```
133
-
134
- ## Syntax
135
-
136
- <table>
137
- <thead>
138
- <tr>
139
- <th>Syntax Element</th>
140
- <th>Description</th>
141
- </tr>
142
- </thead>
143
- <tbody>
144
- <tr>
145
- <td><b>:</b><i>name</i></td>
146
- <td>
147
- Captures anything but a forward slash in a semi-greedy fashion. Capture is named <i>name</i>.
148
- Capture behavior can be modified with <tt>capture</tt> and <tt>greedy</tt> option.
149
- </td>
150
- </tr>
151
- <tr>
152
- <td><b>:</b><i>name</i><b>+</b></td>
153
- <td>
154
- Captures one or more segments (with segments being separated by forward slashes).
155
- Capture is named <i>name</i>.
156
- Capture behavior can be modified with <tt>capture</tt> option.
157
- </td>
158
- </tr>
159
- <tr>
160
- <td><b>:</b><i>name</i><b>*</b></td>
161
- <td>
162
- Captures zero or more segments (with segments being separated by forward slashes).
163
- Capture is named <i>name</i>.
164
- Capture behavior can be modified with <tt>capture</tt> option.
165
- </td>
166
- </tr>
167
- <tr>
168
- <td><b>:</b><i>name</i><b>?</b></td>
169
- <td>
170
- Captures anything but a forward slash in a semi-greedy fashion. Capture is named <i>name</i>.
171
- Also matches an empty string.
172
- Capture behavior can be modified with <tt>capture</tt> and <tt>greedy</tt> option.
173
- </td>
174
- </tr>
175
- <tr>
176
- <td><b>:</b><i>name</i><b>(</b><i>regexp</i><b>)</b></td>
177
- <td>
178
- Captures anything matching the <i>regexp</i> regular expression. Capture is named <i>name</i>.
179
- Capture behavior can be modified with <tt>capture</tt>.
180
- </td>
181
- </tr>
182
- <tr>
183
- <td><b>(</b><i>regexp</i><b>)</b></td>
184
- <td>
185
- Captures anything matching the <i>regexp</i> regular expression. Capture is named splat.
186
- Capture behavior can be modified with <tt>capture</tt>.
187
- </td>
188
- </tr>
189
- <tr>
190
- <td><b>/</b></td>
191
- <td>
192
- Matches forward slash. Does not match URI encoded version of forward slash.
193
- </td>
194
- </tr>
195
- <tr>
196
- <td><i>any other character</i></td>
197
- <td>Matches exactly that character or a URI encoded version of it.</td>
198
- </tr>
199
- </tbody>
200
- </table>
201
-
202
- <a name="-mustermann-fileutils"></a>
203
- # FileUtils for Mustermann
204
-
205
- This gem implements efficient file system operations for Mustermann patterns.
206
-
207
- ## Globbing
208
-
209
- All operations work on a list of files described by one or more pattern.
210
-
211
- ``` ruby
212
- require 'mustermann/file_utils'
213
-
214
- Mustermann::FileUtils[':base.:ext'] # => ['example.txt']
215
-
216
- Mustermann::FileUtils.glob(':base.:ext') do |file, params|
217
- file # => "example.txt"
218
- params # => {"base"=>"example", "ext"=>"txt"}
219
- end
220
- ```
221
-
222
- To avoid having to loop over all files and see if they match, it will generate a glob pattern resembling the Mustermann pattern as closely as possible.
223
-
224
- ``` ruby
225
- require 'mustermann/file_utils'
226
-
227
- Mustermann::FileUtils.glob_pattern('/:name') # => '/*'
228
- Mustermann::FileUtils.glob_pattern('src/:path/:file.(js|rb)') # => 'src/**/*/*.{js,rb}'
229
- Mustermann::FileUtils.glob_pattern('{a,b}/*', type: :shell) # => '{a,b}/*'
230
-
231
- pattern = Mustermann.new('/foo/:page', '/bar/:page') # => #<Mustermann::Composite:...>
232
- Mustermann::FileUtils.glob_pattern(pattern) # => "{/foo/*,/bar/*}"
233
- ```
234
-
235
- ## Mapping
236
-
237
- It is also possible to search for files and have their paths mapped onto another path in one method call:
238
-
239
- ``` ruby
240
- require 'mustermann/file_utils'
241
-
242
- Mustermann::FileUtils.glob_map(':base.:ext' => ':base.bak.:ext') # => {'example.txt' => 'example.bak.txt'}
243
- Mustermann::FileUtils.glob_map(':base.:ext' => :base) { |file, mapped| mapped } # => ['example']
244
- ```
245
-
246
- This mechanism allows things like copying, renaming and linking files:
247
-
248
- ``` ruby
249
- require 'mustermann/file_utils'
250
-
251
- # copies example.txt to example.bak.txt
252
- Mustermann::FileUtils.cp(':base.:ext' => ':base.bak.:ext')
253
-
254
- # copies Foo.app/example.txt to Foo.back.app/example.txt
255
- Mustermann::FileUtils.cp_r(':base.:ext' => ':base.bak.:ext')
256
-
257
- # creates a symbolic link from bin/example to lib/example.rb
258
- Mustermann::FileUtils.ln_s('lib/:name.rb' => 'bin/:name')
259
- ```
260
-
261
- <a name="-mustermann-flask"></a>
262
- # Flask Syntax for Mustermann
263
-
264
- This gem implements the `flask` pattern type for Mustermann. It is compatible with [Flask](http://flask.pocoo.org/) and [Werkzeug](http://werkzeug.pocoo.org/).
265
-
266
- ## Overview
267
-
268
- **Supported options:**
269
- `capture`, `except`, `greedy`, `space_matches_plus`, `uri_decode`, `converters` and `ignore_unknown_options`
270
-
271
- **External documentation:**
272
- [Werkzeug: URL Routing](http://werkzeug.pocoo.org/docs/0.9/routing/)
273
-
274
- ``` ruby
275
- require 'mustermann/flask'
276
-
277
- Mustermann.new('/<prefix>/<path:page>', type: :flask).params('/a/b/c') # => { prefix: 'a', page: 'b/c' }
278
-
279
- pattern = Mustermann.new('/<name>', type: :flask)
280
-
281
- pattern.respond_to? :expand # => true
282
- pattern.expand(name: 'foo') # => '/foo'
283
-
284
- pattern.respond_to? :to_templates # => true
285
- pattern.to_templates # => ['/{name}']
286
- ```
287
-
288
- ## Syntax
289
-
290
- <table>
291
- <thead>
292
- <tr>
293
- <th>Syntax Element</th>
294
- <th>Description</th>
295
- </tr>
296
- </thead>
297
- <tbody>
298
- <tr>
299
- <td><b>&lt;</b><i>name</i><b>&gt;</b></td>
300
- <td>
301
- Captures anything but a forward slash in a semi-greedy fashion. Capture is named <i>name</i>.
302
- Capture behavior can be modified with <tt>capture</tt> and <tt>greedy</tt> option.
303
- </td>
304
- </tr>
305
- <tr>
306
- <td><b>&lt;</b><i>converter</i><b>:</b><i>name</i><b>&gt;</b></td>
307
- <td>
308
- Captures depending on the converter constraint. Capture is named <i>name</i>.
309
- Capture behavior can be modified with <tt>capture</tt> and <tt>greedy</tt> option.
310
- See below.
311
- </td>
312
- </tr>
313
- <tr>
314
- <td><b>&lt;</b><i>converter</i><b>(</b><i>arguments</i><b>):</b><i>name</i><b>&gt;</b></td>
315
- <td>
316
- Captures depending on the converter constraint. Capture is named <i>name</i>.
317
- Capture behavior can be modified with <tt>capture</tt> and <tt>greedy</tt> option.
318
- Arguments are separated by comma. An argument can be a simple string, a string enclosed
319
- in single or double quotes, or a key value pair (keys and values being separated by an
320
- equal sign). See below.
321
- </td>
322
- </tr>
323
- <tr>
324
- <td><b>/</b></td>
325
- <td>
326
- Matches forward slash. Does not match URI encoded version of forward slash.
327
- </td>
328
- </tr>
329
- <tr>
330
- <td><i>any other character</i></td>
331
- <td>Matches exactly that character or a URI encoded version of it.</td>
332
- </tr>
333
- </tbody>
334
- </table>
335
-
336
- ## Converters
337
-
338
- ### Builtin Converters
339
-
340
- #### `string`
341
-
342
- Possible arguments: `minlength`, `maxlength`, `length`
343
-
344
- Captures anything but a forward slash in a semi-greedy fashion.
345
- Capture behavior can be modified with <tt>capture</tt> and <tt>greedy</tt> option.
346
-
347
- This is also the default converter.
348
-
349
- Examples:
350
-
351
- ```
352
- <name>
353
- <string:name>
354
- <string(minlength=3,maxlength=10):slug>
355
- <string(length=10):slug>
356
- ```
357
-
358
- #### `int`
359
-
360
- Possible arguments: `min`, `max`, `fixed_digits`
361
-
362
- Captures digits.
363
- Captured value will be converted to an Integer.
364
-
365
- Examples:
366
-
367
- ```
368
- <int:id>
369
- <int(min=1,max=5):page>
370
- <int(fixed_digits=16):uuid>
371
- ```
372
-
373
- #### `float`
374
-
375
- Possible arguments: `min`, `max`
376
-
377
- Captures digits with a dot.
378
- Captured value will be converted to an Float.
379
-
380
- Examples:
381
-
382
- ```
383
- <float:precision>
384
- <float(min=0,max=1):precision>
385
- ```
386
-
387
- #### `path`
388
-
389
- Captures anything in a non-greedy fashion.
390
-
391
- Example:
392
-
393
- ```
394
- <path:rest>
395
- ```
396
-
397
- #### `any`
398
-
399
- Possible arguments: List of accepted strings.
400
-
401
- Captures anything that matches one of the arguments exactly.
402
-
403
- Example:
404
-
405
- ```
406
- <any(home,search,contact):page>
407
- ```
408
-
409
- ### Custom Converters
410
-
411
- [Flask patterns](#-pattern-details-flask) support registering custom converters.
412
-
413
- A converter object may implement any of the following methods:
414
-
415
- * `convert`: Should return a block converting a string value to whatever value should end up in the `params` hash.
416
- * `constraint`: Should return a regular expression limiting which input string will match the capture.
417
- * `new`: Returns an object that may respond to `convert` and/or `constraint` as described above. Any arguments used for the converter inside the pattern will be passed to `new`.
418
-
419
- ``` ruby
420
- require 'mustermann/flask'
421
-
422
- SimpleConverter = Struct.new(:constraint, :convert)
423
- id_converter = SimpleConverter.new(/\d/, -> s { s.to_i })
424
-
425
- class NumConverter
426
- def initialize(base: 10)
427
- @base = Integer(base)
428
- end
429
-
430
- def convert
431
- -> s { s.to_i(@base) }
432
- end
433
-
434
- def constraint
435
- @base > 10 ? /[\da-#{(@base-1).to_s(@base)}]/ : /[0-#{@base-1}]/
436
- end
437
- end
438
-
439
- pattern = Mustermann.new('/<id:id>/<num(base=8):oct>/<num(base=16):hex>',
440
- type: :flask, converters: { id: id_converter, num: NumConverter})
441
-
442
- pattern.params('/10/12/f1') # => {"id"=>10, "oct"=>10, "hex"=>241}
443
- ```
444
-
445
- ### Global Converters
446
-
447
- It is also possible to register a converter for all flask patterns, using `register_converter`:
448
-
449
- ``` ruby
450
- Mustermann::Flask.register_converter(:id, id_converter)
451
- Mustermann::Flask.register_converter(:num, NumConverter)
452
-
453
- pattern = Mustermann.new('/<id:id>/<num(base=8):oct>/<num(base=16):hex>', type: :flask)
454
- pattern.params('/10/12/f1') # => {"id"=>10, "oct"=>10, "hex"=>241}
455
- ```
456
-
457
- There is a handy syntax for quickly creating new converter classes: When you pass a block instead of a converter object, it will yield a generic converter with setters and getters for `convert` and `constraint`, and any arguments passed to the converter.
458
-
459
- ``` ruby
460
- require 'mustermann/flask'
461
-
462
- Mustermann::Flask.register_converter(:id) do |converter|
463
- converter.constraint = /\d/
464
- converter.convert = -> s { s.to_i }
465
- end
466
-
467
- Mustermann::Flask.register_converter(:num) do |converter, base: 10|
468
- converter.constraint = base > 10 ? /[\da-#{(@base-1).to_s(base)}]/ : /[0-#{base-1}]/
469
- converter.convert = -> s { s.to_i(base) }
470
- end
471
-
472
- pattern = Mustermann.new('/<id:id>/<num(base=8):oct>/<num(base=16):hex>', type: :flask)
473
- pattern.params('/10/12/f1') # => {"id"=>10, "oct"=>10, "hex"=>241}
474
- ```
475
-
476
- ### Subclassing
477
-
478
- Registering global converters will make these available for all Flask patterns. It might even override already registered converters. This global state might break unrelated code.
479
-
480
- It is therefore recommended that, if you don't want to pass in the converters option for every pattern, you create your own subclass of `Mustermann::Flask`.
481
-
482
- ``` ruby
483
- require 'mustermann/flask'
484
-
485
- MyFlask = Class.new(Mustermann::Flask)
486
-
487
- MyFlask.register_converter(:id) do |converter|
488
- converter.constraint = /\d/
489
- converter.convert = -> s { s.to_i }
490
- end
491
-
492
- MyFlask.register_converter(:num) do |converter, base: 10|
493
- converter.constraint = base > 10 ? /[\da-#{(@base-1).to_s(base)}]/ : /[0-#{base-1}]/
494
- converter.convert = -> s { s.to_i(base) }
495
- end
496
-
497
- pattern = MyFlask.new('/<id:id>/<num(base=8):oct>/<num(base=16):hex>')
498
- pattern.params('/10/12/f1') # => {"id"=>10, "oct"=>10, "hex"=>241}
499
- ```
500
-
501
- You can even register this type for usage with `Mustermann.new`:
502
-
503
- ``` ruby
504
- Mustermann.register(:my_flask, MyFlask)
505
- pattern = Mustermann.new('/<id:id>/<num(base=8):oct>/<num(base=16):hex>', type: :my_flask)
506
- pattern.params('/10/12/f1') # => {"id"=>10, "oct"=>10, "hex"=>241}
507
- ```
508
-
509
- <a name="-mustermann-pyramid"></a>
510
- # Pyramid Syntax for Mustermann
511
-
512
- This gem implements the `pyramid` pattern type for Mustermann. It is compatible with [Pyramid](http://www.pylonsproject.org/projects/pyramid/about) and [Pylons](http://www.pylonsproject.org/projects/pylons-framework/about).
513
-
514
- ## Overview
515
-
516
- **Supported options:**
517
- `capture`, `except`, `greedy`, `space_matches_plus`, `uri_decode` and `ignore_unknown_options`
518
-
519
- **External Documentation:** [Pylons Framework: URL Configuration](http://docs.pylonsproject.org/projects/pylons-webframework/en/latest/configuration.html#url-config), [Pylons Book: Routes in Detail](http://pylonsbook.com/en/1.0/urls-routing-and-dispatch.html#routes-in-detail), [Pyramid: Route Pattern Syntax](http://docs.pylonsproject.org/projects/pyramid/en/1.5-branch/narr/urldispatch.html#route-pattern-syntax)
520
-
521
- ``` ruby
522
- require 'mustermann/pyramid'
523
-
524
- Mustermann.new('/{prefix}/*suffix', type: :pyramid).params('/a/b/c') # => { prefix: 'a', suffix: ['b', 'c'] }
525
-
526
- pattern = Mustermann.new('/{name}', type: :pyramid)
527
-
528
- pattern.respond_to? :expand # => true
529
- pattern.expand(name: 'foo') # => '/foo'
530
-
531
- pattern.respond_to? :to_templates # => true
532
- pattern.to_templates # => ['/{name}']
533
- ```
534
-
535
- ## Syntax
536
-
537
-
538
- <table>
539
- <thead>
540
- <tr>
541
- <th>Syntax Element</th>
542
- <th>Description</th>
543
- </tr>
544
- </thead>
545
- <tbody>
546
- <tr>
547
- <td><b>&#123;</b><i>name</i><b>&#125;</b></td>
548
- <td>
549
- Captures anything but a forward slash in a semi-greedy fashion. Capture is named <i>name</i>.
550
- Capture behavior can be modified with <tt>capture</tt> and <tt>greedy</tt> option.
551
- </td>
552
- </tr>
553
- <tr>
554
- <td><b>&#123;</b><i>name</i><b>:</b><i>regexp</i><b>&#125;</b></td>
555
- <td>
556
- Captures anything matching the <i>regexp</i> regular expression. Capture is named <i>name</i>.
557
- Capture behavior can be modified with <tt>capture</tt>.
558
- </td>
559
- </tr>
560
- <tr>
561
- <td><b>*</b><i>name</i></td>
562
- <td>
563
- Captures anything in a non-greedy fashion. Capture is named <i>name</i>.
564
- </td>
565
- </tr>
566
- <tr>
567
- <td><b>/</b></td>
568
- <td>
569
- Matches forward slash. Does not match URI encoded version of forward slash.
570
- </td>
571
- </tr>
572
- <tr>
573
- <td><i>any other character</i></td>
574
- <td>Matches exactly that character or a URI encoded version of it.</td>
575
- </tr>
576
- </tbody>
577
- </table>
578
-
579
- <a name="-mustermann-rails"></a>
580
- # Rails Syntax for Mustermann
581
-
582
- This gem implements the `rails` pattern type for Mustermann. It is compatible with [Ruby on Rails](http://rubyonrails.org/), [Journey](https://github.com/rails/journey), the [http_router gem](https://github.com/joshbuddy/http_router), [Lotus](http://lotusrb.org/) and [Scalatra](http://www.scalatra.org/) (if [configured](http://www.scalatra.org/2.3/guides/http/routes.html#toc_248))</td>
583
-
584
- ## Overview
585
-
586
- **Supported options:**
587
- `capture`, `except`, `greedy`, `space_matches_plus`, `uri_decode`, `version`, and `ignore_unknown_options`.
588
-
589
- **External documentation:**
590
- [Ruby on Rails Guides: Routing](http://guides.rubyonrails.org/routing.html).
591
-
592
- ``` ruby
593
- require 'mustermann'
594
-
595
- pattern = Mustermann.new('/:example', type: :rails)
596
- pattern === "/foo.bar" # => true
597
- pattern === "/foo/bar" # => false
598
- pattern.params("/foo.bar") # => { "example" => "foo.bar" }
599
- pattern.params("/foo/bar") # => nil
600
-
601
- pattern = Mustermann.new('/:example(/:optional)', type: :rails)
602
- pattern === "/foo.bar" # => true
603
- pattern === "/foo/bar" # => true
604
- pattern.params("/foo.bar") # => { "example" => "foo.bar", "optional" => nil }
605
- pattern.params("/foo/bar") # => { "example" => "foo", "optional" => "bar" }
606
-
607
- pattern = Mustermann.new('/*example', type: :rails)
608
- pattern === "/foo.bar" # => true
609
- pattern === "/foo/bar" # => true
610
- pattern.params("/foo.bar") # => { "example" => "foo.bar" }
611
- pattern.params("/foo/bar") # => { "example" => "foo/bar" }
612
- ```
613
-
614
- ## Rails Compatibility
615
-
616
- Rails syntax changed over time. You can target different Ruby on Rails versions by setting the `version` option to the desired Rails version.
617
-
618
- The default is `4.2`. Versions prior to `2.3` are not supported.
619
-
620
- ``` ruby
621
- require 'mustermann'
622
- Mustermann.new('/', type: :rails, version: "2.3")
623
- Mustermann.new('/', type: :rails, version: "3.0.0")
624
-
625
- require 'rails'
626
- Mustermann.new('/', type: :rails, version: Rails::VERSION::STRING)
627
- ```
628
-
629
- ## Syntax
630
-
631
- <table>
632
- <thead>
633
- <tr>
634
- <th>Syntax Element</th>
635
- <th>Description</th>
636
- </tr>
637
- </thead>
638
- <tbody>
639
- <tr>
640
- <td><b>:</b><i>name</i></td>
641
- <td>
642
- Captures anything but a forward slash in a semi-greedy fashion. Capture is named <i>name</i>.
643
- Capture behavior can be modified with tt>capture</tt> and <tt>greedy</tt> option.
644
- </td>
645
- </tr>
646
- <tr>
647
- <td><b>*</b><i>name</i></td>
648
- <td>
649
- Captures anything in a non-greedy fashion. Capture is named <i>name</i>.
650
- </td>
651
- </tr>
652
- <tr>
653
- <td><b>(</b><i>expression</i><b>)</b></td>
654
- <td>Enclosed <i>expression</i> is optional. Not available in 2.3 compatibility mode.</td>
655
- </tr>
656
- <tr>
657
- <td><b>/</b></td>
658
- <td>
659
- Matches forward slash. Does not match URI encoded version of forward slash.
660
- </td>
661
- </tr>
662
- <tr>
663
- <td><b>\</b><i>x</i></td>
664
- <td>
665
- In 3.x compatibility mode and starting with 4.2:
666
- Matches <i>x</i> or URI encoded version of <i>x</i>. For instance <tt>\*</tt> matches <tt>*</tt>.<br>
667
- In 4.0 or 4.1 compatibility mode:
668
- <b>\</b> is ignored, <i>x</i> is parsed normally.<br>
669
- </td>
670
- </tr>
671
- <tr>
672
- <td><i>expression</i> <b>|</b> <i>expression</i></td>
673
- <td>
674
- 3.2+ mode: This will raise a `Mustermann::ParseError`. While Ruby on Rails happily parses this character, it will result in broken routes due to a buggy implementation.<br>
675
- 5.0 mode: It will match if any of the nested expressions matches.
676
- </td>
677
- </tr>
678
- <tr>
679
- <td><i>any other character</i></td>
680
- <td>Matches exactly that character or a URI encoded version of it.</td>
681
- </tr>
682
- </tbody>
683
- </table>
684
-
685
- <a name="-mustermann-shell"></a>
686
- # Shell Syntax for Mustermann
687
-
688
- This gem implements the `shell` pattern type for Mustermann. It is compatible with common Unix shells (like bash or zsh).
689
-
690
- ## Overview
691
-
692
- **Supported options:** `uri_decode` and `ignore_unknown_options`.
693
-
694
- **External documentation:** [Ruby's fnmatch](http://www.ruby-doc.org/core-2.1.4/File.html#method-c-fnmatch), [Wikipedia: Glob (programming)](http://en.wikipedia.org/wiki/Glob_(programming))
695
-
696
- ``` ruby
697
- require 'mustermann'
698
-
699
- pattern = Mustermann.new('/*', type: :shell)
700
- pattern === "/foo.bar" # => true
701
- pattern === "/foo/bar" # => false
702
-
703
- pattern = Mustermann.new('/**/*', type: :shell)
704
- pattern === "/foo.bar" # => true
705
- pattern === "/foo/bar" # => true
706
-
707
- pattern = Mustermann.new('/{foo,bar}', type: :shell)
708
- pattern === "/foo" # => true
709
- pattern === "/bar" # => true
710
- pattern === "/baz" # => false
711
- ```
712
-
713
- ## Syntax
714
-
715
- <table>
716
- <thead>
717
- <tr>
718
- <th>Syntax Element</th>
719
- <th>Description</th>
720
- </tr>
721
- </thead>
722
- <tbody>
723
- <tr>
724
- <td><b>*</b></td>
725
- <td>Matches anything but a slash.</td>
726
- </tr>
727
- <tr>
728
- <td><b>**</b></td>
729
- <td>Matches anything.</td>
730
- </tr>
731
- <tr>
732
- <td><b>[</b><i>set</i><b>]</b></td>
733
- <td>Matches one character in <i>set</i>.</td>
734
- </tr>
735
- <tr>
736
- <td><b>&#123;</b><i>a</i>,<i>b</i><b>&#125;</b></td>
737
- <td>Matches <i>a</i> or <i>b</i>.</td>
738
- </tr>
739
- <tr>
740
- <td><b>\</b><i>x</i></td>
741
- <td>Matches <i>x</i> or URI encoded version of <i>x</i>. For instance <tt>\*</tt> matches <tt>*</tt>.</td>
742
- </tr>
743
- <tr>
744
- <td><i>any other character</i></td>
745
- <td>Matches exactly that character or a URI encoded version of it.</td>
746
- </tr>
747
- </tbody>
748
- </table>
749
-
750
-
751
- <a name="-mustermann-simple"></a>
752
- # Simple Syntax for Mustermann
753
-
754
- This gem implements the `simple` pattern type for Mustermann. It is compatible with [Sinatra](http://www.sinatrarb.com/) (1.x), [Scalatra](http://www.scalatra.org/) and [Dancer](http://perldancer.org/).
755
-
756
- ## Overview
757
-
758
- **Supported options:**
759
- `greedy`, `space_matches_plus`, `uri_decode` and `ignore_unknown_options`.
760
-
761
- This is useful for porting an application that relies on this behavior to a later Sinatra version and to make sure Sinatra 2.0 patterns do not decrease performance. Simple patterns internally use the same code older Sinatra versions used for compiling the pattern. Error messages for broken patterns will therefore not be as informative as for other pattern implementations.
762
-
763
- ``` ruby
764
- require 'mustermann'
765
-
766
- pattern = Mustermann.new('/:example', type: :simple)
767
- pattern === "/foo.bar" # => true
768
- pattern === "/foo/bar" # => false
769
- pattern.params("/foo.bar") # => { "example" => "foo.bar" }
770
- pattern.params("/foo/bar") # => nil
771
-
772
- pattern = Mustermann.new('/:example/?:optional?', type: :simple)
773
- pattern === "/foo.bar" # => true
774
- pattern === "/foo/bar" # => true
775
- pattern.params("/foo.bar") # => { "example" => "foo.bar", "optional" => nil }
776
- pattern.params("/foo/bar") # => { "example" => "foo", "optional" => "bar" }
777
-
778
- pattern = Mustermann.new('/*', type: :simple)
779
- pattern === "/foo.bar" # => true
780
- pattern === "/foo/bar" # => true
781
- pattern.params("/foo.bar") # => { "splat" => ["foo.bar"] }
782
- pattern.params("/foo/bar") # => { "splat" => ["foo/bar"] }
783
- ```
784
-
785
- ## Syntax
786
-
787
- <table>
788
- <thead>
789
- <tr>
790
- <th>Syntax Element</th>
791
- <th>Description</th>
792
- </tr>
793
- </thead>
794
- <tbody>
795
- <tr>
796
- <td><b>:</b><i>name</i></td>
797
- <td>
798
- Captures anything but a forward slash in a greedy fashion. Capture is named <i>name</i>.
799
- </td>
800
- </tr>
801
- <tr>
802
- <td><b>*</b></td>
803
- <td>
804
- Captures anything in a non-greedy fashion. Capture is named splat.
805
- It is always an array of captures, as you can use <tt>*</tt> more than once in a pattern.
806
- </td>
807
- </tr>
808
- <tr>
809
- <td><i>x</i><b>?</b></td>
810
- <td>Makes <i>x</i> optional. For instance <tt>foo?</tt> matches <tt>foo</tt> or <tt>fo</tt>.</td>
811
- </tr>
812
- <tr>
813
- <td><b>/</b></td>
814
- <td>
815
- Matches forward slash. Does not match URI encoded version of forward slash.
816
- </td>
817
- </tr>
818
- <tr>
819
- <td><i>any special character</i></td>
820
- <td>Matches exactly that character or a URI encoded version of it.</td>
821
- </tr>
822
- <tr>
823
- <td><i>any other character</i></td>
824
- <td>Matches exactly that character.</td>
825
- </tr>
826
- </tbody>
827
- </table>
828
-
829
- <a name="-mustermann-strscan"></a>
830
- # String Scanner for Mustermann
831
-
832
- This gem implements `Mustermann::StringScanner`, a tool inspired by Ruby's [`StringScanner`]() class.
833
-
834
- ``` ruby
835
- require 'mustermann/string_scanner'
836
- scanner = Mustermann::StringScanner.new("here is our example string")
837
-
838
- scanner.scan("here") # => "here"
839
- scanner.getch # => " "
840
-
841
- if scanner.scan(":verb our")
842
- scanner.scan(:noun, capture: :word)
843
- scanner[:verb] # => "is"
844
- scanner[:nound] # => "example"
845
- end
846
-
847
- scanner.rest # => "string"
848
- ```
849
-
850
- You can pass it pattern objects directly:
851
-
852
- ``` ruby
853
- pattern = Mustermann.new(':name')
854
- scanner.check(pattern)
855
- ```
856
-
857
- Or have `#scan` (and other methods) check these for you.
858
-
859
- ``` ruby
860
- scanner.check('{name}', type: :template)
861
- ```
862
-
863
- You can also pass in default options for ad hoc patterns when creating the scanner:
864
-
865
- ``` ruby
866
- scanner = Mustermann::StringScanner.new(input, type: :shell)
867
- ```
868
-
869
- <a name="-mustermann-uri-template"></a>
870
- # URI Template Syntax for Mustermann
871
-
872
- This gem implements the `uri-template` (or `template`) pattern type for Mustermann. It is compatible with [RFC 6570](https://tools.ietf.org/html/rfc6570) (level 4), [JSON API](http://jsonapi.org/), [JSON Home Documents](http://tools.ietf.org/html/draft-nottingham-json-home-02) and [many more](https://code.google.com/p/uri-templates/wiki/Implementations)
873
-
874
- ## Overview
875
-
876
- **Supported options:**
877
- `capture`, `except`, `greedy`, `space_matches_plus`, `uri_decode`, and `ignore_unknown_options`.
878
-
879
- Please keep the following in mind:
880
-
881
- > "Some URI Templates can be used in reverse for the purpose of variable matching: comparing the template to a fully formed URI in order to extract the variable parts from that URI and assign them to the named variables. Variable matching only works well if the template expressions are delimited by the beginning or end of the URI or by characters that cannot be part of the expansion, such as reserved characters surrounding a simple string expression. In general, regular expression languages are better suited for variable matching."
882
- > &mdash; *RFC 6570, Sec 1.5: "Limitations"*
883
-
884
- ``` ruby
885
- require 'mustermann'
886
-
887
- pattern = Mustermann.new('/{example}', type: :template)
888
- pattern === "/foo.bar" # => true
889
- pattern === "/foo/bar" # => false
890
- pattern.params("/foo.bar") # => { "example" => "foo.bar" }
891
- pattern.params("/foo/bar") # => nil
892
-
893
- pattern = Mustermann.new("{/segments*}/{page}{.ext,cmpr:2}", type: :template)
894
- pattern.params("/a/b/c.tar.gz") # => {"segments"=>["a","b"], "page"=>"c", "ext"=>"tar", "cmpr"=>"gz"}
895
- ```
896
-
897
- ## Generating URI Templates
898
-
899
- You do not need to use URI templates (and this gem) if all you want is reusing them for hypermedia links. Most other pattern types support generating these (via `#to_pattern`):
900
-
901
- ``` ruby
902
- require 'mustermann'
903
-
904
- Mustermann.new('/:name').to_templates # => ['/{name}']
905
- ```
906
-
907
- Moreover, Mustermann's default pattern type implements a subset of URI templates (`{capture}` and `{+capture}`) and can therefore also be used for simple templates/
908
-
909
- ``` ruby
910
- require 'mustermann'
911
-
912
- Mustermann.new('/{name}').expand(name: "example") # => "/example"
913
- ```
914
-
915
- ## Syntax
916
-
917
- <table>
918
- <thead>
919
- <tr>
920
- <th>Syntax Element</th>
921
- <th>Description</th>
922
- </tr>
923
- </thead>
924
- <tbody>
925
- <tr>
926
- <td><b>&#123;</b><i>o</i> <i>var</i> <i>m</i><b>,</b> <i>var</i> <i>m</i><b>,</b> ...<b>&#125;</b></td>
927
- <td>
928
- Captures expansion.
929
- Operator <i>o</i>: <code>+ # . / ; ? &amp;</tt> or none.
930
- Modifier <i>m</i>: <code>:num *</tt> or none.
931
- </td>
932
- </tr>
933
- <tr>
934
- <td><b>/</b></td>
935
- <td>
936
- Matches forward slash. Does not match URI encoded version of forward slash.
937
- </td>
938
- </tr>
939
- <tr>
940
- <td><i>any other character</i></td>
941
- <td>Matches exactly that character or a URI encoded version of it.</td>
942
- </tr>
943
- </tbody>
944
- </table>
945
-
946
- The operators `+` and `#` will always match non-greedy, whereas all other operators match semi-greedy by default.
947
- All modifiers and operators are supported. However, it does not parse lists as single values without the *explode* modifier (aka *star*).
948
- Parametric operators (`;`, `?` and `&`) currently only match parameters in given order.
949
-
950
- Note that it differs from URI templates in that it takes the unescaped version of special character instead of the escaped version.
951
-
952
- If you reuse the exact same templates and expose them via an external API meant for expansion,
953
- you should set `uri_decode` to `false` in order to conform with the specification.
954
-
955
-
956
- <a name="-mustermann-visualizer"></a>
957
- # Mustermann Pattern Visualizer
958
-
959
- With this gem, you can visualize the internal structure of a Mustermann pattern:
960
-
961
- * You can generate a **syntax highlighted** version of a pattern object. Both HTML/CSS based highlighting and ANSI color code based highlighting is supported.
962
- * You can turn a pattern object into a **tree** (with ANSI color codes) representing the internal AST. This of course only works for AST based patterns.
963
-
964
- ## Syntax Highlighting
965
-
966
- ![](highlighting.png)
967
-
968
- Loading `mustermann/visualizer` will automatically add `to_html` and `to_ansi` to pattern objects.
969
-
970
- ``` ruby
971
- require 'mustermann/visualizer'
972
- puts Mustermann.new('/:name').to_ansi
973
- puts Mustermann.new('/:name').to_html
974
- ```
975
-
976
- Alternatively, you can also create a separate `highlight` object, which allows finer grained control and more formats:
977
-
978
- ``` ruby
979
- require 'mustermann/visualizer'
980
-
981
- pattern = Mustermann.new('/:name')
982
- highlight = Mustermann::Visualizer.highlight(pattern)
983
-
984
- puts highlight.to_ansi
985
- ```
986
- ### `inspect` mode
987
-
988
- By default, the highlighted string will be a colored version of `to_s`. It is also possible to produce a colored version of `inspect`
989
-
990
- ``` ruby
991
- require 'mustermann/visualizer'
992
-
993
- pattern = Mustermann.new('/:name')
994
-
995
- # directly from the pattern
996
- puts pattern.to_ansi(inspect: true)
997
-
998
- # via the highlighter
999
- highlight = Mustermann::Visualizer.highlight(pattern, inspect: true)
1000
- puts highlight.to_ansi
1001
- ```
1002
-
1003
- ### Themes
1004
-
1005
- ![](theme.png)
1006
-
1007
- element | inherits style from | default theme | note
1008
- -------------|---------------------|---------------|-------------------------
1009
- default | | #839496 | ANSI `\e[10m` if not set
1010
- special | default | #268bd2 |
1011
- capture | special | #cb4b16 |
1012
- name | | #b58900 | always inside `capture`
1013
- char | default | |
1014
- expression | capture | | only exists in URI templates
1015
- composition | special | | meta style, does not exist directly
1016
- composite | composition | | used for composite patterns (contains `root`s)
1017
- group | composition | |
1018
- union | composition | |
1019
- optional | special | |
1020
- root | default | | wraps the whole pattern
1021
- separator | char | #93a1a1 |
1022
- splat | capture | |
1023
- named_splat | splat | |
1024
- variable | capture | | always inside `expression`
1025
- escaped | char | #93a1a1 |
1026
- escaped_char | | | always inside `escaped`
1027
- quote | special | #dc322f | always outside of `root`
1028
- type | special | | always inside `composite`, outside of `root`
1029
- illegal | special | #8b0000 |
1030
-
1031
- You can set theme any of the above elements. The default theme will only be applied if no custom theming is used.
1032
-
1033
- ``` ruby
1034
- # custom theme with highlight object
1035
- highlight = Mustermann::Visualizer.highlight(pattern, special: "#08f")
1036
- puts highlight.to_ansi
1037
- ```
1038
-
1039
- Themes apply both to ANSI and to HTML/CSS output. The exact ANSI code used depends on the terminal and its capabilities.
1040
-
1041
- ### HTML and CSS
1042
-
1043
- By default, the syntax elements will be translated into `span` tags with `style` attributes.
1044
-
1045
- ``` ruby
1046
- Mustermann.new('/:name').to_html
1047
- ```
1048
-
1049
- ``` html
1050
- <span style="color: #839496;"><span style="color: #93a1a1;">/</span><span style="color: #cb4b16;">:<span style="color: #b58900;">name</span></span></span></span>
1051
- ```
1052
-
1053
- You can also set the `css` option to `true` to make it include a stylesheet instead.
1054
-
1055
- ``` ruby
1056
- Mustermann.new('/:name').to_html(css: true)
1057
- ```
1058
-
1059
- ``` html
1060
- <span class="mustermann_pattern"><style type="text/css">
1061
- .mustermann_pattern .mustermann_name {
1062
- color: #b58900;
1063
- }
1064
- /* ... etc ... */
1065
- </style><span class="mustermann_root"><span class="mustermann_separator">/</span><span class="mustermann_capture">:<span class="mustermann_name">name</span></span></span></span>
1066
- ```
1067
-
1068
- Or you can set it to `false`, which will omit `style` attributes, but include `class` attributes.
1069
-
1070
- ``` html
1071
- <span class="mustermann_pattern"><span class="mustermann_root"><span class="mustermann_separator">/</span><span class="mustermann_capture">:<span class="mustermann_name">name</span></span></span></span>
1072
- ```
1073
-
1074
- It is possible to change the class prefix and the tag used.
1075
-
1076
- ``` ruby
1077
- Mustermann.new('/:name').to_html(css: false, class_prefix: "mm_", tag: "tt")
1078
- ```
1079
-
1080
- ``` html
1081
- <tt class="mm_pattern"><tt class="mm_root"><tt class="mm_separator">/</tt><tt class="mm_capture">:<tt class="mm_name">name</tt></tt></tt></tt>
1082
- ```
1083
-
1084
- If you create a highlight object, you can ask it for its `stylesheet`.
1085
-
1086
- ``` erb
1087
- <% highlight = Mustermann::Visualizer.highlight("/:name") %>
1088
-
1089
- <html>
1090
- <head>
1091
- <style type="text/css">
1092
- <%= highlight.stylesheet %>
1093
- </style>
1094
- </head>
1095
- <body>
1096
- <%= highlight.to_html(css: false) %>
1097
- </body>
1098
- </html>
1099
- ```
1100
-
1101
-
1102
- ### Other formats
1103
-
1104
- If you create a highlight object, you have two other formats available: Hansi template strings and s-expression like strings. These might be useful if you want to check how a theme will be applied or as intermediate format for highlighting by other means.
1105
-
1106
- ``` ruby
1107
- require 'mustermann/visualizer'
1108
- highlight = Mustermann::Visualizer.highlight("/:page")
1109
- puts highlight.to_hansi_template
1110
- puts highlight.to_sexp
1111
- ```
1112
-
1113
- **Hansi template strings** wrap elements in tags that are similar to XML tags (though they are not, entity encoding and attributes are not supported, escaping works with a slash, so an escaped `>` would be `\>`, not `&gt;`).
1114
-
1115
- ``` xml
1116
- <pattern><root><separator>/</separator><capture>:<name>page</name></capture></root></pattern>
1117
- ```
1118
-
1119
- The **s-expression like syntax** looks as follows:
1120
-
1121
- ```
1122
- (root (separator /) (capture : (name page)))
1123
- ```
1124
-
1125
- * An expression is enclosed by parens and contains elements separated by spaces. The first element in the expression type (corresponding to themeable elements). These are simple strings. The other elements are either expressions, simple strings or full strings.
1126
- * Simple strings do not contain spaces, parens, single or double quotes or any character that needs to be escaped.
1127
- * Full strings are Ruby strings enclosed by double quotes.
1128
- * Spaces before or after parens are optional.
1129
-
1130
- ### IRB/Pry integration
1131
-
1132
- When `mustermann` is being loaded from within an IRB or Pry session, it will automatically load `mustermann/visualizer` too, if possible.
1133
- When displayed as result, it will be highlighted.
1134
-
1135
- ![](irb.png)
1136
-
1137
- In Pry, this will even work when nested inside other objects (like as element on an array).
1138
-
1139
- ## Tree Rendering
1140
-
1141
- ![](tree.png)
1142
-
1143
- Loading `mustermann/visualizer` will automatically add `to_tree` to pattern objects.
1144
-
1145
- ``` ruby
1146
- require 'mustermann/visualizer'
1147
- puts Mustermann.new("/:page(.:ext)?/*action").to_tree
1148
- ```
1149
-
1150
- For patterns not based on an AST (shell, simple, regexp), it will print out a single line:
1151
-
1152
- pattern (not AST based) "/example"
1153
-
1154
- It will display a tree for identity patterns. While these are not based on an AST internally, Mustermann supports generating an AST for these patterns.
1155
-