glyph 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. data/AUTHORS.textile +8 -0
  2. data/CHANGELOG.textile +260 -0
  3. data/LICENSE.textile +26 -0
  4. data/README.textile +49 -21
  5. data/Rakefile +17 -7
  6. data/VERSION +1 -1
  7. data/book/config.yml +11 -5
  8. data/book/document.glyph +24 -13
  9. data/book/lib/macros/reference.rb +41 -14
  10. data/book/output/html/glyph.html +2298 -687
  11. data/book/output/pdf/glyph.pdf +6218 -2698
  12. data/book/script/authors +1 -0
  13. data/book/script/changelog +1 -0
  14. data/book/script/compile.rb +8 -0
  15. data/book/script/license +1 -0
  16. data/book/script/prof +1 -0
  17. data/book/script/prof_results.htm +21079 -0
  18. data/book/script/readme +1 -0
  19. data/book/snippets.yml +3 -4
  20. data/book/text/acknowledgement.glyph +8 -0
  21. data/book/text/authoring.glyph +548 -0
  22. data/book/text/changelog.glyph +76 -0
  23. data/book/text/extending.glyph +224 -0
  24. data/book/text/{getting_started.textile → getting_started.glyph} +30 -24
  25. data/book/text/{introduction.textile → introduction.glyph} +22 -12
  26. data/book/text/license.glyph +21 -0
  27. data/book/text/{ref_commands.textile → ref_commands.glyph} +30 -8
  28. data/book/text/ref_config.glyph +108 -0
  29. data/book/text/ref_macros.glyph +378 -0
  30. data/book/text/troubleshooting.glyph +179 -0
  31. data/config.yml +16 -4
  32. data/glyph.gemspec +83 -22
  33. data/lib/glyph.rb +164 -31
  34. data/lib/glyph/commands.rb +98 -23
  35. data/lib/glyph/document.rb +13 -7
  36. data/lib/glyph/glyph_language.rb +9 -1
  37. data/lib/glyph/glyph_language.treetop +1 -1
  38. data/lib/glyph/interpreter.rb +19 -9
  39. data/lib/glyph/macro.rb +88 -11
  40. data/lib/glyph/macro_validators.rb +48 -0
  41. data/lib/glyph/node.rb +13 -1
  42. data/lib/glyph/system_extensions.rb +0 -28
  43. data/macros/common.rb +125 -31
  44. data/macros/filters.rb +19 -13
  45. data/macros/html/block.rb +119 -68
  46. data/macros/html/inline.rb +29 -3
  47. data/macros/html/structure.rb +40 -40
  48. data/spec/files/article.glyph +5 -0
  49. data/spec/lib/commands_spec.rb +98 -3
  50. data/spec/lib/document_spec.rb +15 -2
  51. data/spec/lib/glyph_spec.rb +39 -10
  52. data/spec/lib/interpreter_spec.rb +8 -2
  53. data/spec/lib/macro_spec.rb +54 -6
  54. data/spec/lib/macro_validators_spec.rb +33 -0
  55. data/spec/lib/node_spec.rb +11 -3
  56. data/spec/macros/filters_spec.rb +5 -5
  57. data/spec/macros/macros_spec.rb +185 -8
  58. data/spec/macros/textile_spec.rb +217 -0
  59. data/spec/spec_helper.rb +25 -15
  60. data/spec/tasks/generate_spec.rb +3 -3
  61. data/spec/tasks/load_spec.rb +11 -1
  62. data/spec/tasks/project_spec.rb +0 -3
  63. data/styles/coderay.css +121 -0
  64. data/styles/default.css +54 -20
  65. data/{book/styles/css3.css → styles/pagination.css} +35 -7
  66. data/styles/ultraviolet/active4d.css +114 -0
  67. data/styles/ultraviolet/all_hallows_eve.css +72 -0
  68. data/styles/ultraviolet/amy.css +147 -0
  69. data/styles/ultraviolet/blackboard.css +88 -0
  70. data/styles/ultraviolet/brilliance_black.css +605 -0
  71. data/styles/ultraviolet/brilliance_dull.css +599 -0
  72. data/styles/ultraviolet/cobalt.css +149 -0
  73. data/styles/ultraviolet/dawn.css +121 -0
  74. data/styles/ultraviolet/eiffel.css +121 -0
  75. data/styles/ultraviolet/espresso_libre.css +109 -0
  76. data/styles/ultraviolet/idle.css +62 -0
  77. data/styles/ultraviolet/iplastic.css +80 -0
  78. data/styles/ultraviolet/lazy.css +73 -0
  79. data/styles/ultraviolet/mac_classic.css +123 -0
  80. data/styles/ultraviolet/magicwb_amiga.css +104 -0
  81. data/styles/ultraviolet/pastels_on_dark.css +188 -0
  82. data/styles/ultraviolet/slush_poppies.css +85 -0
  83. data/styles/ultraviolet/spacecadet.css +51 -0
  84. data/styles/ultraviolet/sunburst.css +180 -0
  85. data/styles/ultraviolet/twilight.css +137 -0
  86. data/styles/ultraviolet/zenburnesque.css +91 -0
  87. data/tasks/generate.rake +45 -26
  88. data/tasks/load.rake +21 -18
  89. data/tasks/project.rake +3 -1
  90. metadata +210 -41
  91. data/book/styles/default.css +0 -190
  92. data/book/text/authoring.textile +0 -351
  93. data/book/text/extending.textile +0 -148
  94. data/book/text/ref_config.textile +0 -0
  95. data/book/text/ref_macros.textile +0 -256
  96. data/book/text/troubleshooting.textile +0 -118
  97. data/styles/css3.css +0 -220
@@ -0,0 +1,48 @@
1
+ module Glyph
2
+ class Macro
3
+
4
+ module Validators
5
+
6
+ # Validates the macro according to the specified block
7
+ # @param [String] message the message to display if the validation fails.
8
+ # @param [Hash] options a hash containing validation options (for now the only option is :level)
9
+ # @example
10
+ # validate("Invalid macro value", :level => :error) {@value == 'valid'} # Raises an error in case of failure
11
+ # validate("Invalid macro value", :level => :warning) {@value == 'valid'} # Displays a warning in case of failure
12
+ def validate(message, options={:level => :error}, &block)
13
+ unless instance_eval(&block) then
14
+ send("macro_#{options[:level]}".to_sym, message)
15
+ end
16
+ end
17
+
18
+ # Ensures that the macro receives up to _n_ parameters.
19
+ # @param [Integer] n the maximum number of parameters allowed for the macro.
20
+ # @param [Hash] options a hash containing validation options (for now the only option is :level)
21
+ def max_parameters(n, options={:level=>:error})
22
+ validate("Macro '#{@name}' takes up to #{n} parameter(s) (#{params.length} given)", options) { params.length <= n }
23
+ end
24
+
25
+ # Ensures that the macro receives at least _n_ parameters.
26
+ # @param [Integer] n the minimum number of parameters allowed for the macro.
27
+ # @param [Hash] options a hash containing validation options (for now the only option is :level)
28
+ def min_parameters(n, options={:level=>:error})
29
+ validate("Macro '#{@name}' takes at least #{n} parameter(s) (#{params.length} given)", options) { params.length >= n }
30
+ end
31
+
32
+ # Ensures that the macro receives exactly _n_ parameters.
33
+ # @param [Integer] n the number of parameters allowed for the macro.
34
+ # @param [Hash] options a hash containing validation options (for now the only option is :level)
35
+ def exact_parameters(n, options={:level=>:error})
36
+ validate("Macro '#{@name}' takes exactly #{n} parameter(s) (#{params.length} given)", options) { params.length == n }
37
+ end
38
+
39
+ # Ensures that the macro receives no parameters.
40
+ # @param [Hash] options a hash containing validation options (for now the only option is :level)
41
+ def no_parameters(options={:level=>:error})
42
+ validate("Macro '#{@name}' takes no parameters (#{params.length} given)", options) { params.length == 0 }
43
+ end
44
+
45
+ end
46
+
47
+ end
48
+ end
data/lib/glyph/node.rb CHANGED
@@ -55,6 +55,15 @@ class Node < Hash
55
55
  @children << ht
56
56
  end
57
57
 
58
+ # Removes a child node from self
59
+ # @param [node] node the child node to remove
60
+ # @raise [ArgumentError] unless an existing child node is passed as parameter
61
+ def >>(node)
62
+ raise ArgumentError, "Unknown child node" unless @children.include? node
63
+ node.parent = nil
64
+ @children.delete node
65
+ end
66
+
58
67
  # Returns a child by its index
59
68
  # @return [Node] the child node or nil
60
69
  # @param [Integer] index the child index
@@ -62,7 +71,10 @@ class Node < Hash
62
71
  @children[index]
63
72
  end
64
73
 
65
- alias >> child
74
+ # See Node#child.
75
+ def &(index)
76
+ @children[index]
77
+ end
66
78
 
67
79
  # Iterates through children
68
80
  # @yieldparam [Node] c the child node
@@ -1,22 +1,5 @@
1
1
  module Kernel
2
2
 
3
- # Prints a message
4
- # @param [#to_s] message the message to print
5
- def info(message)
6
- puts "#{message}" unless cfg :quiet
7
- end
8
-
9
- # Prints a warning
10
- # @param [#to_s] message the message to print
11
- def warning(message)
12
- puts "warning: #{message}" unless cfg :quiet
13
- end
14
-
15
- # @see Glyph::Config#get
16
- def cfg(setting)
17
- Glyph::CONFIG.get(setting)
18
- end
19
-
20
3
  # Dumps and serialize an object to a YAML file
21
4
  # @param [#to_s] file the file to write to
22
5
  # @param [Object] obj the object to serialize
@@ -64,14 +47,3 @@ module Kernel
64
47
  end
65
48
 
66
49
  end
67
-
68
- class MacroError < RuntimeError
69
- attr_reader :node
70
- def initialize(node, msg)
71
- @node = node
72
- source = @node[:source] || "--"
73
- macros = []
74
- @node.ascend {|n| macros << n[:macro].to_s if n[:macro] }
75
- super("#{msg}\n -> source: #{source}\n -> path: #{macros.reverse.join('/')}")
76
- end
77
- end
data/macros/common.rb CHANGED
@@ -1,66 +1,160 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
-
4
- macro :comment do
5
- ""
3
+ macro :snippet do
4
+ ident = @value.to_sym
5
+ if Glyph::SNIPPETS.has_key? ident then
6
+ begin
7
+ interpret Glyph::SNIPPETS[ident]
8
+ rescue Exception => e
9
+ raise if e.is_a? Glyph::MutualInclusionError
10
+ Glyph.warning e.message
11
+ macro_todo "Correct errors in snippet '#{@value}'"
12
+ end
13
+ else
14
+ macro_warning "Snippet '#{ident}' does not exist"
15
+ "[SNIPPET '#{@value}' NOT PROCESSED]"
16
+ end
6
17
  end
7
18
 
8
- macro :todo do
9
- todo = "[#{@source}] -- #{@value}"
10
- Glyph::TODOS << todo unless Glyph::TODOS.include? todo
19
+ macro "snippet:" do
20
+ exact_parameters 2
21
+ ident, text = params
22
+ Glyph::SNIPPETS[ident.to_sym] = text
11
23
  ""
12
24
  end
13
25
 
14
- macro :snippet do
15
- begin
16
- ident = @params[0].to_sym
17
- macro_error "Snippet '#{ident}' does not exist" unless Glyph::SNIPPETS.has_key? ident
18
- interpret Glyph::SNIPPETS[ident]
19
- rescue Exception => e
20
- warning e.message
21
- "[SNIPPET '#{@value}' NOT PROCESSED]"
26
+ macro "macro:" do
27
+ exact_parameters 2
28
+ ident, code = params
29
+ Glyph.macro(ident) do
30
+ instance_eval code
22
31
  end
32
+ ""
23
33
  end
24
34
 
25
35
  macro :include do
26
- begin
27
- file = nil
28
- (Glyph::PROJECT/"text").find do |f|
29
- file = f if f.to_s.match /\/#{@value}$/
30
- end
31
- macro_error "File '#{@value}' no found." unless file
36
+ macro_error "Macro not available when compiling a single file." if Glyph.lite?
37
+ file = nil
38
+ (Glyph::PROJECT/"text").find do |f|
39
+ file = f if f.to_s.match /\/#{@value}$/
40
+ end
41
+ if file then
32
42
  contents = file_load file
33
- if cfg("filters.by_file_extension") then
34
- begin
35
- ext = @value.match(/\.(.*)$/)[1]
36
- macro_error "Filter macro '#{ext}' not found" unless Glyph::MACROS.include?(ext.to_sym)
43
+ ext = @value.match(/\.(.*)$/)[1]
44
+ if Glyph["filters.by_file_extension"] && ext != 'glyph' then
45
+ if Glyph::MACROS.include?(ext.to_sym) then
37
46
  contents = "#{ext}[#{contents}]"
38
- rescue MacroError => e
39
- warning e.message
47
+ else
48
+ macro_warning "Filter macro '#{ext}' not available"
40
49
  end
41
50
  end
42
- interpret contents
43
- rescue MacroError => e
44
- warning e
51
+ begin
52
+ interpret contents
53
+ rescue Exception => e
54
+ raise if e.is_a? Glyph::MutualInclusionError
55
+ Glyph.warning e.message
56
+ macro_todo "Correct errors in file '#{@value}'"
57
+ end
58
+ else
59
+ macro_warning "File '#{@value}' no found."
45
60
  "[FILE '#{@value}' NOT FOUND]"
46
61
  end
47
62
  end
48
63
 
49
64
  macro :ruby do
50
- Kernel.instance_eval(@value)
65
+ res = Glyph.instance_eval(@value.gsub(/\\*([\[\]\|])/){$1})
66
+ res.is_a?(Proc) ? "" : res
51
67
  end
52
68
 
53
69
  macro :config do
54
- cfg @value
70
+ Glyph[@value]
71
+ end
72
+
73
+ macro "config:" do
74
+ exact_parameters 2
75
+ setting,value = params
76
+ Glyph[setting] = value
77
+ nil
78
+ end
79
+
80
+ macro :comment do
81
+ ""
55
82
  end
56
83
 
57
84
  macro :escape do
58
85
  @value
59
86
  end
60
87
 
88
+ macro :encode do
89
+ encode @value
90
+ end
91
+
92
+ macro :decode do
93
+ decode @value
94
+ end
95
+
96
+ macro :condition do
97
+ min_parameters 1
98
+ max_parameters 2
99
+ cond, actual_value = params
100
+ res = interpret(cond)
101
+ if res.blank? || res == "false" then
102
+ ""
103
+ else
104
+ interpret(decode(actual_value))
105
+ end
106
+ end
107
+
108
+
109
+ macro :eq do
110
+ min_parameters 1
111
+ max_parameters 2
112
+ a, b = params
113
+ res_a = interpret(a.to_s)
114
+ res_b = interpret(b.to_s)
115
+ (res_a == res_b) ? true : nil
116
+ end
117
+
118
+ macro :not do
119
+ max_parameters 1
120
+ v = interpret(@value)
121
+ (v.blank? || v == "false") ? true : nil
122
+ end
123
+
124
+ macro :and do
125
+ min_parameters 1
126
+ max_parameters 2
127
+ a, b = params
128
+ res_a = !interpret(a.to_s).blank?
129
+ res_b = !interpret(b.to_s).blank?
130
+ (res_a && res_b) ? true : nil
131
+ end
132
+
133
+ macro :or do
134
+ min_parameters 1
135
+ max_parameters 2
136
+ a, b = params
137
+ res_a = !interpret(a.to_s).blank?
138
+ res_b = !interpret(b.to_s).blank?
139
+ (res_a || res_b) ? true : nil
140
+ end
141
+
142
+ macro :match do
143
+ exact_parameters 2
144
+ val, regexp = params
145
+ macro_error "Invalid regular expression: #{regexp}" unless regexp.match /^\/.*\/[a-z]?$/
146
+ (interpret(val).match(instance_eval(regexp))) ? true : nil
147
+ end
148
+
61
149
  macro_alias '--' => :comment
150
+ macro_alias '*' => :encode
151
+ macro_alias '**' => :decode
62
152
  macro_alias '&' => :snippet
153
+ macro_alias '&:' => 'snippet:'
154
+ macro_alias '%:' => 'macro:'
63
155
  macro_alias '@' => :include
64
156
  macro_alias '%' => :ruby
65
157
  macro_alias '$' => :config
158
+ macro_alias '$:' => 'config:'
66
159
  macro_alias '.' => :escape
160
+ macro_alias '?' => :condition
data/macros/filters.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  macro :textile do
4
+ exact_parameters 1, :level => :warning
4
5
  rc = nil
5
6
  begin
6
7
  require 'RedCloth'
@@ -8,7 +9,7 @@ macro :textile do
8
9
  rescue Exception
9
10
  macro_error "RedCloth gem not installed. Please run: gem insall RedCloth"
10
11
  end
11
- target = cfg "filters.target"
12
+ target = Glyph["filters.target"]
12
13
  case target.to_sym
13
14
  when :html
14
15
  rc.to_html.gsub /<p><\/p>/, ''
@@ -20,45 +21,50 @@ macro :textile do
20
21
  end
21
22
 
22
23
  macro :markdown do
24
+ exact_parameters 1, :level => :warning
23
25
  md = nil
24
- markdown_converter = cfg "filters.markdown_converter"
26
+ markdown_converter = Glyph["filters.markdown_converter"].to_sym rescue nil
25
27
  if !markdown_converter then
26
28
  begin
27
29
  require 'bluecloth'
28
- markdown_converter = :BlueCloth
30
+ markdown_converter = :bluecloth
29
31
  rescue LoadError
30
32
  begin
31
33
  require 'rdiscount'
32
- markdown_converter = :RDiscount
34
+ markdown_converter = :rdiscount
33
35
  rescue LoadError
34
36
  begin
35
37
  require 'maruku'
36
- markdown_converter = :Maruku
38
+ markdown_converter = :maruku
37
39
  rescue LoadError
38
40
  begin
39
41
  require 'kramdown'
40
- markdown_converter = :Kramdown
42
+ markdown_converter = :kramdown
41
43
  rescue LoadError
42
- macro_error "No MarkDown converter installed. Please run: gem insall bluecloth"
44
+ macro_error "No MarkDown converter installed. Please run: gem install bluecloth"
43
45
  end
44
46
  end
45
47
  end
46
48
  end
47
- Glyph.config_override "filters.markdown_converter", markdown_converter
49
+ Glyph["filters.markdown_converter"] = markdown_converter
48
50
  end
49
51
  case markdown_converter
50
- when :BlueCloth
52
+ when :bluecloth
53
+ require 'bluecloth'
51
54
  md = BlueCloth.new @value
52
- when :RDiscount
55
+ when :rdiscount
56
+ require 'rdiscount'
53
57
  md = RDiscount.new @value
54
- when :Maruku
58
+ when :maruku
59
+ require 'maruku'
55
60
  md = Maruku.new @value
56
- when :Kramdown
61
+ when :kramdown
62
+ require 'kramdown'
57
63
  md = Kramdown::Document.new @value
58
64
  else
59
65
  macro_error "No MarkDown converter installed. Please run: gem insall bluecloth"
60
66
  end
61
- target = cfg "filters.target"
67
+ target = Glyph["filters.target"]
62
68
  if target.to_sym == :html then
63
69
  md.to_html
64
70
  else
data/macros/html/block.rb CHANGED
@@ -1,117 +1,168 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  macro :note do
4
- %{<div class="#{@name}"><span class="note-title">#{@name.to_s.capitalize}</span>#{@value}
4
+ %{<div class="#{@name}">
5
+ <span class="note-title">#{@name.to_s.capitalize}</span>#{@value}
5
6
 
6
- </div>}
7
+ </div>}
7
8
  end
8
9
 
9
10
  macro :box do
10
- %{<div class="box"><span class="box-title">#{@params[0]}</span>
11
- #{@params[1]}
11
+ exact_parameters 2, :level => :warning
12
+ %{<div class="box">
13
+ <div class="box-title">#{params[0]}</div>
14
+ #{params[1]}
12
15
 
13
- </div>}
16
+ </div>}
14
17
  end
15
18
 
16
19
  macro :code do
17
- %{<div class="code"><pre><code>
18
- #{@value.gsub('>', '&gt;').gsub('<', '&lt;')}
19
- </code></pre></div>}
20
+ min_parameters 1
21
+ %{
22
+ <div class="code">
23
+ <pre>
24
+ <code>
25
+ #{@value}
26
+ </code>
27
+ </pre>
28
+ </div>}
29
+ end
30
+
31
+ macro :highlight do
32
+ min_parameters 2
33
+ lang = params[0]
34
+ text = raw_params[1..raw_params.length-1].join '\\|'
35
+ text.gsub!(/\\(.)/){$1}
36
+ highlighter = Glyph["highlighters.current"].to_sym rescue nil
37
+ if !highlighter then
38
+ begin
39
+ require 'coderay'
40
+ highlighter = :coderay
41
+ rescue LoadError
42
+ begin
43
+ require 'uv'
44
+ highlighter = :ultraviolet
45
+ rescue LoadError
46
+ macro_error "No highlighter installed. Please run: gem install coderay"
47
+ end
48
+ end
49
+ Glyph["highlighter.current"] = highlighter
50
+ end
51
+ target = Glyph["highlighters.target"]
52
+ result = ""
53
+ case highlighter.to_sym
54
+ when :coderay
55
+ begin
56
+ require 'coderay'
57
+ result = CodeRay.scan(text, lang).div(Glyph["highlighters.coderay"])
58
+ rescue LoadError
59
+ macro_error "CodeRay highlighter not installed. Please run: gem install coderay"
60
+ rescue Exception => e
61
+ macro_error e.message
62
+ end
63
+ when :ultraviolet
64
+ begin
65
+ require 'uv'
66
+ target = 'xhtml' if target == 'html'
67
+ result = Uv.parse(text.to_s, target.to_s, lang.to_s,
68
+ Glyph["highlighters.ultraviolet.line_numbers"],
69
+ Glyph["highlighters.ultraviolet.theme"].to_s)
70
+ rescue LoadError
71
+ macro_error "UltraViolet highlighter not installed. Please run: gem install ultraviolet"
72
+ rescue Exception => e
73
+ puts e.backtrace
74
+ macro_error e.message
75
+ end
76
+ else
77
+ macro_error "No highlighter installed. Please run: gem install coderay"
78
+ end
79
+ result
20
80
  end
21
81
 
22
82
  macro :title do
23
- %{
24
- <h1>
25
- #{cfg("document.title")}
26
- </h1>
27
- }
83
+ no_parameters
84
+ %{<h1>
85
+ #{Glyph["document.title"]}
86
+ </h1>}
28
87
  end
29
88
 
30
89
  macro :img do
31
- image = @params[0]
32
- width = @params[1]
90
+ min_parameters 1
91
+ max_parameters 3
92
+ image = params[0]
93
+ width = params[1]
94
+ source_file = Glyph.lite? ? image : Glyph::PROJECT/"images/#{image}"
95
+ dest_file = Glyph.lite? ? image : "images/#{image}"
33
96
  w = (width) ? "width=\"#{width}\"" : ''
34
- height = @params[2]
97
+ height = params[2]
35
98
  h = (height) ? "height=\"#{height}\"" : ''
36
- if (Glyph::PROJECT/"images/#{image}").exist? then
37
- %{
38
- <img src="images/#{image}" #{w} #{h} alt="-"/>
39
- }
40
- else
41
- warning "Image '#{image}' not found"
42
- ""
43
- end
99
+ Glyph.warning "Image '#{image}' not found" unless Pathname.new(dest_file).exist?
100
+ %{<img src="#{dest_file}" #{w} #{h} alt="-"/>}
44
101
  end
45
102
 
46
103
  macro :fig do
47
- image = @params[0]
48
- caption = @params[1]
104
+ min_parameters 1
105
+ max_parameters 2
106
+ image = params[0]
107
+ caption = params[1]
49
108
  caption ||= nil
50
109
  caption = %{<div class="caption">#{caption}</div>} if caption
51
- if (Glyph::PROJECT/"images/#{image}").exist? then
52
- %{
53
- <div class="figure">
54
- <img src="images/#{image}" alt="-"/>
55
- #{caption}
56
- </div>
57
- }
58
- else
59
- warning "Figure '#{image}' not found"
60
- ""
61
- end
110
+ source_file = Glyph.lite? ? image : Glyph::PROJECT/"images/#{image}"
111
+ dest_file = Glyph.lite? ? image : "images/#{image}"
112
+ Glyph.warning "Figure '#{image}' not found" unless Pathname.new(dest_file).exist?
113
+ %{<div class="figure">
114
+ <img src="#{dest_file}" alt="-"/>
115
+ #{caption}
116
+ </div>}
62
117
  end
63
118
 
64
119
 
65
120
  macro :subtitle do
66
- %{
67
- <h2>
68
- #{cfg("document.subtitle")}
69
- </h2>
70
- }
121
+ no_parameters
122
+ %{<h2>
123
+ #{Glyph["document.subtitle"]}
124
+ </h2>}
71
125
  end
72
126
 
73
127
  macro :author do
74
- %{
75
- <div class="author">
76
- by <em>#{cfg("document.author")}</em>
77
- </div>
78
- }
128
+ no_parameters
129
+ %{<div class="author">
130
+ by <em>#{Glyph["document.author"]}</em>
131
+ </div>}
79
132
  end
80
133
 
81
134
  macro :pubdate do
82
- %{
83
- <div class="pubdate">
84
- #{Time.now.strftime("%B %Y")}
85
- </div>
86
- }
135
+ no_parameters
136
+ %{<div class="pubdate">
137
+ #{Time.now.strftime("%B %Y")}
138
+ </div>}
87
139
  end
88
140
 
89
141
  macro :table do
90
- %{
91
- <table>#{@value}
92
- </table>
93
- }
142
+ exact_parameters 1
143
+ %{<table>
144
+ #{@value}
145
+ </table>}
94
146
  end
95
147
 
96
148
  macro :tr do
97
- %{
98
- <tr>#{@value}
99
- </tr>
100
- }
149
+ exact_parameters 1, :level => :warning
150
+ %{<tr>
151
+ #{@value}
152
+ </tr>}
101
153
  end
102
154
 
103
155
  macro :td do
104
- %{
105
- <td>#{@value}
106
- </td>
107
- }
156
+ exact_parameters 1, :level => :warning
157
+ %{<td>
158
+ #{@value}
159
+
160
+ </td>}
108
161
  end
109
162
 
110
163
  macro :th do
111
- %{
112
- <th>#{@value}
113
- </th>
114
- }
164
+ exact_parameters 1, :level => :warning
165
+ %{<th>#{@value}</th>}
115
166
  end
116
167
 
117
168
  macro_alias :important => :note