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,8 @@
1
+ section[
2
+ header[Markdown|md]
3
+ This contains markdown text.
4
+
5
+ - item 1
6
+ - item 2
7
+ - item 3
8
+ ]
@@ -0,0 +1,2 @@
1
+ #main
2
+ background-color: #0000ff
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env ruby
2
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
3
+ require 'glyph/commands'
4
+
5
+ describe "glyph" do
6
+
7
+ before do
8
+ create_project_dir
9
+ end
10
+
11
+ after do
12
+ delete_project
13
+ end
14
+
15
+ it "[init] should create a project in the current directory" do
16
+ Glyph.enable "project:create"
17
+ run_command_successfully(['init']).should == false
18
+ Dir.chdir Glyph::PROJECT.to_s
19
+ run_command_successfully(['init']).should == true
20
+ end
21
+
22
+ it "[config] should read configuration settings" do
23
+ create_project
24
+ run_command_successfully(["config", "-g"]).should == false
25
+ run_command(["config", "filters.target"]).match(/html/m).should_not == nil
26
+ end
27
+
28
+ it "[config] should write configuration settings" do
29
+ create_project
30
+ run_command_successfully(["config", "test_setting", true]).should == true
31
+ Glyph::CONFIG.get(:test_setting).should == true
32
+ Glyph::PROJECT_CONFIG.get('test_setting').should == true
33
+ Glyph::GLOBAL_CONFIG.get('test_setting').should_not == true
34
+ run_command_successfully(["config", "-g", "another.test", "something else"]).should == true
35
+ Glyph::CONFIG.get("another.test").should == "something else"
36
+ Glyph::PROJECT_CONFIG.get('another.test').should_not == "something else"
37
+ Glyph::GLOBAL_CONFIG.get('another.test').should == "something else"
38
+ run_command_successfully(["config", "-g", "yet.another.test", "something else", "extra argument"]).should == false
39
+ end
40
+
41
+ it "[add] should create a new text file" do
42
+ create_project
43
+ run_command_successfully(["add", "test.textile"]).should == true
44
+ (Glyph::PROJECT/'text/test.textile').exist?.should == true
45
+ end
46
+
47
+ it "[compile] should compile the project" do
48
+ create_project
49
+ run_command(["compile"]).match(/test_project\.html/m).should_not == nil
50
+ (Glyph::PROJECT/'output/html/test_project.html').exist?.should == true
51
+ end
52
+
53
+ it "[compile] should support a custom source file" do
54
+ create_project
55
+ file_copy Glyph::PROJECT/'document.glyph', Glyph::PROJECT/'custom.glyph'
56
+ run_command(["compile", "-s", "custom.glyph"]).match(/custom\.glyph/m).should_not == nil
57
+ (Glyph::PROJECT/'output/html/test_project.html').exist?.should == true
58
+ end
59
+
60
+ it "[compile] should continue execution in case of macro errors" do
61
+ create_project
62
+ text = %{
63
+ =>[#invalid1]
64
+ =>[#invalid2]
65
+ =>[#valid]
66
+ &[test]
67
+ &[invalid3]
68
+ #[valid|Valid bookmark]
69
+ }
70
+ file_write Glyph::PROJECT/'document.glyph', text
71
+ res = run_command(['-d', "compile"])
72
+ res.match(/Bookmark 'invalid1' does not exist/).should_not == nil
73
+ res.match(/Bookmark 'invalid2' does not exist/).should_not == nil
74
+ res.match(/Bookmark 'valid' does not exist/).should == nil
75
+ res.match(/Snippet 'invalid3' does not exist/).should_not == nil
76
+ end
77
+
78
+ it "[compile] should not compile the project in case of an unknown output format" do
79
+ run_command_successfully(["compile", "-f", "wrong"]).should == false
80
+ end
81
+
82
+
83
+ end
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env ruby
2
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
3
+
4
+ describe Glyph::Config do
5
+
6
+ before do
7
+ @valid = {:test => true}.to_yaml
8
+ @invalid = [1,2,3].to_yaml
9
+ @config_path = Glyph::SPEC_DIR/'config.yml'
10
+ @write_config_file = lambda do |contents|
11
+ File.open(@config_path, "w+") { |f| f.write(contents) }
12
+ end
13
+ @cfg = Glyph::Config.new :file => @config_path
14
+ end
15
+
16
+ after(:all) do
17
+ @config_path.delete
18
+ end
19
+
20
+ it "should load a YAML configuration file" do
21
+ @write_config_file.call @invalid
22
+ lambda { @cfg.read }.should raise_error
23
+ @write_config_file.call @valid
24
+ @cfg.read.should == {:test => true}
25
+ end
26
+
27
+ it "should get and set configuration data through dot notation" do
28
+ @write_config_file.call @valid
29
+ @cfg.read
30
+ lambda { @cfg.set :test, false }.should_not raise_error
31
+ lambda { @cfg.set "test.wrong", true}.should raise_error
32
+ lambda { @cfg.set "test2.value", true}.should_not raise_error
33
+ @cfg.get("test2.value").should == true
34
+ lambda { @cfg.set "test2.value", "false"}.should_not raise_error
35
+ @cfg.get("test2.value").should == false
36
+ @cfg.get("test2.value2").should == nil
37
+ @cfg.to_hash.should == {:test => false, :test2 => {:value => false}}
38
+ end
39
+
40
+ it "can be resetted with a Hash, if resettable" do
41
+ lambda { @cfg.reset }.should raise_error
42
+ cfg2 = Glyph::Config.new :resettable => true
43
+ cfg2.reset :test => "reset!"
44
+ cfg2.to_hash.should == {:test => "reset!"}
45
+ end
46
+
47
+ it "should be set to an empty Hash by default" do
48
+ cfg2 = Glyph::Config.new
49
+ cfg2.to_hash.should == {}
50
+ end
51
+
52
+ it "should write a YAML configuration file" do
53
+ @write_config_file.call @valid
54
+ @cfg.read
55
+ @cfg.set :test1, 1
56
+ @cfg.set :test2, 2
57
+ @cfg.set :test3, 3
58
+ @cfg.write
59
+ cfg2 = Glyph::Config.new :file => @config_path
60
+ cfg2.read
61
+ cfg2.to_hash.should == @cfg.to_hash
62
+ end
63
+
64
+ it "should merge with another Config without data loss" do
65
+ hash1 = {:a =>1, :b => {:b1 => 1, :b2 => 2, :b3 => {:b11 => 1, :b12 =>2}, :b4 => 4}, :c => 3}
66
+ hash2 = {:a =>1, :b => {:b1 => 1111, :b2 => 2222, :b3 => {:b12 =>2222}}}
67
+ @write_config_file.call hash1.to_yaml
68
+ @cfg.read
69
+ @write_config_file.call hash2.to_yaml
70
+ cfg2 = Glyph::Config.new :file => @config_path
71
+ @cfg.update cfg2
72
+ updated = {:a =>1, :b => {:b1 => 1111, :b2 => 2222, :b3 => {:b11 => 1, :b12 =>2222}, :b4 => 4}, :c=> 3}
73
+ @cfg.to_hash.should == updated
74
+ hash1.merge! hash2
75
+ hash1.should == {:a =>1, :b => {:b1 => 1111, :b2 => 2222, :b3 => {:b12 =>2222}}, :c=> 3}
76
+ end
77
+
78
+
79
+ end
@@ -0,0 +1,100 @@
1
+ #!/usr/bin/env ruby
2
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
3
+
4
+ describe Glyph::Document 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
+ @tree = create_tree "test[test[test[Test\\|\\]...]]]"
13
+ @doc = create_doc @tree
14
+
15
+ end
16
+
17
+ it "should expose document data" do
18
+ @doc.bookmarks.should == {}
19
+ @doc.placeholders.should == {}
20
+ @doc.new?.should == true
21
+ end
22
+
23
+ it "should store bookmarks" do
24
+ lambda { @doc.bookmark(:id => "test", :title => "Test Bookmark #1")}.should_not raise_error
25
+ lambda { @doc.bookmark(:id => :test, :title => "Test Bookmark #2")}.should_not raise_error
26
+ @doc.bookmarks.length.should == 1
27
+ @doc.bookmarks[:test].should == {:id => :test, :title => "Test Bookmark #2"}
28
+ end
29
+
30
+ it "should store placeholders" do
31
+ p = lambda { "test" }
32
+ lambda { @doc.placeholder &p }.should_not raise_error
33
+ @doc.placeholders["‡‡‡‡‡PLACEHOLDER¤1‡‡‡‡‡".to_sym].should == p
34
+ end
35
+
36
+ it "can inherit data from another document" do
37
+ @doc.bookmark :id => :test1, :title => "Test #1"
38
+ @doc.bookmark :id => :test2, :title => "Test #2"
39
+ @doc.placeholder { "test" }
40
+ @doc.header :id => :test3, :title => "Test #3", :level => 3
41
+ doc2 = create_doc @tree
42
+ doc2.bookmarks.length.should == 0
43
+ doc2.placeholders.length.should == 0
44
+ doc2.bookmark :id => :test4, :title => "Test #4"
45
+ doc2.inherit_from @doc
46
+ doc2.bookmarks.length.should == 2
47
+ doc2.placeholders.length.should == 1
48
+ doc2.headers.length.should == 1
49
+ doc2.bookmarks[:test3].should == nil
50
+ end
51
+
52
+ it "should analyze the syntax tree and finalize the document" do
53
+ lambda { @doc.output }.should raise_error
54
+ lambda { @doc.finalize }.should raise_error
55
+ lambda { @doc.analyze }.should_not raise_error
56
+ lambda { @doc.analyze }.should raise_error
57
+ @doc.analyzed?.should == true
58
+ lambda { @doc.output }.should raise_error
59
+ lambda { @doc.finalize }.should_not raise_error
60
+ @doc.output.should == "Test: Test: Test: Test|]..."
61
+ end
62
+
63
+ it "should expose document structure" do
64
+ lambda { @doc.structure }.should raise_error
65
+ @doc.analyze
66
+ @doc.structure.is_a?(Node).should == true
67
+ end
68
+
69
+ it "should substitute placeholders when finalizing" do
70
+ Glyph.macro :count_tests do
71
+ n = placeholder do |document|
72
+ count = 0
73
+ document.structure.descend do |node, level|
74
+ count +=1 if node[:macro] == :test
75
+ end
76
+ count
77
+ end
78
+ n
79
+ end
80
+ text = %{
81
+ Total: count_tests[] tests.
82
+ test[
83
+ test[
84
+ test[
85
+ test
86
+ ]
87
+ ]
88
+ test[test]
89
+ ]
90
+ }
91
+ tree = create_tree text
92
+ doc = create_doc tree
93
+ doc.analyze
94
+ doc.finalize
95
+ doc.output.gsub(/\n|\t/, '')[0..14].should == "Total: 4 tests."
96
+ end
97
+
98
+
99
+ end
100
+
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env ruby
2
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
3
+
4
+ describe Glyph do
5
+
6
+ before do
7
+ Glyph.enable 'project:create'
8
+ end
9
+
10
+ it "should initialize a rake app and tasks" do
11
+ Glyph::APP.tasks.length.should > 0
12
+ end
13
+
14
+ it "should run rake tasks" do
15
+ delete_project_dir
16
+ create_project_dir
17
+ Glyph.run 'project:create', Glyph::PROJECT
18
+ lambda { Glyph.run! 'project:create', Glyph::PROJECT }.should raise_error
19
+ delete_project_dir
20
+ create_project_dir
21
+ lambda { Glyph.run! 'project:create', Glyph::PROJECT }.should_not raise_error
22
+ delete_project_dir
23
+ end
24
+
25
+ it "should define macros" do
26
+ lambda { define_em_macro }.should_not raise_error
27
+ lambda { define_ref_macro }.should_not raise_error
28
+ Glyph::MACROS.include?(:em).should == true
29
+ Glyph::MACROS.include?(:ref).should == true
30
+ end
31
+
32
+ it "should support macro aliases" do
33
+ define_ref_macro
34
+ lambda { Glyph.macro_alias("->" => :ref)}.should_not raise_error
35
+ Glyph::MACROS[:"->"].should == Glyph::MACROS[:ref]
36
+ Glyph.macro_alias :em => :ref
37
+ Glyph::MACROS[:em].should_not == Glyph::MACROS[:ref]
38
+ end
39
+
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,
46
+ :include, :config, :ruby, :escape, :textile, :markdown, :div, :header, :document, :body,
47
+ :head, :style, :toc, :section]
48
+ aliases = [
49
+ [[:bookmark, "#"], :anchor],
50
+ [["=>"], :link],
51
+ [[:important, :caution, :tip], :note],
52
+ [["@"], :include],
53
+ [["&"], :snippet],
54
+ [["$"], :config],
55
+ [["%"], :ruby],
56
+ [["."], :escape],
57
+ [["--"], :comment],
58
+ [[:md], :markdown],
59
+ [[:frontcover, :titlepage, :halftitlepage, :frontmatter, :bodymatter, :backmatter, :backcover], :div]]
60
+ total = 0
61
+ macros.each { |v| total+=1; Glyph::MACROS[v.to_sym].should_not == nil }
62
+ check_aliases = lambda do |arr, target|
63
+ arr.each {|v| total += 1; Glyph::MACROS[v.to_sym].should == Glyph::MACROS[target.to_sym]}
64
+ end
65
+ aliases.each { |v| check_aliases.call v[0], v[1] }
66
+ check_aliases.call cfg('structure.frontmatter'), :div
67
+ check_aliases.call cfg('structure.bodymatter'), :div
68
+ check_aliases.call cfg('structure.backmatter'), :div
69
+ cfg('structure.frontmatter').length.should == 8
70
+ cfg('structure.bodymatter').length.should == 4
71
+ cfg('structure.backmatter').length.should == 13
72
+ #puts Glyph::MACROS.keys.map{|i| i.to_s}.sort.to_yaml
73
+ total.should == Glyph::MACROS.length
74
+ end
75
+
76
+ end
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/env ruby
2
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
3
+
4
+ describe Glyph::Interpreter do
5
+
6
+ before do
7
+ delete_project
8
+ create_project
9
+ Glyph.run! 'load:macros'
10
+ Glyph.run! 'load:snippets'
11
+ end
12
+
13
+
14
+ after do
15
+ delete_project
16
+ end
17
+
18
+ it "should process text and run simple macros" do
19
+ define_em_macro
20
+ text = "This is a em[test]. It em[should] work."
21
+ interpret text
22
+ @p.document.output.should == "This is a <em>test</em>. It <em>should</em> work."
23
+ text2 = "This is pointless, but valid: em[]. This em[will] though."
24
+ interpret text2
25
+ @p.document.output.should == "This is pointless, but valid: <em></em>. This <em>will</em> though."
26
+ end
27
+
28
+ it "should process and run complex macros" do
29
+ define_ref_macro
30
+ text = "This is a ref[http://www.h3rald.com|test]."
31
+ interpret text
32
+ @p.document.output.should == "This is a <a href=\"http://www.h3rald.com\">test</a>."
33
+ end
34
+
35
+ it "should support multiline macros" do
36
+ define_ref_macro
37
+ text = %{This is a test containing a ref[
38
+ http://www.h3rald.com
39
+ |
40
+ multiline
41
+
42
+ ] macro.}
43
+ interpret text
44
+ @p.document.output.should == %{This is a test containing a <a href="http://www.h3rald.com">multiline</a> macro.}
45
+ end
46
+
47
+ it "should support escape characters" do
48
+ define_em_macro
49
+ text = %{This text contains em[
50
+ some escaped em\\[content\\]... etc.].}
51
+ interpret text
52
+ @p.document.output.should == %{This text contains <em>some escaped em[content]... etc.</em>.}
53
+ end
54
+
55
+ it "should support nested macros" do
56
+ define_em_macro
57
+ define_ref_macro
58
+ text = %{This is an ref[#test|em[emphasized] link]}
59
+ interpret text
60
+ @p.document.output.should == %{This is an <a href="#test"><em>emphasized</em> link</a>}
61
+ end
62
+
63
+ it "should store syntax node information in context" do
64
+ define_em_macro
65
+ define_ref_macro
66
+ count = 0
67
+ Glyph.macro :test_node do |node|
68
+ node.ascend do |n|
69
+ count+=1
70
+ end
71
+ node.parent[:macro]
72
+ end
73
+ text = %{Test em[test_node[em[test_node[---]]]].}
74
+ interpret text
75
+ @p.document.output.should == "Test <em>em</em>."
76
+ count.should == 8
77
+ end
78
+
79
+ it "should process document.glyph" do
80
+ interpret file_load(Glyph::PROJECT/'document.glyph')
81
+ macros = []
82
+ @p.document.structure.descend do |n, level|
83
+ macros << {n[:macro] => level} if n[:macro]
84
+ end
85
+ macros.should == [{:"@" => 1},{:textile => 2},{:section => 3}, {:header => 4},
86
+ {:"@" => 4}, {:textile => 5}, {:section => 6}, {:header => 7},
87
+ {:"@" => 1}, {:markdown => 2},{:section => 3}, {:header => 4}]
88
+ end
89
+
90
+ end