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.
- data/Rakefile +19 -40
- data/benchmark.rb +1 -2
- data/book/config.yml +8 -8
- data/book/document.glyph +18 -19
- data/book/images/glyph/commands_tasks.png +0 -0
- data/book/lib/layouts/bookindex.glyph +113 -111
- data/book/lib/layouts/bookpage.glyph +112 -108
- data/book/lib/macros/reference.rb +2 -2
- data/book/lib/tasks/tasks.rake +1 -1
- data/book/text/acknowledgements.glyph +1 -0
- data/book/text/changelog.glyph +140 -112
- data/book/text/compiling/compiling.glyph +36 -24
- data/book/text/compiling/lite_mode.glyph +11 -11
- data/book/text/compiling/programmatic_usage.glyph +57 -57
- data/book/text/config/document.glyph +7 -1
- data/book/text/config/options.glyph +5 -3
- data/book/text/config/output.glyph +41 -8
- data/book/text/extending/bookmarks_headers.glyph +13 -11
- data/book/text/extending/command.glyph +1 -1
- data/book/text/extending/commands_tasks.glyph +2 -2
- data/book/text/extending/internals.glyph +29 -29
- data/book/text/extending/interpreting.glyph +48 -9
- data/book/text/extending/macro_def.glyph +80 -32
- data/book/text/extending/output_format.glyph +2 -2
- data/book/text/extending/placeholders.glyph +27 -15
- data/book/text/extending/validators.glyph +1 -1
- data/book/text/getting_started/configuration.glyph +1 -1
- data/book/text/getting_started/create_project.glyph +4 -5
- data/book/text/getting_started/structure.glyph +2 -2
- data/book/text/macros/macros_core.glyph +341 -199
- data/book/text/macros/macros_filters.glyph +1 -1
- data/book/text/macros/macros_inline.glyph +3 -3
- data/book/text/macros/macros_structure.glyph +1 -1
- data/book/text/ref_commands.glyph +98 -93
- data/book/text/snippets.glyph +18 -0
- data/book/text/stats/bookmarks.glyph +16 -16
- data/book/text/stats/links.glyph +23 -23
- data/book/text/stats/macros.glyph +14 -14
- data/book/text/stats/snippets.glyph +26 -26
- data/book/text/stats/stats.glyph +14 -15
- data/book/text/text_editing/attribute_intro.glyph +8 -8
- data/book/text/text_editing/code.glyph +16 -16
- data/book/text/text_editing/conditionals.glyph +12 -13
- data/book/text/text_editing/esc_quot.glyph +3 -3
- data/book/text/text_editing/evaluation.glyph +57 -3
- data/book/text/text_editing/inclusions.glyph +34 -25
- data/book/text/text_editing/macro_composition.glyph +28 -0
- data/book/text/text_editing/macro_intro.glyph +4 -4
- data/book/text/text_editing/section_aliases.glyph +23 -23
- data/book/text/text_editing/sections.glyph +22 -22
- data/book/text/text_editing/stylesheets.glyph +33 -33
- data/book/text/text_editing/topics.glyph +6 -6
- data/book/text/text_editing/xml_fallback.glyph +1 -1
- data/book/text/troubleshooting/errors_command.glyph +4 -4
- data/book/text/troubleshooting/errors_generic.glyph +16 -10
- data/book/text/troubleshooting/errors_macro.glyph +18 -21
- data/book/text/troubleshooting/errors_parser.glyph +7 -7
- data/config.yml +51 -29
- data/document.glyph +18 -18
- data/glyph.gemspec +39 -287
- data/layouts/web5/topic.glyph +1 -1
- data/lib/glyph.rb +42 -10
- data/lib/glyph/analyzer.rb +5 -2
- data/lib/glyph/bookmark.rb +3 -1
- data/lib/glyph/commands.rb +11 -9
- data/lib/glyph/commands/add.rb +3 -1
- data/lib/glyph/commands/compile.rb +10 -7
- data/lib/glyph/commands/config.rb +7 -5
- data/lib/glyph/commands/init.rb +2 -0
- data/lib/glyph/commands/outline.rb +2 -0
- data/lib/glyph/commands/stats.rb +3 -0
- data/lib/glyph/commands/todo.rb +2 -0
- data/lib/glyph/config.rb +2 -0
- data/lib/glyph/document.rb +34 -9
- data/lib/glyph/interpreter.rb +2 -0
- data/lib/glyph/macro.rb +97 -25
- data/lib/glyph/macro_validators.rb +9 -6
- data/lib/glyph/node.rb +3 -1
- data/lib/glyph/parser.rb +68 -33
- data/lib/glyph/reporter.rb +3 -1
- data/lib/glyph/syntax_node.rb +23 -28
- data/lib/glyph/system_extensions.rb +21 -0
- data/lib/glyph/utils.rb +24 -4
- data/macros/block.rb +111 -0
- data/macros/core.rb +163 -33
- data/macros/filters.rb +3 -2
- data/macros/inline.rb +97 -0
- data/macros/reps/html.rb +180 -0
- data/macros/reps/html5.rb +100 -0
- data/macros/reps/web.rb +4 -0
- data/macros/reps/web5.rb +4 -0
- data/macros/structure.rb +229 -0
- data/macros/xml.rb +29 -24
- data/spec/config.yml +7 -0
- data/spec/files/article.glyph +2 -2
- data/spec/files/web_doc.glyph +9 -5
- data/spec/lib/commands_spec.rb +13 -9
- data/spec/lib/config_spec.rb +2 -2
- data/spec/lib/document_spec.rb +10 -0
- data/spec/lib/glyph_spec.rb +30 -8
- data/spec/lib/macro_spec.rb +39 -4
- data/spec/lib/macro_validators_spec.rb +3 -4
- data/spec/lib/parser_spec.rb +7 -0
- data/spec/lib/reporter_spec.rb +1 -0
- data/spec/lib/syntax_node_spec.rb +40 -6
- data/spec/macros/core_spec.rb +154 -21
- data/spec/macros/filters_spec.rb +1 -1
- data/spec/macros/html5_spec.rb +4 -5
- data/spec/macros/macros_spec.rb +6 -7
- data/spec/macros/web5_spec.rb +3 -3
- data/spec/macros/web_spec.rb +10 -7
- data/spec/macros/xml_spec.rb +11 -2
- data/spec/spec_helper.rb +11 -5
- data/spec/tasks/generate_spec.rb +40 -5
- data/spec/tasks/load_spec.rb +1 -13
- data/styles/coderay.css +147 -38
- data/styles/default.css +19 -22
- data/styles/pagination.css +30 -30
- data/tasks/generate.rake +54 -18
- data/tasks/load.rake +9 -24
- data/tasks/project.rake +0 -2
- metadata +208 -207
- data/.gitignore +0 -7
- data/VERSION +0 -1
- data/book/snippets.yml +0 -18
- data/lib/glyph/macro_helpers.rb +0 -282
- data/macros/html/block.rb +0 -124
- data/macros/html/inline.rb +0 -42
- data/macros/html/structure.rb +0 -191
- data/macros/html5/block.rb +0 -69
- data/macros/html5/inline.rb +0 -24
- 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
|
|
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 =
|
|
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", "
|
|
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
|
|
6
|
+
if snippet? ident then
|
|
7
7
|
begin
|
|
8
8
|
update_source "snippet[#{ident}]"
|
|
9
|
-
interpret
|
|
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
|
-
|
|
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
|
-
|
|
141
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 :
|
|
172
|
-
|
|
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
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
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 "
|
|
199
|
+
macro "define:" do
|
|
186
200
|
safety_check
|
|
187
201
|
exact_parameters 2
|
|
188
|
-
|
|
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 '
|
|
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
|