glyph 0.2.0 → 0.3.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/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
|