glyph 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS.textile +1 -1
- data/CHANGELOG.textile +119 -222
- data/LICENSE.textile +1 -1
- data/README.textile +42 -23
- data/Rakefile +1 -3
- data/VERSION +1 -1
- data/benchmark.rb +72 -0
- data/book/config.yml +4 -4
- data/book/document.glyph +90 -57
- data/book/images/document_generation.png +0 -0
- data/book/lib/macros/reference.rb +75 -22
- data/book/output/html/glyph.html +3183 -2121
- data/book/output/html/images/document_generation.png +0 -0
- data/book/output/pdf/glyph.pdf +7370 -4913
- data/book/resources/document_generation.txt +34 -0
- data/book/snippets.yml +6 -0
- data/book/text/changelog.glyph +45 -34
- data/book/text/compiling/compiling.glyph +23 -0
- data/book/text/compiling/lite_mode.glyph +23 -0
- data/book/text/compiling/programmatic_usage.glyph +77 -0
- data/book/text/extending/bookmarks_headers.glyph +21 -0
- data/book/text/extending/further_reading.glyph +13 -0
- data/book/text/extending/internals.glyph +79 -0
- data/book/text/extending/interpreting.glyph +51 -0
- data/book/text/extending/macro_def.glyph +64 -0
- data/book/text/extending/params_attrs.glyph +70 -0
- data/book/text/extending/placeholders.glyph +34 -0
- data/book/text/extending/validators.glyph +16 -0
- data/book/text/getting_started/configuration.glyph +49 -0
- data/book/text/getting_started/create_project.glyph +41 -0
- data/book/text/getting_started/structure.glyph +55 -0
- data/book/text/introduction.glyph +49 -26
- data/book/text/license.glyph +1 -1
- data/book/text/macros/macros_block.glyph +99 -0
- data/book/text/macros/macros_core.glyph +208 -0
- data/book/text/macros/macros_filters.glyph +40 -0
- data/book/text/macros/macros_inline.glyph +50 -0
- data/book/text/macros/macros_structure.glyph +100 -0
- data/book/text/ref_commands.glyph +94 -73
- data/book/text/ref_config.glyph +34 -42
- data/book/text/ref_macros.glyph +1 -373
- data/book/text/text_editing/code.glyph +51 -0
- data/book/text/text_editing/conditionals.glyph +49 -0
- data/book/text/text_editing/evaluation.glyph +13 -0
- data/book/text/text_editing/glyph_files.glyph +7 -0
- data/book/text/text_editing/images.glyph +29 -0
- data/book/text/text_editing/inclusions.glyph +44 -0
- data/book/text/text_editing/links.glyph +53 -0
- data/book/text/text_editing/macro_intro.glyph +111 -0
- data/book/text/text_editing/raw_html.glyph +112 -0
- data/book/text/text_editing/sections.glyph +63 -0
- data/book/text/text_editing/stylesheets.glyph +36 -0
- data/book/text/troubleshooting/errors_command.glyph +39 -0
- data/book/text/troubleshooting/errors_generic.glyph +29 -0
- data/book/text/troubleshooting/errors_intro.glyph +3 -0
- data/book/text/troubleshooting/errors_macro.glyph +98 -0
- data/book/text/troubleshooting/errors_parser.glyph +29 -0
- data/config.yml +77 -58
- data/document.glyph +25 -25
- data/glyph.gemspec +57 -22
- data/lib/glyph.rb +54 -13
- data/lib/glyph/commands.rb +84 -17
- data/lib/glyph/config.rb +3 -3
- data/lib/glyph/document.rb +14 -8
- data/lib/glyph/interpreter.rb +18 -58
- data/lib/glyph/macro.rb +160 -55
- data/lib/glyph/macro_validators.rb +104 -12
- data/lib/glyph/node.rb +24 -0
- data/lib/glyph/parser.rb +278 -0
- data/lib/glyph/syntax_node.rb +225 -0
- data/macros/core.rb +212 -0
- data/macros/filters.rb +66 -15
- data/macros/html/block.rb +43 -105
- data/macros/html/inline.rb +11 -12
- data/macros/html/structure.rb +123 -58
- data/macros/xml.rb +33 -0
- data/spec/files/container.textile +2 -2
- data/spec/files/document.glyph +2 -2
- data/spec/files/document_with_toc.glyph +3 -3
- data/spec/files/included.textile +1 -1
- data/spec/files/ligature.jpg +0 -0
- data/spec/files/markdown.markdown +2 -1
- data/spec/lib/commands_spec.rb +46 -3
- data/spec/lib/document_spec.rb +4 -4
- data/spec/lib/glyph_spec.rb +17 -46
- data/spec/lib/interpreter_spec.rb +6 -25
- data/spec/lib/macro_spec.rb +141 -43
- data/spec/lib/macro_validators_spec.rb +27 -5
- data/spec/lib/node_spec.rb +26 -1
- data/spec/lib/parser_spec.rb +246 -0
- data/spec/lib/syntax_node_spec.rb +111 -0
- data/spec/macros/core_spec.rb +195 -0
- data/spec/macros/filters_spec.rb +38 -4
- data/spec/macros/macros_spec.rb +20 -176
- data/spec/macros/textile_spec.rb +13 -71
- data/spec/macros/xml_spec.rb +77 -0
- data/spec/spec_helper.rb +50 -10
- data/spec/tasks/load_spec.rb +13 -2
- data/styles/default.css +18 -6
- data/styles/pagination.css +1 -19
- data/tasks/generate.rake +2 -2
- data/tasks/load.rake +27 -17
- data/tasks/project.rake +1 -1
- metadata +75 -62
- data/book/script/compile.rb +0 -8
- data/book/script/prof +0 -1
- data/book/script/prof_results.htm +0 -21079
- data/book/text/authoring.glyph +0 -548
- data/book/text/extending.glyph +0 -224
- data/book/text/getting_started.glyph +0 -158
- data/book/text/troubleshooting.glyph +0 -179
- data/lib/glyph/glyph_language.rb +0 -538
- data/lib/glyph/glyph_language.treetop +0 -27
- data/macros/common.rb +0 -160
data/macros/xml.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
macro "|xml|" do
|
4
|
+
begin
|
5
|
+
valid_xml_element
|
6
|
+
max_parameters 1
|
7
|
+
rescue Exception => e
|
8
|
+
if @node[:fallback] then
|
9
|
+
macro_error "Unknown macro '#{@node[:element]}'"
|
10
|
+
else
|
11
|
+
raise
|
12
|
+
end
|
13
|
+
end
|
14
|
+
name = @node[:element]
|
15
|
+
if name.to_s.in? Glyph['language.options.xml_blacklist'] then
|
16
|
+
""
|
17
|
+
else
|
18
|
+
attributes # evaluate attributes
|
19
|
+
xml_attributes = @node.children.select{|node| node.is_a?(Glyph::AttributeNode)}.
|
20
|
+
map do |e|
|
21
|
+
if valid_xml_attribute(e[:name]) then
|
22
|
+
%|#{e[:name]}="#{e[:value]}"|
|
23
|
+
else
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
end.compact.join(" ")
|
27
|
+
xml_attributes = " "+xml_attributes unless xml_attributes.blank?
|
28
|
+
end_first_tag = param(0) ? ">" : ""
|
29
|
+
end_tag = param(0) ? "</#{name}>" : " />"
|
30
|
+
contents = (@node.param(0)&0) && (@node.param(0)&0)[:element] ? "\n#{param(0)}\n" : param(0)
|
31
|
+
%{<#{name}#{xml_attributes}#{end_first_tag}#{contents}#{end_tag}}
|
32
|
+
end
|
33
|
+
end
|
data/spec/files/document.glyph
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
include[container.textile]
|
2
|
+
include[a/b/c/markdown.markdown]
|
@@ -1,3 +1,3 @@
|
|
1
|
-
toc[]
|
2
|
-
|
3
|
-
|
1
|
+
toc[1]
|
2
|
+
include[container.textile]
|
3
|
+
include[a/b/c/markdown.markdown]
|
data/spec/files/included.textile
CHANGED
data/spec/files/ligature.jpg
CHANGED
Binary file
|
data/spec/lib/commands_spec.rb
CHANGED
@@ -9,7 +9,7 @@ describe "glyph" do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
after do
|
12
|
-
|
12
|
+
reset_quiet
|
13
13
|
delete_project
|
14
14
|
end
|
15
15
|
|
@@ -45,6 +45,13 @@ describe "glyph" do
|
|
45
45
|
(Glyph::SPEC_DIR/'.glyphrc').unlink
|
46
46
|
end
|
47
47
|
|
48
|
+
it "[config] should not overwrite system settings" do
|
49
|
+
create_project
|
50
|
+
Glyph['system.test_setting'] = false
|
51
|
+
run_command(["config", "system.test_setting", true]).match(/warning.+\(system use only\)/m).should_not == nil
|
52
|
+
Glyph['system.test_setting'].should == false
|
53
|
+
end
|
54
|
+
|
48
55
|
it "[add] should create a new text file" do
|
49
56
|
create_project
|
50
57
|
run_command_successfully(["add", "test.textile"]).should == true
|
@@ -60,7 +67,7 @@ describe "glyph" do
|
|
60
67
|
it "[compile] should support a custom source file" do
|
61
68
|
create_project
|
62
69
|
file_copy Glyph::PROJECT/'document.glyph', Glyph::PROJECT/'custom.glyph'
|
63
|
-
run_command(["compile", "-s", "custom.glyph"]).match(/custom\.glyph/m).should_not == nil
|
70
|
+
run_command(["-d", "compile", "-s", "custom.glyph"]).match(/custom\.glyph/m).should_not == nil
|
64
71
|
(Glyph::PROJECT/'output/html/test_project.html').exist?.should == true
|
65
72
|
end
|
66
73
|
|
@@ -160,7 +167,7 @@ describe "glyph" do
|
|
160
167
|
|
161
168
|
it "[compile] should finalize the document in case of errors in included files" do
|
162
169
|
create_project
|
163
|
-
file_write Glyph::PROJECT/'document.glyph', "section[
|
170
|
+
file_write Glyph::PROJECT/'document.glyph', "section[@title[Test]\ninclude[errors.glyph]\ninclude[syntax_error.glyph]]"
|
164
171
|
file_write Glyph::PROJECT/'text/errors.glyph', "not[a|b]"
|
165
172
|
file_write Glyph::PROJECT/'text/syntax_error.glyph', "$[a"
|
166
173
|
err = "Document cannot be finalized due to previous errors"
|
@@ -175,4 +182,40 @@ describe "glyph" do
|
|
175
182
|
res.match("error: #{err}").should == nil
|
176
183
|
end
|
177
184
|
|
185
|
+
it "[outline] should display the document outline" do
|
186
|
+
create_project
|
187
|
+
start = %{=====================================
|
188
|
+
test_project - Outline
|
189
|
+
=====================================}
|
190
|
+
c_file = "=== container.textile"
|
191
|
+
i_file = "=== a/b/c/included.textile"
|
192
|
+
m_file = "=== a/b/c/markdown.markdown"
|
193
|
+
c_title = "- Container section "
|
194
|
+
i_title = "- Test Section "
|
195
|
+
m_title = "- Markdown "
|
196
|
+
c_id = "[#h_1]"
|
197
|
+
i_id = "[#h_2]"
|
198
|
+
m_id = "[#md]"
|
199
|
+
file_write Glyph::PROJECT/'document.glyph', "document[#{file_load(Glyph::PROJECT/'document.glyph')}]"
|
200
|
+
run_command(["outline"]).should == %{#{start}
|
201
|
+
#{c_title}
|
202
|
+
#{i_title}
|
203
|
+
#{m_title}
|
204
|
+
}
|
205
|
+
reset_quiet
|
206
|
+
run_command(["outline", "-l", "1"]).should == %{#{start}
|
207
|
+
#{c_title}
|
208
|
+
#{m_title}
|
209
|
+
}
|
210
|
+
reset_quiet
|
211
|
+
run_command(["outline", "-ift"]).should == %{#{start}
|
212
|
+
#{c_file}
|
213
|
+
#{c_title}#{c_id}
|
214
|
+
#{i_file}
|
215
|
+
#{i_title}#{i_id}
|
216
|
+
#{m_file}
|
217
|
+
#{m_title}#{m_id}
|
218
|
+
}
|
219
|
+
end
|
220
|
+
|
178
221
|
end
|
data/spec/lib/document_spec.rb
CHANGED
@@ -7,7 +7,7 @@ describe Glyph::Document do
|
|
7
7
|
|
8
8
|
before do
|
9
9
|
Glyph.macro :test do |node|
|
10
|
-
"Test: #{
|
10
|
+
"Test: #{value}"
|
11
11
|
end
|
12
12
|
create_tree = lambda {|text| }
|
13
13
|
create_doc = lambda {|tree| }
|
@@ -72,7 +72,7 @@ describe Glyph::Document do
|
|
72
72
|
n = placeholder do |document|
|
73
73
|
count = 0
|
74
74
|
document.structure.descend do |node, level|
|
75
|
-
count +=1 if node[:
|
75
|
+
count +=1 if node[:name] == :test
|
76
76
|
end
|
77
77
|
count
|
78
78
|
end
|
@@ -99,10 +99,10 @@ describe Glyph::Document do
|
|
99
99
|
it "should substitute escaped pipes only when finalizing the document" do
|
100
100
|
define_em_macro
|
101
101
|
define_ref_macro
|
102
|
-
text = %{em[ref[link with ref[fake \\| parameter]]]}
|
102
|
+
text = %{em[ref[link with ref[fake \\| parameter|.]|.]]}
|
103
103
|
# Nevermind the absurdity. It's just to test that the escaped pipes
|
104
104
|
# are handled properly.
|
105
|
-
result = %{<em><a href="link with <a href="fake | parameter"
|
105
|
+
result = %{<em><a href="link with <a href="fake | parameter">.</a>">.</a></em>}
|
106
106
|
tree = create_tree text
|
107
107
|
doc = create_doc tree
|
108
108
|
doc.analyze
|
data/spec/lib/glyph_spec.rb
CHANGED
@@ -7,6 +7,10 @@ describe Glyph do
|
|
7
7
|
Glyph.enable 'project:create'
|
8
8
|
end
|
9
9
|
|
10
|
+
after do
|
11
|
+
delete_project
|
12
|
+
end
|
13
|
+
|
10
14
|
it "should initialize a rake app and tasks" do
|
11
15
|
Rake.application.tasks.length.should > 0
|
12
16
|
end
|
@@ -31,66 +35,22 @@ describe Glyph do
|
|
31
35
|
|
32
36
|
it "should support macro aliases" do
|
33
37
|
define_ref_macro
|
38
|
+
define_em_macro
|
34
39
|
lambda { Glyph.macro_alias("->" => :ref)}.should_not raise_error
|
35
40
|
Glyph::MACROS[:"->"].should == Glyph::MACROS[:ref]
|
36
41
|
Glyph.macro_alias :em => :ref
|
37
42
|
Glyph::MACROS[:em].should_not == Glyph::MACROS[:ref]
|
38
43
|
end
|
39
44
|
|
40
|
-
it "should provide a set of default macros and aliases" do
|
41
|
-
delete_project
|
42
|
-
create_project
|
43
|
-
Glyph.run! 'load:macros'
|
44
|
-
macros = [:anchor, :link, :codeph, :fmi, :note, :box, :code, :title, :subtitle,
|
45
|
-
:img, :fig, :author, :pubdate, :table, :td, :tr, :th, :comment, :todo, :snippet, "snippet:",
|
46
|
-
:include, :config, "config:", :ruby, :escape, :textile, :markdown, :div, :header, :document, :body,
|
47
|
-
:head, :style, :toc, :section, :condition, :eq, :and, :or, :not, :match, :highlight, "macro:",
|
48
|
-
:encode, :decode, :draftcomment]
|
49
|
-
aliases = [
|
50
|
-
[[:bookmark, "#"], :anchor],
|
51
|
-
[["=>"], :link],
|
52
|
-
[[:important, :caution, :tip], :note],
|
53
|
-
[["@"], :include],
|
54
|
-
[["&"], :snippet],
|
55
|
-
[["&:"], "snippet:"],
|
56
|
-
[["%:"], "macro:"],
|
57
|
-
[["?"], "condition"],
|
58
|
-
[["$"], :config],
|
59
|
-
[["$:"], "config:"],
|
60
|
-
[["%"], :ruby],
|
61
|
-
[["."], :escape],
|
62
|
-
[["--"], :comment],
|
63
|
-
[[:dc], :draftcomment],
|
64
|
-
[["!"], :todo],
|
65
|
-
[["*"], :encode],
|
66
|
-
[["**"], :decode],
|
67
|
-
[[:md], :markdown],
|
68
|
-
[[:frontcover, :titlepage, :halftitlepage, :frontmatter, :bodymatter, :backmatter, :backcover], :div]]
|
69
|
-
total = 0
|
70
|
-
macros.each { |v| total+=1; Glyph::MACROS[v.to_sym].should_not == nil }
|
71
|
-
check_aliases = lambda do |arr, target|
|
72
|
-
arr.each {|v| total += 1; Glyph::MACROS[v.to_sym].should == Glyph::MACROS[target.to_sym]}
|
73
|
-
end
|
74
|
-
aliases.each { |v| check_aliases.call v[0], v[1] }
|
75
|
-
check_aliases.call Glyph['structure.frontmatter'], :div
|
76
|
-
check_aliases.call Glyph['structure.bodymatter'], :div
|
77
|
-
check_aliases.call Glyph['structure.backmatter'], :div
|
78
|
-
Glyph['structure.frontmatter'].length.should == 8
|
79
|
-
Glyph['structure.bodymatter'].length.should == 4
|
80
|
-
Glyph['structure.backmatter'].length.should == 13
|
81
|
-
#puts Glyph::MACROS.keys.map{|i| i.to_s}.sort.to_yaml
|
82
|
-
total.should == Glyph::MACROS.length
|
83
|
-
end
|
84
|
-
|
85
45
|
it "should provide a filter method to convert raw text into HTML" do
|
86
46
|
Glyph['document.title'] = "Test"
|
87
47
|
Glyph.filter("title[]").gsub(/\n|\t/, '').should == "<h1>Test</h1>"
|
88
48
|
end
|
89
49
|
|
90
50
|
it "should provide a compile method to compile files in lite mode" do
|
51
|
+
reset_quiet
|
91
52
|
file_copy Glyph::PROJECT/'../files/article.glyph', Glyph::PROJECT/'article.glyph'
|
92
53
|
lambda { Glyph.compile Glyph::PROJECT/'article.glyph' }.should_not raise_error
|
93
|
-
reset_quiet
|
94
54
|
(Glyph::PROJECT/'article.html').exist?.should == true
|
95
55
|
end
|
96
56
|
|
@@ -102,4 +62,15 @@ describe Glyph do
|
|
102
62
|
Glyph['test_setting'].should == nil
|
103
63
|
end
|
104
64
|
|
65
|
+
it "should not allow certain macros to be expanded in safe mode" do
|
66
|
+
create_project
|
67
|
+
Glyph.run! "load:all"
|
68
|
+
Glyph.safe_mode = true
|
69
|
+
lambda { output_for("include[test.glyph]")}.should raise_error Glyph::MacroError
|
70
|
+
lambda {output_for("config:[test|true]")}.should raise_error Glyph::MacroError
|
71
|
+
lambda { output_for("ruby[Time.now]")}.should raise_error Glyph::MacroError
|
72
|
+
lambda { output_for("rw:[a|section[{{0}}]]")}.should raise_error Glyph::MacroError
|
73
|
+
Glyph.safe_mode = false
|
74
|
+
end
|
75
|
+
|
105
76
|
end
|
@@ -11,17 +11,16 @@ describe Glyph::Interpreter do
|
|
11
11
|
|
12
12
|
|
13
13
|
after do
|
14
|
+
reset_quiet
|
14
15
|
delete_project
|
15
16
|
end
|
16
17
|
|
17
18
|
it "should process text and run simple macros" do
|
18
19
|
define_em_macro
|
19
20
|
text = "This is a em[test]. It em[should] work."
|
20
|
-
|
21
|
-
@p.document.output.should == "This is a <em>test</em>. It <em>should</em> work."
|
21
|
+
output_for(text).should == "This is a <em>test</em>. It <em>should</em> work."
|
22
22
|
text2 = "This is pointless, but valid: em[]. This em[will] though."
|
23
|
-
|
24
|
-
@p.document.output.should == "This is pointless, but valid: <em></em>. This <em>will</em> though."
|
23
|
+
output_for(text2).should == "This is pointless, but valid: <em></em>. This <em>will</em> though."
|
25
24
|
end
|
26
25
|
|
27
26
|
it "should process and run complex macros" do
|
@@ -62,35 +61,17 @@ describe Glyph::Interpreter do
|
|
62
61
|
it "should store syntax node information in context" do
|
63
62
|
define_em_macro
|
64
63
|
define_ref_macro
|
65
|
-
count = 0
|
66
64
|
Glyph.macro :test_node do |node|
|
67
|
-
node.
|
68
|
-
count+=1
|
69
|
-
end
|
70
|
-
node.parent[:macro]
|
65
|
+
node.parent_macro[:name]
|
71
66
|
end
|
72
67
|
text = %{Test em[test_node[em[test_node[---]]]].}
|
73
68
|
interpret text
|
74
69
|
@p.document.output.should == "Test <em>em</em>."
|
75
|
-
count.should == 8
|
76
70
|
end
|
77
71
|
|
78
|
-
it "should process document.glyph" do
|
79
|
-
interpret file_load(Glyph::PROJECT/'document.glyph')
|
80
|
-
macros = []
|
81
|
-
@p.document.structure.descend do |n, level|
|
82
|
-
macros << {n[:macro] => level} if n[:macro]
|
83
|
-
end
|
84
|
-
macros.should == [{:"@" => 1},{:textile => 2},{:section => 3}, {:header => 4},
|
85
|
-
{:"@" => 4}, {:textile => 5}, {:section => 6}, {:header => 7},
|
86
|
-
{:"@" => 1}, {:markdown => 2},{:section => 3}, {:header => 4}]
|
87
|
-
end
|
88
|
-
|
89
|
-
|
90
72
|
it "should provide diagnostic information on errors" do
|
91
|
-
failure = "
|
92
|
-
|
93
|
-
lambda { interpret "section[em[]" }.should raise_error(Glyph::SyntaxError, failure)
|
73
|
+
failure = "-- [1, 12] Macro 'section' not closed"
|
74
|
+
lambda { interpret("section[em[]").document }.should raise_error(Glyph::SyntaxError, failure)
|
94
75
|
end
|
95
76
|
|
96
77
|
end
|
data/spec/lib/macro_spec.rb
CHANGED
@@ -5,14 +5,16 @@ describe Glyph::Macro do
|
|
5
5
|
|
6
6
|
before do
|
7
7
|
Glyph.macro :test do
|
8
|
-
"Test: #{
|
8
|
+
"Test: #{value}"
|
9
9
|
end
|
10
10
|
create_tree = lambda {|text| }
|
11
11
|
create_doc = lambda {|tree| }
|
12
12
|
@text = "test[section[header[Test!|test]]]"
|
13
13
|
@tree = create_tree @text
|
14
14
|
@doc = create_doc @tree
|
15
|
-
@node = {:
|
15
|
+
@node = Glyph::MacroNode.new.from({:name => :test, :source => {:name => "--"}, :document => @doc})
|
16
|
+
@node << Glyph::ParameterNode.new.from({:name => :"0"})
|
17
|
+
(@node&0) << Glyph::TextNode.new.from({:value => "Testing..."})
|
16
18
|
@macro = Glyph::Macro.new @node
|
17
19
|
end
|
18
20
|
|
@@ -26,10 +28,10 @@ describe Glyph::Macro do
|
|
26
28
|
|
27
29
|
it "should not interpret escaped macros" do
|
28
30
|
Glyph.macro :int_1 do
|
29
|
-
"->#{interpret(
|
31
|
+
"->#{interpret(value)}<-"
|
30
32
|
end
|
31
33
|
Glyph.macro :int_2 do
|
32
|
-
"=>#{interpret(
|
34
|
+
"=>#{interpret(value)}<="
|
33
35
|
end
|
34
36
|
text1 = "int_1[int_2[Test]]"
|
35
37
|
text2 = "int_1[=int_2[Test]=]"
|
@@ -60,49 +62,145 @@ describe Glyph::Macro do
|
|
60
62
|
@doc.placeholders.length.should == 1
|
61
63
|
end
|
62
64
|
|
63
|
-
it "should
|
64
|
-
@macro.
|
65
|
+
it "should expand" do
|
66
|
+
@macro.expand.should == "Test: Testing..."
|
65
67
|
end
|
66
68
|
|
67
|
-
it "should
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
69
|
+
it "should support rewriting" do
|
70
|
+
test = 0
|
71
|
+
Glyph.macro :test do
|
72
|
+
interpret "#{@node.value}-#{test+=1}"
|
73
|
+
end
|
74
|
+
Glyph.macro :release do
|
75
|
+
interpret "Release\n#{@node.value}"
|
76
|
+
end
|
77
|
+
Glyph.macro :features do
|
78
|
+
interpret "\n\ntest[Features: \n#{@node.value}]"
|
79
|
+
end
|
80
|
+
Glyph.macro :feature do
|
81
|
+
interpret "test[#{@node.value}]\n"
|
82
|
+
end
|
83
|
+
text = %{
|
84
|
+
release[
|
85
|
+
features[
|
86
|
+
feature[a]
|
87
|
+
feature[b]
|
88
|
+
feature[c]
|
89
|
+
]
|
90
|
+
]
|
91
|
+
}
|
92
|
+
output_for(text).gsub(/\n|\t/, '').should ==
|
93
|
+
"ReleaseFeatures: a-2b-3c-4-1"
|
94
|
+
test = 0
|
95
|
+
Glyph.macro :test do
|
96
|
+
interpret "#{value}-#{test+=1}"
|
97
|
+
end
|
98
|
+
Glyph.macro :release do
|
99
|
+
interpret "Release\n#{value}"
|
100
|
+
end
|
101
|
+
Glyph.macro :features do
|
102
|
+
interpret "\n\ntest[Features: \n#{value}]"
|
103
|
+
end
|
104
|
+
Glyph.macro :feature do
|
105
|
+
interpret "test[#{value}]\n"
|
106
|
+
end
|
107
|
+
output_for(text).gsub(/\n|\t/, '').should ==
|
108
|
+
"ReleaseFeatures: a-1b-2c-3-4"
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should support access to parameters and attributes" do
|
112
|
+
Glyph.macro :test do
|
113
|
+
"test: #{value}"
|
114
|
+
end
|
115
|
+
Glyph.macro :test1 do
|
116
|
+
"test1: #{value}"
|
117
|
+
end
|
118
|
+
node = Glyph::Parser.new("test[@a[test1[...]]test1[...]|test1[---]]").parse
|
119
|
+
m = Glyph::Macro.new(node&0)
|
120
|
+
m.parameters.should == ["test1: ...", "test1: ---"]
|
121
|
+
m.attributes.should == {:a => "test1: ..."}
|
122
|
+
m.parameter(0).should == "test1: ..."
|
123
|
+
m.parameter(1).should == "test1: ---"
|
124
|
+
m.parameter(2).should == nil
|
125
|
+
m.attribute(:a).should == "test1: ..."
|
126
|
+
m.attribute(:b).should == nil
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should not evaluate attributes unless specifically requested" do
|
130
|
+
define_em_macro
|
131
|
+
node = Glyph::Parser.new("par0[em[...]|em[---]]").parse
|
132
|
+
m = Glyph::Macro.new(node&0)
|
133
|
+
syntaxnode = lambda do |hash|
|
134
|
+
Glyph::SyntaxNode.new.from hash
|
135
|
+
end
|
136
|
+
p0 = p_node 0
|
137
|
+
p0 << macro_node(:em, :escape => false)
|
138
|
+
p00 = p_node 0
|
139
|
+
(p0&0) << p00
|
140
|
+
p00 << text_node("...")
|
141
|
+
p1 = p_node 1
|
142
|
+
p1 << macro_node(:em, :escape => false)
|
143
|
+
p10 = p_node 0
|
144
|
+
(p1&0) << p10
|
145
|
+
p10 << text_node("---")
|
146
|
+
m.node.parameters.should == [p0, p1]
|
147
|
+
m.node.parameters[0][:value].should == nil
|
148
|
+
m.node.parameters[1][:value].should == nil
|
149
|
+
m.parameter(0).should == "<em>...</em>"
|
150
|
+
m.node.parameters[0][:value].should == "<em>...</em>"
|
151
|
+
m.node.parameters[1][:value].should == nil
|
73
152
|
end
|
74
153
|
|
75
|
-
it "should
|
76
|
-
|
77
|
-
Glyph.
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
154
|
+
it "should not evaluate parameters unless specifically requested" do
|
155
|
+
define_em_macro
|
156
|
+
node = Glyph::Parser.new("par0[@a[em[...]]@b[em[---]]]").parse
|
157
|
+
m = Glyph::Macro.new(node&0)
|
158
|
+
syntaxnode = lambda do |hash|
|
159
|
+
Glyph::SyntaxNode.new.from hash
|
160
|
+
end
|
161
|
+
p0 = a_node :a, :escape => false
|
162
|
+
p0 << macro_node(:em, :escape => false)
|
163
|
+
p00 = p_node 0
|
164
|
+
(p0&0) << p00
|
165
|
+
p00 << text_node("...")
|
166
|
+
p1 = a_node :b, :escape => false
|
167
|
+
p1 << macro_node(:em, :escape => false)
|
168
|
+
p10 = p_node 0
|
169
|
+
(p1&0) << p10
|
170
|
+
p10 << text_node("---")
|
171
|
+
m.node.attributes.should == [p0, p1]
|
172
|
+
m.node.attribute(:a)[:value].should == nil
|
173
|
+
m.node.attribute(:b)[:value].should == nil
|
174
|
+
m.attribute(:a).should == "<em>...</em>"
|
175
|
+
m.node.attribute(:a)[:value].should == "<em>...</em>"
|
176
|
+
m.node.attribute(:b)[:value].should == nil
|
177
|
+
end
|
178
|
+
|
179
|
+
it "should expose a path method to determine its location" do
|
180
|
+
tree = Glyph::Parser.new(%{
|
181
|
+
test1[
|
182
|
+
a[...]|
|
183
|
+
b[
|
184
|
+
test2[@a[x[]]]
|
185
|
+
]
|
186
|
+
]}).parse
|
187
|
+
node = tree&1&1&1&0&1&0&0
|
188
|
+
m = Glyph::Macro.new(node)
|
189
|
+
m.path.should == "test1/1/b/test2/@a/x"
|
190
|
+
end
|
191
|
+
|
192
|
+
it "should substitute bracket escapes properly" do
|
193
|
+
define_em_macro
|
194
|
+
Glyph.macro :test_int do
|
195
|
+
interpret "- #{value} -"
|
196
|
+
end
|
197
|
+
text1 = %{em[test\\\\\.\\[...\\\\\.\\]]} # test\\\.\[\\\.\]
|
198
|
+
text2 = %{em[=test\\\\\\.[...\\\\\\.]=]} # test\\\.[\\\.]
|
199
|
+
text3 = %{test_int[em[=test\\\\\.[...\\\\\.]=]]}
|
200
|
+
out = "<em>test\\[...\\]</em>"
|
201
|
+
output_for(text1).should == out
|
202
|
+
output_for(text2).should == out
|
203
|
+
output_for(text3).should == "- #{out} -"
|
106
204
|
end
|
107
205
|
|
108
206
|
end
|