glyph 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. data/README.textile +80 -0
  2. data/Rakefile +51 -0
  3. data/VERSION +1 -0
  4. data/bin/glyph +7 -0
  5. data/book/config.yml +5 -0
  6. data/book/document.glyph +55 -0
  7. data/book/images/glyph.png +0 -0
  8. data/book/images/glyph.svg +351 -0
  9. data/book/lib/macros/reference.rb +98 -0
  10. data/book/output/html/glyph.html +1809 -0
  11. data/book/output/html/images/glyph.png +0 -0
  12. data/book/output/html/images/glyph.svg +351 -0
  13. data/book/output/pdf/glyph.pdf +4277 -0
  14. data/book/snippets.yml +13 -0
  15. data/book/styles/css3.css +220 -0
  16. data/book/styles/default.css +190 -0
  17. data/book/text/authoring.textile +351 -0
  18. data/book/text/extending.textile +148 -0
  19. data/book/text/getting_started.textile +152 -0
  20. data/book/text/introduction.textile +88 -0
  21. data/book/text/ref_commands.textile +74 -0
  22. data/book/text/ref_config.textile +0 -0
  23. data/book/text/ref_macros.textile +256 -0
  24. data/book/text/troubleshooting.textile +118 -0
  25. data/config.yml +63 -0
  26. data/document.glyph +29 -0
  27. data/glyph.gemspec +138 -0
  28. data/lib/glyph.rb +128 -0
  29. data/lib/glyph/commands.rb +124 -0
  30. data/lib/glyph/config.rb +152 -0
  31. data/lib/glyph/document.rb +145 -0
  32. data/lib/glyph/glyph_language.rb +530 -0
  33. data/lib/glyph/glyph_language.treetop +27 -0
  34. data/lib/glyph/interpreter.rb +84 -0
  35. data/lib/glyph/macro.rb +69 -0
  36. data/lib/glyph/node.rb +126 -0
  37. data/lib/glyph/system_extensions.rb +77 -0
  38. data/macros/common.rb +66 -0
  39. data/macros/filters.rb +69 -0
  40. data/macros/html/block.rb +119 -0
  41. data/macros/html/inline.rb +43 -0
  42. data/macros/html/structure.rb +138 -0
  43. data/spec/files/container.textile +5 -0
  44. data/spec/files/document.glyph +2 -0
  45. data/spec/files/document_with_toc.glyph +3 -0
  46. data/spec/files/included.textile +4 -0
  47. data/spec/files/ligature.jpg +449 -0
  48. data/spec/files/markdown.markdown +8 -0
  49. data/spec/files/test.sass +2 -0
  50. data/spec/lib/commands_spec.rb +83 -0
  51. data/spec/lib/config_spec.rb +79 -0
  52. data/spec/lib/document_spec.rb +100 -0
  53. data/spec/lib/glyph_spec.rb +76 -0
  54. data/spec/lib/interpreter_spec.rb +90 -0
  55. data/spec/lib/macro_spec.rb +60 -0
  56. data/spec/lib/node_spec.rb +76 -0
  57. data/spec/macros/filters_spec.rb +42 -0
  58. data/spec/macros/macros_spec.rb +159 -0
  59. data/spec/spec_helper.rb +92 -0
  60. data/spec/tasks/generate_spec.rb +31 -0
  61. data/spec/tasks/load_spec.rb +37 -0
  62. data/spec/tasks/project_spec.rb +41 -0
  63. data/styles/css3.css +220 -0
  64. data/styles/default.css +190 -0
  65. data/tasks/generate.rake +57 -0
  66. data/tasks/load.rake +55 -0
  67. data/tasks/project.rake +33 -0
  68. metadata +192 -0
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env ruby
2
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
3
+
4
+ describe Glyph::Macro do
5
+
6
+ before do
7
+ Glyph.macro :test do |node|
8
+ "Test: #{node[:value]}"
9
+ end
10
+ create_tree = lambda {|text| }
11
+ create_doc = lambda {|tree| }
12
+ @text = "test[section[header[Test!|test]]]"
13
+ @tree = create_tree @text
14
+ @doc = create_doc @tree
15
+ @node = {:macro => :test, :value => "Testing...", :source => "--", :document => @doc}.to_node
16
+ @macro = Glyph::Macro.new @node
17
+ end
18
+
19
+ it "should raise macro errors" do
20
+ lambda { @macro.macro_error "Error!" }.should raise_error(MacroError)
21
+
22
+ end
23
+
24
+ it "should interpret strings" do
25
+ @macro.interpret("test[--]").should == "Test: --"
26
+ end
27
+
28
+ it "should store and check bookmarks" do
29
+ h = { :id => "test2", :title => "Test 2" }
30
+ @macro.bookmark h
31
+ @doc.bookmark?(:test2).should == h
32
+ @macro.bookmark?(:test2).should == h
33
+ end
34
+
35
+ it "should store and check headers" do
36
+ h = { :level => 2, :id => "test3", :title => "Test 3" }
37
+ @macro.header h
38
+ @doc.header?("test3").should == h
39
+ @macro.header?("test3").should == h
40
+ end
41
+
42
+ it "should store placeholders" do
43
+ @macro.placeholder { |document| }
44
+ @doc.placeholders.length.should == 1
45
+ end
46
+
47
+ it "should execute" do
48
+ @macro.execute.should == "Test: Testing..."
49
+ end
50
+
51
+ it "should detect mutual inclusion" do
52
+ delete_project
53
+ create_project
54
+ Glyph.run! 'load:macros'
55
+ Glyph::SNIPPETS[:inc] = "Test &[inc]"
56
+ @macro.interpret("&[inc] test").should == "Test [SNIPPET 'inc' NOT PROCESSED] test"
57
+ end
58
+
59
+ end
60
+
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env ruby
2
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
3
+
4
+ describe Node do
5
+
6
+ def create_node
7
+ @ht = {:a => 1, :b => 2}.to_node
8
+ end
9
+
10
+ it "should be a hash" do
11
+ ht = Node.new
12
+ ht.is_a?(Hash).should == true
13
+ ht.children.should == []
14
+ end
15
+
16
+ it "should be generated from a hash" do
17
+ create_node
18
+ @ht.respond_to?(:children).should == true
19
+ end
20
+
21
+ it "should support child elements" do
22
+ create_node
23
+ lambda { @ht << "wrong" }.should raise_error
24
+ lambda { @ht << {:c => 3, :d => 4} }.should_not raise_error
25
+ @ht.children[0][:c].should == 3
26
+ lambda { @ht << {:e => 5, :f => 6}.to_node }.should_not raise_error
27
+ @ht.child(1) << {:g => 7, :h => 8}
28
+ @ht.child(1) << {:i => 9, :j => 10}
29
+ ((@ht>>1>>1)[:j]).should == 10
30
+ end
31
+
32
+ it "should support iteration" do
33
+ create_node
34
+ @ht << {:c => 3, :d => 4}
35
+ @ht << {:e => 5, :f => 6}
36
+ @ht.child(0) << {:g => 7, :h => 8}
37
+ sum = 0
38
+ @ht.each_child do |c|
39
+ c.values.each { |v| sum+=v}
40
+ end
41
+ sum.should == 18
42
+ level = 0
43
+ str = ""
44
+ @ht.descend do |c, l|
45
+ level = l
46
+ c.values.sort.each { |v| str+=v.to_s}
47
+ end
48
+ str.should == "12347856"
49
+ level.should == 1
50
+ end
51
+
52
+ it "should store information about parent nodes" do
53
+ create_node
54
+ @ht << {:c => 3, :d => 4}
55
+ @ht << {:e => 5, :f => 6}
56
+ @ht.child(1) << {:g => 7, :h => 8}
57
+ @ht.child(1).child(0) << {:i => 9, :j => 10}
58
+ (@ht>>1>>0>>0).parent.should == @ht>>1>>(0)
59
+ (@ht>>1>>0>>0).root.should == @ht
60
+ end
61
+
62
+ it "should find child nodes" do
63
+ create_node
64
+ @ht << {:c => 3, :d => 4}
65
+ @ht << {:e => 5, :f => 6}
66
+ result = @ht.find_child do |node|
67
+ node[:d] == 4
68
+ end
69
+ result.should == {:c => 3, :d => 4}
70
+ result2 = @ht.find_child do |node|
71
+ node[:q] == 7
72
+ end
73
+ result2.should == nil
74
+ end
75
+
76
+ end
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env ruby
2
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
3
+
4
+ describe "Filter Macros" do
5
+
6
+ before do
7
+ delete_project
8
+ create_project
9
+ Glyph.run! 'load:macros'
10
+ end
11
+
12
+ after do
13
+ delete_project
14
+ end
15
+
16
+ it "should filter textile input" do
17
+ text = "textile[This is a _TEST_(TM).]"
18
+ interpret text
19
+ @p.document.output.should == "<p>This is a <em><span class=\"caps\">TEST</span></em>&#8482;.</p>"
20
+ run_command ["config", "filters.target", :latex]
21
+ interpret text
22
+ @p.document.output.should == "This is a \\emph{TEST}\\texttrademark{}.\n\n"
23
+ run_command ["config", "filters.target", ":html"]
24
+ run_command ["config", "filters.redcloth.restrictions", "[:no_span_caps]"]
25
+ interpret text
26
+ @p.document.output.should == "<p>This is a <em>TEST</em>&#8482;.</p>"
27
+ end
28
+
29
+ it "should filter markdown input" do
30
+ text = "markdown[This is a test:
31
+
32
+ - item 1
33
+ - item 2
34
+ - item 3
35
+
36
+ ...]"
37
+ interpret text
38
+ @p.document.output.gsub(/\n|\t/, '').should ==
39
+ "<p>This is a test:</p><ul><li>item 1</li><li>item 2</li><li>item 3</li></ul><p>...</p>"
40
+ end
41
+
42
+ end
@@ -0,0 +1,159 @@
1
+ #!/usr/bin/env ruby
2
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
3
+
4
+ describe "Macro:" do
5
+
6
+ before do
7
+ create_project
8
+ Glyph.run! 'load:macros'
9
+ Glyph.run! 'load:snippets'
10
+ end
11
+
12
+ after do
13
+ delete_project
14
+ end
15
+
16
+ it "anchor" do
17
+ interpret "this is a #[test|test]."
18
+ doc = @p.document
19
+ doc.output.should == "this is a <a id=\"test\">test</a>."
20
+ doc.bookmarks.has_key?(:test).should == true
21
+ lambda { interpret "this is a #[test|test]. #[test|This won't work!]"; @p.document }.should raise_error(MacroError)
22
+ end
23
+
24
+ it "snippet" do
25
+ define_em_macro
26
+ interpret "Testing a snippet: &[test]."
27
+ @p.document.output.should == "Testing a snippet: This is a \nTest snippet."
28
+ interpret("Testing &[wrong].")
29
+ @p.document.output.should == "Testing [SNIPPET 'wrong' NOT PROCESSED]."
30
+ Glyph::SNIPPETS[:a] = "this is a em[test] &[b]"
31
+ Glyph::SNIPPETS[:b] = "and another em[test]"
32
+ text = "TEST: &[a]"
33
+ interpret text
34
+ @p.document.output.should == "TEST: this is a <em>test</em> and another <em>test</em>"
35
+ # Check snippets with links
36
+ Glyph::SNIPPETS[:c] = "This is a link to something afterwards: =>[#other]"
37
+ text = "Test. &[c]. #[other|Test]."
38
+ interpret text
39
+ @p.document.output.should == %{Test. This is a link to something afterwards: <a href="#other">Test</a>. <a id="other">Test</a>.}
40
+ end
41
+
42
+ it "section, chapter, header" do
43
+ text = "chapter[header[Chapter X] ... section[header[Section Y|sec-y] ... section[header[Another section] ...]]]"
44
+ interpret text
45
+ doc = @p.document
46
+ doc.output.gsub(/\n|\t/, '').should == %{<div class="chapter">
47
+ <h2 id="h_1">Chapter X</h2> ...
48
+ <div class="section">
49
+ <h3 id="sec-y">Section Y</h3> ...
50
+ <div class="section">
51
+ <h4 id="h_3">Another section</h4> ...
52
+ </div>
53
+ </div>
54
+ </div>
55
+ }.gsub(/\n|\t/, '')
56
+ doc.bookmark?(:"sec-y").should == {:id => :"sec-y", :title => "Section Y"}
57
+ end
58
+
59
+ it "include" do
60
+ Glyph.config_override "filters.by_extension", true
61
+ text = file_load(Glyph::PROJECT/'text/container.textile')
62
+ interpret text
63
+ @p.document.output.gsub(/\n|\t|_\d{1,3}/, '').should == %{
64
+ <div class="section">
65
+ <h2 id="h_1">Container section</h2>
66
+ This is a test.
67
+ <div class="section">
68
+ <h3 id="h_2">Test Section</h3>
69
+ <p>&#8230;</p>
70
+ </div>
71
+ </div>
72
+ }.gsub(/\n|\t|_\d{1,3}/, '')
73
+ end
74
+
75
+
76
+ it "style" do
77
+ interpret "style[test.sass]"
78
+ @p.document.output.gsub(/\n|\t/, '').should == "<style type=\"text/css\">#main { background-color: #0000ff; }</style>"
79
+ end
80
+
81
+ it "escape" do
82
+ define_em_macro
83
+ text = %{This is a test em[This can .[=contain test[macros em[test]]=]]}
84
+ interpret text
85
+ @p.document.output.should == %{This is a test <em>This can contain test[macros em[test]]</em>}
86
+ end
87
+
88
+ it "ruby" do
89
+ interpret "2 + 2 = %[2+2]"
90
+ @p.document.output.should == %{2 + 2 = 4}
91
+ end
92
+
93
+ it "config" do
94
+ Glyph.config_override "test.setting", "TEST"
95
+ interpret "test.setting = $[test.setting]"
96
+ @p.document.output.should == %{test.setting = TEST}
97
+ end
98
+
99
+ it "toc" do
100
+ file_copy Glyph::PROJECT/'../files/document_with_toc.glyph', Glyph::PROJECT/'document.glyph'
101
+ interpret file_load(Glyph::PROJECT/'document.glyph')
102
+ doc = @p.document
103
+ doc.output.gsub!(/\n|\t/, '')
104
+ doc.output.slice(/(.+?<\/div>)/, 1).should == %{
105
+ <div class="contents">
106
+ <h2 class="toc-header" id="h_toc">Table of Contents</h2>
107
+ <ol class="toc">
108
+ <li class=" section"><a href="#h_1">Container section</a></li>
109
+ <li><ol>
110
+ <li class=" section"><a href="#h_2">Test Section</a></li>
111
+ </ol></li>
112
+ <li class=" section"><a href="#md">Markdown</a></li>
113
+ </ol>
114
+ </div>
115
+ }.gsub(/\n|\t/, '')
116
+ end
117
+
118
+ it "link" do
119
+ text = %{
120
+ link[#test_id]
121
+ link[#test_id2]
122
+ #[test_id|Test #1]
123
+ #[test_id2|Test #2]
124
+ }
125
+ interpret text
126
+ @p.document.output.gsub(/\n|\t/, '').should == %{
127
+ <a href="#test_id">Test #1</a>
128
+ <a href="#test_id2">Test #2</a>
129
+ <a id="test_id">Test #1</a>
130
+ <a id="test_id2">Test #2</a>
131
+ }.gsub(/\n|\t/, '')
132
+ end
133
+
134
+ it "fmi" do
135
+ interpret "fmi[this topic|#test] #[test|Test]"
136
+ @p.document.output.should == %{<span class="fmi">
137
+ for more information on this topic,
138
+ see <a href="#test">Test</a></span> <a id="test">Test</a>}.gsub(/\n|\t/, '')
139
+ end
140
+
141
+ it "img" do
142
+ interpret "img[ligature.jpg|90%|90%]"
143
+ @p.document.output.gsub(/\t|\n/, '').should == %{
144
+ <img src="images/ligature.jpg"
145
+ width="90%" height="90%" alt="-"/>
146
+ }.gsub(/\n|\t/, '')
147
+ end
148
+
149
+ it "fig" do
150
+ interpret "fig[ligature.jpg|Ligature]"
151
+ @p.document.output.gsub(/\t|\n/, '').should == %{
152
+ <div class="figure">
153
+ <img src="images/ligature.jpg" alt="-"/>
154
+ <div class="caption">Ligature</div>
155
+ </div>
156
+ }.gsub(/\n|\t/, '')
157
+ end
158
+
159
+ end
@@ -0,0 +1,92 @@
1
+ #!/usr/bin/env ruby
2
+ $: << File.expand_path(File.dirname(__FILE__) + '/../lib')
3
+
4
+ require "stringio"
5
+
6
+ module Glyph; end
7
+
8
+ begin
9
+ unless Glyph.const_defined? :TEST_MODE then
10
+ Glyph::TEST_MODE = true
11
+ end
12
+ rescue Exception => e
13
+ end
14
+
15
+ require "glyph"
16
+
17
+ Glyph.config_override :quiet, true
18
+
19
+ def create_project_dir
20
+ Glyph::PROJECT.mkpath
21
+ end
22
+
23
+ def create_project
24
+ enable_all_tasks
25
+ create_project_dir
26
+ Glyph.run! 'project:create', Glyph::PROJECT.to_s
27
+ file_copy Glyph::SPEC_DIR/'files/container.textile', Glyph::PROJECT/'text/container.textile'
28
+ (Glyph::PROJECT/'text/a/b/c').mkpath
29
+ file_copy Glyph::SPEC_DIR/'files/included.textile', Glyph::PROJECT/'text/a//b/c/included.textile'
30
+ file_copy Glyph::SPEC_DIR/'files/markdown.markdown', Glyph::PROJECT/'text/a//b/c/markdown.markdown'
31
+ file_copy Glyph::SPEC_DIR/'files/document.glyph', Glyph::PROJECT/'document.glyph'
32
+ file_copy Glyph::SPEC_DIR/'files/test.sass', Glyph::PROJECT/'styles/test.sass'
33
+ file_copy Glyph::SPEC_DIR/'files/ligature.jpg', Glyph::PROJECT/'images/ligature.jpg'
34
+ end
35
+
36
+ def enable_all_tasks
37
+ Rake::Task.tasks.each {|t| t.reenable }
38
+ end
39
+
40
+ def delete_project_dir
41
+ FileUtils.rm_rf Glyph::PROJECT.to_s
42
+ end
43
+
44
+ def delete_project
45
+ delete_project_dir
46
+ Glyph::SNIPPETS.clear
47
+ Glyph::MACROS.clear
48
+ Glyph.config_override 'document.source', 'document.glyph'
49
+ Glyph.instance_eval { remove_const :DOCUMENT rescue nil }
50
+ end
51
+
52
+ def run_command(cmd)
53
+ out = StringIO.new
54
+ old_stdout = $stdout
55
+ old_stderr = $stderr
56
+ $stdout = out
57
+ $stderr = out
58
+ Glyph.config_override :quiet, false
59
+ GLI.run cmd
60
+ Glyph.config_override :quiet, true
61
+ $stdout = old_stdout
62
+ $stderr = old_stderr
63
+ out.string
64
+ end
65
+
66
+ def run_command_successfully(cmd)
67
+ run_command(cmd).match(/error/) == nil
68
+ end
69
+
70
+ def define_em_macro
71
+ Glyph.macro :em do
72
+ %{<em>#{@value}</em>}
73
+ end
74
+ end
75
+
76
+ def define_ref_macro
77
+ Glyph.macro :ref do
78
+ %{<a href="#{@params[0]}">#{@params[1]}</a>}
79
+ end
80
+ end
81
+
82
+ def interpret(text)
83
+ @p = Glyph::Interpreter.new(text)
84
+ end
85
+
86
+ def create_tree(text)
87
+ GlyphLanguageParser.new.parse text
88
+ end
89
+
90
+ def create_doc(tree)
91
+ Glyph::Document.new tree, {}
92
+ end
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
3
+
4
+ describe "generate" do
5
+
6
+ before do
7
+ create_project
8
+ end
9
+
10
+ after do
11
+ delete_project
12
+ end
13
+
14
+ it ":document should generate Glyph::DOCUMENT" do
15
+ lambda { Glyph.run! 'generate:document'}.should_not raise_error
16
+ Glyph::DOCUMENT.structure.children.length.should > 0
17
+ end
18
+
19
+ it ":html should generate a standalone html document" do
20
+ lambda { Glyph.run! 'generate:html'}.should_not raise_error
21
+ (Glyph::PROJECT/'output/html/test_project.html').exist?.should == true
22
+ end
23
+
24
+ it "should copy images" do
25
+ dir = (Glyph::PROJECT/'images/test').mkpath
26
+ file_copy Glyph::HOME/'spec/files/ligature.jpg', Glyph::PROJECT/'images/test'
27
+ lambda { Glyph.run! 'generate:html' }.should_not raise_error
28
+ (Glyph::PROJECT/'output/html/images/test/ligature.jpg').exist?.should == true
29
+ end
30
+
31
+ end