glyph 0.4.2 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. data/Rakefile +19 -40
  2. data/benchmark.rb +1 -2
  3. data/book/config.yml +8 -8
  4. data/book/document.glyph +18 -19
  5. data/book/images/glyph/commands_tasks.png +0 -0
  6. data/book/lib/layouts/bookindex.glyph +113 -111
  7. data/book/lib/layouts/bookpage.glyph +112 -108
  8. data/book/lib/macros/reference.rb +2 -2
  9. data/book/lib/tasks/tasks.rake +1 -1
  10. data/book/text/acknowledgements.glyph +1 -0
  11. data/book/text/changelog.glyph +140 -112
  12. data/book/text/compiling/compiling.glyph +36 -24
  13. data/book/text/compiling/lite_mode.glyph +11 -11
  14. data/book/text/compiling/programmatic_usage.glyph +57 -57
  15. data/book/text/config/document.glyph +7 -1
  16. data/book/text/config/options.glyph +5 -3
  17. data/book/text/config/output.glyph +41 -8
  18. data/book/text/extending/bookmarks_headers.glyph +13 -11
  19. data/book/text/extending/command.glyph +1 -1
  20. data/book/text/extending/commands_tasks.glyph +2 -2
  21. data/book/text/extending/internals.glyph +29 -29
  22. data/book/text/extending/interpreting.glyph +48 -9
  23. data/book/text/extending/macro_def.glyph +80 -32
  24. data/book/text/extending/output_format.glyph +2 -2
  25. data/book/text/extending/placeholders.glyph +27 -15
  26. data/book/text/extending/validators.glyph +1 -1
  27. data/book/text/getting_started/configuration.glyph +1 -1
  28. data/book/text/getting_started/create_project.glyph +4 -5
  29. data/book/text/getting_started/structure.glyph +2 -2
  30. data/book/text/macros/macros_core.glyph +341 -199
  31. data/book/text/macros/macros_filters.glyph +1 -1
  32. data/book/text/macros/macros_inline.glyph +3 -3
  33. data/book/text/macros/macros_structure.glyph +1 -1
  34. data/book/text/ref_commands.glyph +98 -93
  35. data/book/text/snippets.glyph +18 -0
  36. data/book/text/stats/bookmarks.glyph +16 -16
  37. data/book/text/stats/links.glyph +23 -23
  38. data/book/text/stats/macros.glyph +14 -14
  39. data/book/text/stats/snippets.glyph +26 -26
  40. data/book/text/stats/stats.glyph +14 -15
  41. data/book/text/text_editing/attribute_intro.glyph +8 -8
  42. data/book/text/text_editing/code.glyph +16 -16
  43. data/book/text/text_editing/conditionals.glyph +12 -13
  44. data/book/text/text_editing/esc_quot.glyph +3 -3
  45. data/book/text/text_editing/evaluation.glyph +57 -3
  46. data/book/text/text_editing/inclusions.glyph +34 -25
  47. data/book/text/text_editing/macro_composition.glyph +28 -0
  48. data/book/text/text_editing/macro_intro.glyph +4 -4
  49. data/book/text/text_editing/section_aliases.glyph +23 -23
  50. data/book/text/text_editing/sections.glyph +22 -22
  51. data/book/text/text_editing/stylesheets.glyph +33 -33
  52. data/book/text/text_editing/topics.glyph +6 -6
  53. data/book/text/text_editing/xml_fallback.glyph +1 -1
  54. data/book/text/troubleshooting/errors_command.glyph +4 -4
  55. data/book/text/troubleshooting/errors_generic.glyph +16 -10
  56. data/book/text/troubleshooting/errors_macro.glyph +18 -21
  57. data/book/text/troubleshooting/errors_parser.glyph +7 -7
  58. data/config.yml +51 -29
  59. data/document.glyph +18 -18
  60. data/glyph.gemspec +39 -287
  61. data/layouts/web5/topic.glyph +1 -1
  62. data/lib/glyph.rb +42 -10
  63. data/lib/glyph/analyzer.rb +5 -2
  64. data/lib/glyph/bookmark.rb +3 -1
  65. data/lib/glyph/commands.rb +11 -9
  66. data/lib/glyph/commands/add.rb +3 -1
  67. data/lib/glyph/commands/compile.rb +10 -7
  68. data/lib/glyph/commands/config.rb +7 -5
  69. data/lib/glyph/commands/init.rb +2 -0
  70. data/lib/glyph/commands/outline.rb +2 -0
  71. data/lib/glyph/commands/stats.rb +3 -0
  72. data/lib/glyph/commands/todo.rb +2 -0
  73. data/lib/glyph/config.rb +2 -0
  74. data/lib/glyph/document.rb +34 -9
  75. data/lib/glyph/interpreter.rb +2 -0
  76. data/lib/glyph/macro.rb +97 -25
  77. data/lib/glyph/macro_validators.rb +9 -6
  78. data/lib/glyph/node.rb +3 -1
  79. data/lib/glyph/parser.rb +68 -33
  80. data/lib/glyph/reporter.rb +3 -1
  81. data/lib/glyph/syntax_node.rb +23 -28
  82. data/lib/glyph/system_extensions.rb +21 -0
  83. data/lib/glyph/utils.rb +24 -4
  84. data/macros/block.rb +111 -0
  85. data/macros/core.rb +163 -33
  86. data/macros/filters.rb +3 -2
  87. data/macros/inline.rb +97 -0
  88. data/macros/reps/html.rb +180 -0
  89. data/macros/reps/html5.rb +100 -0
  90. data/macros/reps/web.rb +4 -0
  91. data/macros/reps/web5.rb +4 -0
  92. data/macros/structure.rb +229 -0
  93. data/macros/xml.rb +29 -24
  94. data/spec/config.yml +7 -0
  95. data/spec/files/article.glyph +2 -2
  96. data/spec/files/web_doc.glyph +9 -5
  97. data/spec/lib/commands_spec.rb +13 -9
  98. data/spec/lib/config_spec.rb +2 -2
  99. data/spec/lib/document_spec.rb +10 -0
  100. data/spec/lib/glyph_spec.rb +30 -8
  101. data/spec/lib/macro_spec.rb +39 -4
  102. data/spec/lib/macro_validators_spec.rb +3 -4
  103. data/spec/lib/parser_spec.rb +7 -0
  104. data/spec/lib/reporter_spec.rb +1 -0
  105. data/spec/lib/syntax_node_spec.rb +40 -6
  106. data/spec/macros/core_spec.rb +154 -21
  107. data/spec/macros/filters_spec.rb +1 -1
  108. data/spec/macros/html5_spec.rb +4 -5
  109. data/spec/macros/macros_spec.rb +6 -7
  110. data/spec/macros/web5_spec.rb +3 -3
  111. data/spec/macros/web_spec.rb +10 -7
  112. data/spec/macros/xml_spec.rb +11 -2
  113. data/spec/spec_helper.rb +11 -5
  114. data/spec/tasks/generate_spec.rb +40 -5
  115. data/spec/tasks/load_spec.rb +1 -13
  116. data/styles/coderay.css +147 -38
  117. data/styles/default.css +19 -22
  118. data/styles/pagination.css +30 -30
  119. data/tasks/generate.rake +54 -18
  120. data/tasks/load.rake +9 -24
  121. data/tasks/project.rake +0 -2
  122. metadata +208 -207
  123. data/.gitignore +0 -7
  124. data/VERSION +0 -1
  125. data/book/snippets.yml +0 -18
  126. data/lib/glyph/macro_helpers.rb +0 -282
  127. data/macros/html/block.rb +0 -124
  128. data/macros/html/inline.rb +0 -42
  129. data/macros/html/structure.rb +0 -191
  130. data/macros/html5/block.rb +0 -69
  131. data/macros/html5/inline.rb +0 -24
  132. data/macros/html5/structure.rb +0 -140
@@ -1,12 +1,33 @@
1
+ # Core Symbol class.
1
2
  class Symbol
3
+ # Comparison operator based on the one in the String class.
2
4
  def <=>(b)
3
5
  self.to_s <=> b.to_s
4
6
  end
5
7
  end
6
8
 
9
+ # Core String class.
7
10
  class String
11
+ # Converts the strings to "title case" (capitalizes each word).
8
12
  def title_case
9
13
  self.snake_case.split('_').map{|s| s.capitalize}.join(' ')
10
14
  end
11
15
  end
12
16
 
17
+ # Core Hash class.
18
+ class Hash
19
+ # Converts the hash to a string of Glyph options.
20
+ def to_options(sep=" ")
21
+ "".tap do |s|
22
+ self.each_pair do |k, v|
23
+ key = k.to_s
24
+ s += key.length == 1 ? "-" : "--"
25
+ s += key
26
+ s += sep
27
+ s += v.to_s =~ /\s/ ? "\"#{v}\"" : v.to_s
28
+ s += " "
29
+ end
30
+ end.strip
31
+ end
32
+ end
33
+
data/lib/glyph/utils.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Glyph
2
4
  #@since 0.4.0
3
5
  module Utils
@@ -51,7 +53,7 @@ module Glyph
51
53
  # @return [String] the contents of the file
52
54
  def file_load(file)
53
55
  result = ""
54
- File.open(file.to_s, 'r') do |f|
56
+ File.open(file.to_s, 'r:utf-8') do |f|
55
57
  while l = f.gets
56
58
  result << l
57
59
  end
@@ -64,7 +66,7 @@ module Glyph
64
66
  # @param [String] contents the string to write
65
67
  # @return [String] the string written to the file
66
68
  def file_write(file, contents="")
67
- File.open(file.to_s, 'w+') do |f|
69
+ File.open(file.to_s, 'w+:utf-8') do |f|
68
70
  f.print contents
69
71
  end
70
72
  contents
@@ -96,7 +98,7 @@ module Glyph
96
98
  # @yield [src, dest] the source file and the corresponding output file
97
99
  # @since 0.4.0
98
100
  def with_files_from(dir, &block)
99
- output = (Glyph['document.output'] == 'pdf') ? 'html' : Glyph['document.output']
101
+ output = complex_output? ? 'tmp' : Glyph['document.output']
100
102
  dir_path = Glyph::PROJECT/"output/#{output}/#{dir}"
101
103
  dir_path.mkpath
102
104
  (Glyph::PROJECT/dir).find do |i|
@@ -109,6 +111,13 @@ module Glyph
109
111
  end
110
112
  end
111
113
 
114
+ # Returns true if Glyph['document.output'] requires two or more conversions
115
+ # @since 0.5.0
116
+ def complex_output?
117
+ out = Glyph['document.output']
118
+ !Glyph["output.#{out}.generator"].blank? || !Glyph["output.#{out}.through"].blank?
119
+ end
120
+
112
121
  # Returns true if the macro name is used as an alias
113
122
  # @param [String, Symbol] name the macro name to check
114
123
  def macro_alias?(name)
@@ -145,7 +154,7 @@ module Glyph
145
154
 
146
155
  # Returns true if the PROJECT constant is set to a valid Glyph project directory
147
156
  def project?
148
- children = ["text", "snippets.yml", "config.yml", "document.glyph"].sort
157
+ children = ["text", "config.yml", "document.glyph"].sort
149
158
  actual_children = PROJECT.children.map{|c| c.basename.to_s}.sort
150
159
  (actual_children & children) == children
151
160
  end
@@ -155,5 +164,16 @@ module Glyph
155
164
  Glyph["output.#{Glyph['document.output']}.multifile"]
156
165
  end
157
166
 
167
+ # Execute an external command
168
+ # @since 0.5.0
169
+ def run_external_command(cmd)
170
+ IO.popen(cmd+" 2>&1") do |pipe|
171
+ pipe.sync = true
172
+ while str = pipe.gets do
173
+ puts str
174
+ end
175
+ end
176
+ end
177
+
158
178
  end
159
179
  end
data/macros/block.rb ADDED
@@ -0,0 +1,111 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ macro :note do
5
+ @data[:name] = @name
6
+ @data[:text] = value
7
+ render
8
+ end
9
+
10
+ macro :box do
11
+ exact_parameters 2
12
+ @data[:title] = param 0
13
+ @data[:text] = param 1
14
+ render
15
+ end
16
+
17
+ macro :codeblock do
18
+ exact_parameters 1
19
+ @data[:text] = param 0
20
+ render
21
+ end
22
+
23
+ macro :image do
24
+ min_parameters 1
25
+ max_parameters 3
26
+ image = param(0)
27
+ src_file = Glyph.lite? ? image : Glyph::PROJECT/"images/#{image}"
28
+ dest_file = Glyph.lite? ? image : "images/#{image}"
29
+ warning "Image '#{image}' not found" unless Pathname.new(src_file).exist?
30
+ @data[:attrs] = @node.attrs
31
+ @data[:src] = Glyph["output.#{Glyph['document.output']}.base"].to_s+dest_file
32
+ render
33
+ end
34
+
35
+ macro :figure do
36
+ min_parameters 1
37
+ max_parameters 2
38
+ image = param(0)
39
+ caption = param(1) rescue nil
40
+ src_file = Glyph.lite? ? image : Glyph::PROJECT/"images/#{image}"
41
+ dest_file = Glyph.lite? ? image : "images/#{image}"
42
+ warning "Figure '#{image}' not found" unless Pathname.new(src_file).exist?
43
+ @data[:attrs] = @node.attrs
44
+ @data[:src] = Glyph["output.#{Glyph['document.output']}.base"].to_s+dest_file
45
+ @data[:caption] = param(1)
46
+ render
47
+ end
48
+
49
+ macro :title do
50
+ no_parameters
51
+ unless Glyph["document.title"].blank? then
52
+ render
53
+ else
54
+ ""
55
+ end
56
+ end
57
+
58
+ macro :subtitle do
59
+ no_parameters
60
+ unless Glyph["document.subtitle"].blank? then
61
+ render
62
+ else
63
+ ""
64
+ end
65
+ end
66
+
67
+ macro :author do
68
+ no_parameters
69
+ render
70
+ end
71
+
72
+ # TODO -- document new param!
73
+ macro :pubdate do
74
+ max_parameters 1
75
+ @data[:date] = params(0).blank? ? Time.now.strftime("%B %Y") : params(0)
76
+ render
77
+ end
78
+
79
+ macro :revision do
80
+ no_parameters
81
+ unless Glyph["document.revision"].blank? then
82
+ render
83
+ else
84
+ ""
85
+ end
86
+ end
87
+
88
+ macro :navigation do
89
+ exact_parameters 1
90
+ topic_id = param(0).to_sym
91
+ base_url = Glyph["output.#{Glyph['document.output']}.base"]
92
+ @data[:contents] = render :link, :target => "#{base_url}index.html", :title => "Contents"
93
+ # Get the previous topic
94
+ previous_topic = @node[:document].topics.last
95
+ if previous_topic then
96
+ @data[:previous] = render :link, :target => "#{base_url}#{previous_topic[:src].gsub(/\..+$/, '.html')}", :title => previous_topic[:title]
97
+ else
98
+ @data[:previous] = ""
99
+ end
100
+ # The next topic is not going to be available yet, use a placeholder
101
+ @data[:next] = placeholder do |document|
102
+ current_topic = document.topics.select{|t| t[:id] == topic_id}[0] rescue nil
103
+ next_topic = document.topics[document.topics.index(current_topic)+1] rescue nil
104
+ render :link, :title => next_topic[:title], :target => "#{base_url}#{next_topic[:src].gsub(/\..+$/, '.html')}" if next_topic
105
+ end
106
+ render
107
+ end
108
+
109
+ macro_alias :important => :note
110
+ macro_alias :tip => :note
111
+ macro_alias :caution => :note
data/macros/core.rb CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env ruby
2
+ # encoding: utf-8
2
3
 
3
4
  macro :snippet do
4
- no_mutual_inclusion_in 0
5
5
  ident = value.to_sym
6
- if Glyph::SNIPPETS.has_key? ident then
6
+ if snippet? ident then
7
7
  begin
8
8
  update_source "snippet[#{ident}]"
9
- interpret Glyph::SNIPPETS[ident]
9
+ interpret snippet?(ident)
10
10
  rescue Exception => e
11
11
  case
12
12
  when e.is_a?(Glyph::MutualInclusionError) then
@@ -16,7 +16,6 @@ macro :snippet do
16
16
  else
17
17
  macro_warning e.message, e
18
18
  end
19
- macro_todo "Correct errors in snippet '#{ident}'"
20
19
  end
21
20
  else
22
21
  macro_warning "Snippet '#{ident}' does not exist"
@@ -28,7 +27,7 @@ macro "snippet:" do
28
27
  exact_parameters 2
29
28
  ident = param(0)
30
29
  text = param(1)
31
- Glyph::SNIPPETS[ident.to_sym] = text
30
+ snippet ident, text
32
31
  ""
33
32
  end
34
33
 
@@ -43,6 +42,19 @@ macro "macro:" do
43
42
  ""
44
43
  end
45
44
 
45
+ macro :load do
46
+ safety_check
47
+ exact_parameters 1
48
+ file = param 0
49
+ path = Glyph::PROJECT/file
50
+ if path.exist? then
51
+ file_load path
52
+ else
53
+ macro_warning "File '#{file}' no found."
54
+ "[FILE '#{value}' NOT FOUND]"
55
+ end
56
+ end
57
+
46
58
  macro :include do
47
59
  safety_check
48
60
  exact_parameters 1
@@ -85,10 +97,8 @@ macro :include do
85
97
  raise
86
98
  rescue Glyph::MacroError => e
87
99
  macro_warning e.message, e
88
- macro_todo "Correct errors in file '#{value}'"
89
100
  rescue Exception => e
90
101
  macro_warning e.message, e
91
- macro_todo "Correct errors in file '#{value}'"
92
102
  end
93
103
  end
94
104
  else
@@ -137,44 +147,48 @@ macro :condition do
137
147
  end
138
148
 
139
149
  macro :eq do
140
- within :condition
141
- min_parameters 1
142
- max_parameters 2
143
- (param(0).to_s == param(1).to_s) ? true : nil
150
+ exact_parameters 2
151
+ (param(0) == param(1)) ? true : nil
144
152
  end
145
153
 
146
154
  macro :not do
147
- within :condition
148
155
  max_parameters 1
149
156
  v = param(0).to_s
150
157
  (v.blank? || v == "false") ? true : nil
151
158
  end
152
159
 
153
160
  macro :and do
154
- within :condition
155
- min_parameters 1
156
- max_parameters 2
161
+ exact_parameters 2
157
162
  res_a = !param(0).blank?
158
163
  res_b = !param(1).blank?
159
164
  (res_a && res_b) ? true : nil
160
165
  end
161
166
 
162
167
  macro :or do
163
- within :condition
164
- min_parameters 1
165
- max_parameters 2
168
+ exact_parameters 2
166
169
  res_a = !param(0).blank?
167
170
  res_b = !param(1).blank?
168
171
  (res_a || res_b) ? true : nil
169
172
  end
170
173
 
171
- macro :match do
172
- within :condition
174
+ macro :lt do
175
+ exact_parameters 2
176
+ (param(0) < param(1)) ? true : nil
177
+ end
178
+
179
+ macro :lte do
173
180
  exact_parameters 2
174
- val = param(0).to_s
175
- regexp = param(1).to_s
176
- macro_error "Invalid regular expression: #{regexp}" unless regexp.match /^\/.*\/[a-z]?$/
177
- val.match(instance_eval(regexp)) ? true : nil
181
+ (param(0) <= param(1)) ? true : nil
182
+ end
183
+
184
+ macro :gt do
185
+ exact_parameters 2
186
+ (param(0) > param(1)) ? true : nil
187
+ end
188
+
189
+ macro :gte do
190
+ exact_parameters 2
191
+ (param(0) >= param(1)) ? true : nil
178
192
  end
179
193
 
180
194
  macro "alias:" do
@@ -182,16 +196,10 @@ macro "alias:" do
182
196
  Glyph.macro_alias param(0) => param(1)
183
197
  end
184
198
 
185
- macro "rewrite:" do
199
+ macro "define:" do
186
200
  safety_check
187
201
  exact_parameters 2
188
- macro_name = param(0).to_sym
189
- @node.param(1).descend do |n, level|
190
- if n[:name] == macro_name then
191
- macro_error "Macro '#{macro_name}' cannot be defined by itself"
192
- end
193
- end
194
- Glyph.rewrite macro_name, raw_param(1).dup
202
+ Glyph.define param(0).to_sym, raw_param(1).dup
195
203
  nil
196
204
  end
197
205
 
@@ -199,6 +207,122 @@ macro "output?" do
199
207
  Glyph['document.output'].in? parameters
200
208
  end
201
209
 
210
+ macro :layout do
211
+ dispatch do |node|
212
+ node[:name] = "layout/#{node[:name]}".to_sym
213
+ Glyph::Macro.new(node).expand
214
+ end
215
+ end
216
+
217
+ macro :let do
218
+ exact_parameters 1
219
+ param(0).to_s
220
+ end
221
+
222
+ macro :attribute do
223
+ exact_parameters 1
224
+ a = param(0).to_sym
225
+ macro_node = @node.find_parent do |n|
226
+ n.is_a?(Glyph::MacroNode) && n.attr(a)
227
+ end
228
+ if macro_node then
229
+ Glyph::Macro.new(macro_node).attr(a)
230
+ else
231
+ nil
232
+ end
233
+ end
234
+
235
+ macro "attribute:" do
236
+ exact_parameters 2
237
+ a = param(0).to_sym
238
+ macro_node = @node.find_parent do |n|
239
+ n.is_a?(Glyph::MacroNode) && n.attr(a)
240
+ end
241
+ macro_error "Undeclared attribute '#{a}'" unless macro_node
242
+ attr_value = param(1)
243
+ macro_node.attr(a).children.clear
244
+ macro_node.attr(a) << Glyph::TextNode.new.from(:value => attr_value)
245
+ nil
246
+ end
247
+
248
+ macro :add do
249
+ min_parameters 2
250
+ params.inject(0){|sum, n| sum + n.to_i}
251
+ end
252
+
253
+ macro :subtract do
254
+ min_parameters 2
255
+ params[1..params.length-1].inject(params[0].to_i){|diff, n| diff - n.to_i}
256
+ end
257
+
258
+ macro :multiply do
259
+ min_parameters 2
260
+ params.inject(1){|mult, n| mult * n.to_i}
261
+ end
262
+
263
+ macro :s do
264
+ dispatch do |node|
265
+ forbidden = [:each, :each_line, :each_byte, :upto, :intern, :to_sym, :to_f]
266
+ meth = node[:name]
267
+ infer_type = lambda do |str|
268
+ case
269
+ when str.match(/[+-]?\d+/) then
270
+ # Integer
271
+ str.to_i
272
+ when str.match(/^\/.+?\/[imoxneus]?$/) then
273
+ # Regexp
274
+ Kernel.instance_eval str
275
+ else
276
+ str
277
+ end
278
+ end
279
+ macro_error "Macro 's/#{meth}' takes at least one parameter" unless node.params.length > 0
280
+ macro_error "String method '#{meth}' is not supported" if meth.in?(forbidden) || meth.to_s.match(/\!$/)
281
+ str = node.param(0).evaluate(node, :params => true)
282
+ begin
283
+ if node.param(1) then
284
+ meth_params = node.params[1..node.params.length-1].map{|p| infer_type.call(p.evaluate(node, :params => true))}
285
+ str.send(meth, *meth_params).to_s
286
+ else
287
+ str.send(meth).to_s
288
+ end
289
+ rescue Exception => e
290
+ macro_warning "\"#{str}\".#{meth}(#{meth_params.map{|p| p.inspect}.join(', ') rescue nil}) - #{e.message}", e
291
+ ""
292
+ end
293
+ end
294
+ end
295
+
296
+ macro :while do
297
+ exact_parameters 2
298
+ raw_cond = @node.parameter 0
299
+ raw_body = @node.parameter 1
300
+ cond = raw_cond.evaluate(@node, :params => true)
301
+ while (!cond.blank? && cond != "false") do
302
+ result = raw_body.evaluate(@node, :params => true)
303
+ cond = raw_cond.evaluate(@node, :params => true)
304
+ result
305
+ end
306
+ end
307
+
308
+ macro :fragment do
309
+ exact_parameters 2
310
+ ident, contents = param(0).to_sym, param(1)
311
+ macro_error "Fragment '#{ident}' is already defined" if @node[:document].fragments.has_key? ident
312
+ @node[:document].fragments[ident] = contents
313
+ end
314
+
315
+ macro :embed do
316
+ exact_parameters 1
317
+ ident = param(0).to_sym
318
+ placeholder do |document|
319
+ fragment = document.fragments[ident]
320
+ macro_error "Fragment '#{ident}' is not defined" unless fragment
321
+ fragment
322
+ end
323
+ end
324
+
325
+
202
326
  macro_alias '--' => :comment
203
327
  macro_alias '&' => :snippet
204
328
  macro_alias '&:' => 'snippet:'
@@ -208,4 +332,10 @@ macro_alias '$' => :config
208
332
  macro_alias '$:' => 'config:'
209
333
  macro_alias '.' => :escape
210
334
  macro_alias '?' => :condition
211
- macro_alias 'rw:' => 'rewrite:'
335
+ macro_alias 'def:' => 'define:'
336
+ macro_alias '@' => :attribute
337
+ macro_alias :attr => :attribute
338
+ macro_alias '@:' => "attribute:"
339
+ macro_alias "attr:" => "attribute:"
340
+ macro_alias "##" => :fragment
341
+ macro_alias "<=" => :embed