glyph 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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