glyph 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS.textile +8 -0
- data/CHANGELOG.textile +260 -0
- data/LICENSE.textile +26 -0
- data/README.textile +49 -21
- data/Rakefile +17 -7
- data/VERSION +1 -1
- data/book/config.yml +11 -5
- data/book/document.glyph +24 -13
- data/book/lib/macros/reference.rb +41 -14
- data/book/output/html/glyph.html +2298 -687
- data/book/output/pdf/glyph.pdf +6218 -2698
- data/book/script/authors +1 -0
- data/book/script/changelog +1 -0
- data/book/script/compile.rb +8 -0
- data/book/script/license +1 -0
- data/book/script/prof +1 -0
- data/book/script/prof_results.htm +21079 -0
- data/book/script/readme +1 -0
- data/book/snippets.yml +3 -4
- data/book/text/acknowledgement.glyph +8 -0
- data/book/text/authoring.glyph +548 -0
- data/book/text/changelog.glyph +76 -0
- data/book/text/extending.glyph +224 -0
- data/book/text/{getting_started.textile → getting_started.glyph} +30 -24
- data/book/text/{introduction.textile → introduction.glyph} +22 -12
- data/book/text/license.glyph +21 -0
- data/book/text/{ref_commands.textile → ref_commands.glyph} +30 -8
- data/book/text/ref_config.glyph +108 -0
- data/book/text/ref_macros.glyph +378 -0
- data/book/text/troubleshooting.glyph +179 -0
- data/config.yml +16 -4
- data/glyph.gemspec +83 -22
- data/lib/glyph.rb +164 -31
- data/lib/glyph/commands.rb +98 -23
- data/lib/glyph/document.rb +13 -7
- data/lib/glyph/glyph_language.rb +9 -1
- data/lib/glyph/glyph_language.treetop +1 -1
- data/lib/glyph/interpreter.rb +19 -9
- data/lib/glyph/macro.rb +88 -11
- data/lib/glyph/macro_validators.rb +48 -0
- data/lib/glyph/node.rb +13 -1
- data/lib/glyph/system_extensions.rb +0 -28
- data/macros/common.rb +125 -31
- data/macros/filters.rb +19 -13
- data/macros/html/block.rb +119 -68
- data/macros/html/inline.rb +29 -3
- data/macros/html/structure.rb +40 -40
- data/spec/files/article.glyph +5 -0
- data/spec/lib/commands_spec.rb +98 -3
- data/spec/lib/document_spec.rb +15 -2
- data/spec/lib/glyph_spec.rb +39 -10
- data/spec/lib/interpreter_spec.rb +8 -2
- data/spec/lib/macro_spec.rb +54 -6
- data/spec/lib/macro_validators_spec.rb +33 -0
- data/spec/lib/node_spec.rb +11 -3
- data/spec/macros/filters_spec.rb +5 -5
- data/spec/macros/macros_spec.rb +185 -8
- data/spec/macros/textile_spec.rb +217 -0
- data/spec/spec_helper.rb +25 -15
- data/spec/tasks/generate_spec.rb +3 -3
- data/spec/tasks/load_spec.rb +11 -1
- data/spec/tasks/project_spec.rb +0 -3
- data/styles/coderay.css +121 -0
- data/styles/default.css +54 -20
- data/{book/styles/css3.css → styles/pagination.css} +35 -7
- data/styles/ultraviolet/active4d.css +114 -0
- data/styles/ultraviolet/all_hallows_eve.css +72 -0
- data/styles/ultraviolet/amy.css +147 -0
- data/styles/ultraviolet/blackboard.css +88 -0
- data/styles/ultraviolet/brilliance_black.css +605 -0
- data/styles/ultraviolet/brilliance_dull.css +599 -0
- data/styles/ultraviolet/cobalt.css +149 -0
- data/styles/ultraviolet/dawn.css +121 -0
- data/styles/ultraviolet/eiffel.css +121 -0
- data/styles/ultraviolet/espresso_libre.css +109 -0
- data/styles/ultraviolet/idle.css +62 -0
- data/styles/ultraviolet/iplastic.css +80 -0
- data/styles/ultraviolet/lazy.css +73 -0
- data/styles/ultraviolet/mac_classic.css +123 -0
- data/styles/ultraviolet/magicwb_amiga.css +104 -0
- data/styles/ultraviolet/pastels_on_dark.css +188 -0
- data/styles/ultraviolet/slush_poppies.css +85 -0
- data/styles/ultraviolet/spacecadet.css +51 -0
- data/styles/ultraviolet/sunburst.css +180 -0
- data/styles/ultraviolet/twilight.css +137 -0
- data/styles/ultraviolet/zenburnesque.css +91 -0
- data/tasks/generate.rake +45 -26
- data/tasks/load.rake +21 -18
- data/tasks/project.rake +3 -1
- metadata +210 -41
- data/book/styles/default.css +0 -190
- data/book/text/authoring.textile +0 -351
- data/book/text/extending.textile +0 -148
- data/book/text/ref_config.textile +0 -0
- data/book/text/ref_macros.textile +0 -256
- data/book/text/troubleshooting.textile +0 -118
- data/styles/css3.css +0 -220
data/lib/glyph/commands.rb
CHANGED
@@ -21,24 +21,92 @@ command :add do |c|
|
|
21
21
|
end
|
22
22
|
|
23
23
|
GLI.desc 'Compile the project'
|
24
|
-
arg_name "[
|
24
|
+
arg_name "[source_file]"
|
25
|
+
arg_name "[destination_file]"
|
25
26
|
command :compile do |c|
|
26
27
|
c.desc "Specify a glyph file to compile (default: document.glyph)"
|
27
28
|
c.flag [:s, :source]
|
28
29
|
c.desc "Specify the format of the output file (default: html)"
|
29
30
|
c.flag [:f, :format]
|
31
|
+
c.desc "Auto-regenerate output on file changes"
|
32
|
+
c.switch :auto
|
30
33
|
c.action do |global_options, options, args|
|
31
|
-
|
34
|
+
raise ArgumentError, "Too many arguments" if args.length > 2
|
35
|
+
Glyph.lite_mode = true unless args.blank?
|
36
|
+
Glyph.run! 'load:config'
|
37
|
+
original_config = Glyph::CONFIG.dup
|
32
38
|
output_targets = Glyph::CONFIG.get('document.output_targets')
|
33
39
|
target = nil
|
34
|
-
Glyph
|
35
|
-
target =
|
40
|
+
Glyph['document.output'] = options[:f] if options[:f]
|
41
|
+
target = Glyph['document.output']
|
36
42
|
target = nil if target.blank?
|
37
|
-
target ||=
|
38
|
-
Glyph
|
43
|
+
target ||= Glyph['filters.target']
|
44
|
+
Glyph['document.source'] = options[:s] if options[:s]
|
39
45
|
raise ArgumentError, "Output target not specified" unless target
|
40
46
|
raise ArgumentError, "Unknown output target '#{target}'" unless output_targets.include? target.to_sym
|
41
|
-
|
47
|
+
|
48
|
+
# Lite mode
|
49
|
+
if Glyph.lite? then
|
50
|
+
source_file = Pathname.new args[0]
|
51
|
+
filename = source_file.basename(source_file.extname).to_s
|
52
|
+
destination_file = Pathname.new(args[1]) rescue nil
|
53
|
+
src_extension = Regexp.escape(source_file.extname)
|
54
|
+
dst_extension = ".#{Glyph['document.output']}"
|
55
|
+
destination_file ||= Pathname.new(source_file.to_s.gsub(/#{src_extension}$/, dst_extension))
|
56
|
+
raise ArgumentError, "Source file '#{source_file}' does not exist" unless source_file.exist?
|
57
|
+
raise ArgumentError, "Source and destination file are the same" if source_file.to_s == destination_file.to_s
|
58
|
+
Glyph['document.filename'] = filename
|
59
|
+
Glyph['document.source'] = source_file.to_s
|
60
|
+
Glyph['document.output_dir'] = destination_file.parent.to_s # System use only
|
61
|
+
Glyph['document.output_file'] = destination_file.basename.to_s # System use only
|
62
|
+
end
|
63
|
+
begin
|
64
|
+
Glyph.run "generate:#{target}"
|
65
|
+
rescue Exception => e
|
66
|
+
message = e.message
|
67
|
+
if Glyph.debug? then
|
68
|
+
message << "\n"+"-"*20+"[ Backtrace: ]"+"-"*20
|
69
|
+
message << "\n"+e.backtrace.join("\n")
|
70
|
+
message << "\n"+"-"*54
|
71
|
+
end
|
72
|
+
raise RuntimeError, message if Glyph.library?
|
73
|
+
Glyph.error message
|
74
|
+
end
|
75
|
+
|
76
|
+
# Auto-regeneration
|
77
|
+
if options[:auto] && !Glyph.lite? then
|
78
|
+
Glyph.lite_mode = false
|
79
|
+
begin
|
80
|
+
require 'directory_watcher'
|
81
|
+
rescue LoadError
|
82
|
+
raise RuntimeError, "DirectoryWatcher is not available. Install it with: gem install directory_watcher"
|
83
|
+
end
|
84
|
+
Glyph.info 'Auto-regeneration enabled'
|
85
|
+
Glyph.info 'Use ^C to interrupt'
|
86
|
+
glob = ['*.glyph', 'config.yml', 'images/**/*', 'lib/**/*', 'snippets.yml', 'styles/**/*', 'text/**/*']
|
87
|
+
dw = DirectoryWatcher.new(Glyph::PROJECT, :glob => glob, :interval => 1, :pre_load => true)
|
88
|
+
dw.add_observer do |*args|
|
89
|
+
puts "="*50
|
90
|
+
Glyph.info "Regeneration started: #{args.size} files changed"
|
91
|
+
Glyph.reset
|
92
|
+
begin
|
93
|
+
Glyph.run! "generate:#{target}"
|
94
|
+
rescue Exception => e
|
95
|
+
Glyph.error e.message
|
96
|
+
if Glyph.debug? then
|
97
|
+
puts "-"*20+"[ Backtrace: ]"+"-"*20
|
98
|
+
puts e.backtrace
|
99
|
+
pits "-"*54
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
dw.start
|
104
|
+
begin
|
105
|
+
sleep
|
106
|
+
rescue Interrupt
|
107
|
+
end
|
108
|
+
dw.stop
|
109
|
+
end
|
42
110
|
end
|
43
111
|
end
|
44
112
|
|
@@ -46,13 +114,13 @@ GLI.desc 'Display all project TODO items'
|
|
46
114
|
command :todo do |c|
|
47
115
|
c.action do |global_options, options, args|
|
48
116
|
Glyph.run "generate:document"
|
49
|
-
unless Glyph
|
50
|
-
info "*** TODOs: ***"
|
51
|
-
Glyph
|
52
|
-
info t
|
117
|
+
unless Glyph.document.todos.blank?
|
118
|
+
Glyph.info "*** TODOs: ***"
|
119
|
+
Glyph.document.todos.each do |t|
|
120
|
+
Glyph.info t
|
53
121
|
end
|
54
122
|
else
|
55
|
-
info "Nothing left to do."
|
123
|
+
Glyph.info "Nothing left to do."
|
56
124
|
end
|
57
125
|
end
|
58
126
|
end
|
@@ -65,20 +133,27 @@ command :config do |c|
|
|
65
133
|
c.action do |global_options,options,args|
|
66
134
|
Glyph.run 'load:config'
|
67
135
|
if options[:g] then
|
68
|
-
|
136
|
+
config = Glyph::GLOBAL_CONFIG
|
69
137
|
else
|
70
|
-
|
138
|
+
config = Glyph::PROJECT_CONFIG
|
71
139
|
end
|
72
140
|
case args.length
|
73
141
|
when 0 then
|
74
142
|
raise ArgumentError, "Too few arguments."
|
75
143
|
when 1 then # read current config
|
76
|
-
setting =
|
144
|
+
setting = Glyph[args[0]]
|
77
145
|
raise RuntimeError, "Unknown setting '#{args[0]}'" if setting.blank?
|
78
|
-
info
|
146
|
+
Glyph.info setting
|
79
147
|
when 2 then
|
80
|
-
|
81
|
-
Glyph.
|
148
|
+
# Remove all overrides
|
149
|
+
Glyph.config_reset
|
150
|
+
# Reload current project config
|
151
|
+
config.read
|
152
|
+
config.set args[0], args[1]
|
153
|
+
# Write changes to file
|
154
|
+
config.write
|
155
|
+
# Refresh configuration
|
156
|
+
Glyph.config_refresh
|
82
157
|
else
|
83
158
|
raise ArgumentError, "Too many arguments."
|
84
159
|
end
|
@@ -90,7 +165,7 @@ pre do |global,command,options,args|
|
|
90
165
|
# Return true to proceed; false to abourt and not call the
|
91
166
|
# chosen command
|
92
167
|
if global[:d] then
|
93
|
-
Glyph
|
168
|
+
Glyph.debug_mode = true
|
94
169
|
end
|
95
170
|
if !command || command.name == :help then
|
96
171
|
puts "====================================="
|
@@ -105,17 +180,17 @@ post do |global,command,options,args|
|
|
105
180
|
end
|
106
181
|
|
107
182
|
on_error do |exception|
|
108
|
-
if exception.is_a? MacroError then
|
109
|
-
|
110
|
-
puts exception.message
|
183
|
+
if exception.is_a? Glyph::MacroError then
|
184
|
+
Glyph.warning exception.message
|
111
185
|
false
|
112
186
|
else
|
113
|
-
if Glyph.
|
187
|
+
if Glyph.debug? then
|
114
188
|
puts "Exception: #{exception.message}"
|
115
189
|
puts "Backtrace:"
|
116
190
|
exception.backtrace.each do |b|
|
117
191
|
puts b
|
118
192
|
end
|
193
|
+
Glyph.debug_mode = false
|
119
194
|
end
|
120
195
|
true
|
121
196
|
end
|
data/lib/glyph/document.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Glyph
|
2
4
|
|
3
5
|
# The Glyph::Document class stores information about a document or a chunk of text
|
@@ -16,19 +18,20 @@ module Glyph
|
|
16
18
|
['\\|', '|']
|
17
19
|
]
|
18
20
|
|
19
|
-
attr_reader :bookmarks, :placeholders, :headers, :context
|
21
|
+
attr_reader :bookmarks, :placeholders, :headers, :context, :errors, :todos
|
20
22
|
|
21
23
|
# Creates a new document
|
22
24
|
# @param [GlyphSyntaxNode] tree the syntax tree to be evaluate
|
23
25
|
# @param [Glyph::Node] context the context associated with the tree
|
24
26
|
# @raise [RuntimeError] unless tree responds to :evaluate
|
25
27
|
def initialize(tree, context)
|
26
|
-
raise RuntimeError, "Document contains syntax errors." unless tree.respond_to? :evaluate
|
27
28
|
@tree = tree
|
28
29
|
@context = context
|
29
30
|
@bookmarks = {}
|
30
31
|
@placeholders = {}
|
31
32
|
@headers = []
|
33
|
+
@errors = []
|
34
|
+
@todos = []
|
32
35
|
@state = :new
|
33
36
|
end
|
34
37
|
|
@@ -40,11 +43,12 @@ module Glyph
|
|
40
43
|
@tree.data
|
41
44
|
end
|
42
45
|
|
43
|
-
# Copies bookmarks, headers and placeholders from another Glyph::Document
|
46
|
+
# Copies bookmarks, headers, todos and placeholders from another Glyph::Document
|
44
47
|
# @param [Glyph::Document] document a valid Glyph::Document
|
45
48
|
def inherit_from(document)
|
46
49
|
@bookmarks = document.bookmarks
|
47
50
|
@headers = document.headers
|
51
|
+
@todos = document.todos
|
48
52
|
@placeholders = document.placeholders
|
49
53
|
end
|
50
54
|
|
@@ -101,18 +105,20 @@ module Glyph
|
|
101
105
|
|
102
106
|
# Finalizes the document by evaluating its @placeholders
|
103
107
|
# @return [:finalized]
|
104
|
-
# @raise [RuntimeError]
|
105
|
-
# if it is already finalized
|
108
|
+
# @raise [RuntimeError] if the document the document has not been analyzed,
|
109
|
+
# if it is already finalized or if errors occurred during analysis
|
106
110
|
def finalize
|
107
111
|
raise RuntimeError, "Document has not been analyzed" unless analyzed?
|
108
112
|
raise RuntimeError, "Document has already been finalized" if finalized?
|
109
|
-
return (@state = :finalized) if @context[:
|
113
|
+
return (@state = :finalized) if @context[:embedded]
|
114
|
+
raise RuntimeError, "Document cannot be finalized due to previous errors" unless @context[:document].errors.blank?
|
115
|
+
# Substitute placeholders
|
110
116
|
ESCAPES.each{|e| @output.gsub! e[0], e[1]}
|
111
117
|
@placeholders.each_pair do |key, value|
|
112
118
|
begin
|
113
119
|
@output.gsub! key.to_s, value.call(self).to_s
|
114
120
|
rescue Exception => e
|
115
|
-
warning e.message
|
121
|
+
Glyph.warning e.message
|
116
122
|
end
|
117
123
|
end
|
118
124
|
@state = :finalized
|
data/lib/glyph/glyph_language.rb
CHANGED
@@ -49,6 +49,7 @@ module GlyphLanguage
|
|
49
49
|
r0
|
50
50
|
end
|
51
51
|
|
52
|
+
# @private
|
52
53
|
module EscapingMacro0
|
53
54
|
def macro_name
|
54
55
|
elements[0]
|
@@ -96,7 +97,7 @@ module GlyphLanguage
|
|
96
97
|
end
|
97
98
|
end
|
98
99
|
if s0.last
|
99
|
-
r0 = instantiate_node(
|
100
|
+
r0 = instantiate_node(EscapingMacroNode,input, i0...index, s0)
|
100
101
|
r0.extend(EscapingMacro0)
|
101
102
|
else
|
102
103
|
@index = i0
|
@@ -108,6 +109,7 @@ module GlyphLanguage
|
|
108
109
|
r0
|
109
110
|
end
|
110
111
|
|
112
|
+
# @private
|
111
113
|
module Macro0
|
112
114
|
def macro_name
|
113
115
|
elements[0]
|
@@ -167,9 +169,11 @@ module GlyphLanguage
|
|
167
169
|
r0
|
168
170
|
end
|
169
171
|
|
172
|
+
# @private
|
170
173
|
module EscapedText0
|
171
174
|
end
|
172
175
|
|
176
|
+
# @private
|
173
177
|
module EscapedText1
|
174
178
|
def macro_name
|
175
179
|
elements[0]
|
@@ -177,6 +181,7 @@ module GlyphLanguage
|
|
177
181
|
|
178
182
|
end
|
179
183
|
|
184
|
+
# @private
|
180
185
|
module EscapedText2
|
181
186
|
end
|
182
187
|
|
@@ -345,9 +350,11 @@ module GlyphLanguage
|
|
345
350
|
r0
|
346
351
|
end
|
347
352
|
|
353
|
+
# @private
|
348
354
|
module Text0
|
349
355
|
end
|
350
356
|
|
357
|
+
# @private
|
351
358
|
module Text1
|
352
359
|
def macro_name
|
353
360
|
elements[0]
|
@@ -355,6 +362,7 @@ module GlyphLanguage
|
|
355
362
|
|
356
363
|
end
|
357
364
|
|
365
|
+
# @private
|
358
366
|
module Text2
|
359
367
|
end
|
360
368
|
|
data/lib/glyph/interpreter.rb
CHANGED
@@ -6,27 +6,29 @@ class GlyphSyntaxNode < Treetop::Runtime::SyntaxNode
|
|
6
6
|
def evaluate(context, current=nil)
|
7
7
|
current ||= context.to_node
|
8
8
|
@data ||= current.to_node
|
9
|
-
|
10
|
-
value
|
9
|
+
elements.map { |e| e.evaluate(context, current) if e.respond_to? :evaluate }.join
|
11
10
|
end
|
12
11
|
|
13
|
-
end
|
12
|
+
end
|
14
13
|
|
15
14
|
# @private
|
16
15
|
class MacroNode < GlyphSyntaxNode
|
17
16
|
|
18
|
-
def evaluate(context, current
|
17
|
+
def evaluate(context, current)
|
19
18
|
name = macro_name.text_value.to_sym
|
20
|
-
raise
|
19
|
+
raise Glyph::SyntaxError, "Undefined macro '#{name}'\n -> source: #{current[:source]}" unless Glyph::MACROS.include? name
|
21
20
|
@data = {:macro => name, :source => context[:source], :document => context[:document]}.to_node
|
21
|
+
@data[:escape] = true if is_a? EscapingMacroNode
|
22
22
|
current << @data
|
23
|
-
value = super(context, @data).strip
|
24
|
-
@data[:value] = value
|
23
|
+
@data[:value] = super(context, @data).strip
|
25
24
|
Glyph::Macro.new(@data).execute
|
26
25
|
end
|
27
26
|
|
28
27
|
end
|
29
28
|
|
29
|
+
# @private
|
30
|
+
class EscapingMacroNode < MacroNode; end
|
31
|
+
|
30
32
|
# @private
|
31
33
|
class TextNode < GlyphSyntaxNode
|
32
34
|
|
@@ -45,14 +47,22 @@ module Glyph
|
|
45
47
|
# * Analyzes and finalizes the document
|
46
48
|
class Interpreter
|
47
49
|
|
50
|
+
PARSER = GlyphLanguageParser.new
|
51
|
+
|
48
52
|
# Creates a new Glyph::Interpreter object.
|
49
53
|
# @param [String] text the string to interpret
|
50
54
|
# @param [Hash] context the context to pass along when evaluating macros
|
51
55
|
def initialize(text, context=nil)
|
52
56
|
context ||= {:source => '--'}
|
53
|
-
@
|
54
|
-
@raw = @parser.parse text
|
57
|
+
@raw = PARSER.parse text
|
55
58
|
@context = context
|
59
|
+
tf = PARSER.terminal_failures
|
60
|
+
if !@raw.respond_to?(:evaluate) then
|
61
|
+
reason = "Incorrect macro syntax"
|
62
|
+
err = "#{reason}\n -> #{@context[:source]} [Line #{PARSER.failure_line}, Column #{PARSER.failure_column}]"
|
63
|
+
@context[:document].errors << err if @context[:document] && !@context[:embedded]
|
64
|
+
raise Glyph::SyntaxError, err
|
65
|
+
end
|
56
66
|
@document = Glyph::Document.new @raw, @context
|
57
67
|
@document.inherit_from @context[:document] if @context[:document]
|
58
68
|
end
|
data/lib/glyph/macro.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Glyph
|
2
4
|
|
3
5
|
# A Macro object is instantiated by a Glyph::Interpreter whenever a macro is found in the parsed text.
|
@@ -5,6 +7,8 @@ module Glyph
|
|
5
7
|
# useful methods to be used in macro definitions.
|
6
8
|
class Macro
|
7
9
|
|
10
|
+
include Validators
|
11
|
+
|
8
12
|
# Creates a new macro instance from a Node
|
9
13
|
# @param [Node] node a node populated with macro data
|
10
14
|
def initialize(node)
|
@@ -12,26 +16,97 @@ module Glyph
|
|
12
16
|
@name = @node[:macro]
|
13
17
|
@value = @node[:value]
|
14
18
|
@source = @node[:source]
|
15
|
-
|
16
|
-
|
19
|
+
@escaped_pipe = '‡‡‡‡‡ESCAPED¤PIPE‡‡‡‡‡'
|
20
|
+
end
|
21
|
+
|
22
|
+
# Parses the macro parameters (stripping values)
|
23
|
+
# @return [Array] the macro parameters
|
24
|
+
def params
|
25
|
+
return @params if @params
|
26
|
+
@params = @value.gsub(/\\\|/, @escaped_pipe).split('|').map{|p| p.strip.gsub @escaped_pipe, "\\|"}
|
27
|
+
end
|
28
|
+
|
29
|
+
# Parses the macro parameters (without stripping values)
|
30
|
+
# @return [Array] the macro parameters
|
31
|
+
def raw_params
|
32
|
+
return @raw_params if @raw_params
|
33
|
+
@params = @value.gsub(/\\\|/, @escaped_pipe).split('|').map{|p| p.gsub @escaped_pipe, "\\|"}
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns the "path" to the macro within the syntax tree.
|
37
|
+
# @return [String] the macro path
|
38
|
+
def path
|
39
|
+
macros = []
|
40
|
+
@node.ascend {|n| macros << n[:macro].to_s if n[:macro] }
|
41
|
+
macros.reverse.join('/')
|
42
|
+
end
|
43
|
+
|
44
|
+
# Returns a todo message to include in the document in case of errors.
|
45
|
+
# @param [String] message the message to include in the document
|
46
|
+
# @return [String] the resulting todo message
|
47
|
+
def macro_todo(message)
|
48
|
+
draft = Glyph['document.draft']
|
49
|
+
Glyph['document.draft'] = true unless draft
|
50
|
+
res = interpret "![#{message}]"
|
51
|
+
Glyph['document.draft'] = false unless draft
|
52
|
+
res
|
53
|
+
end
|
54
|
+
|
55
|
+
# Raises a macro error (preventing document post-processing)
|
56
|
+
# @param [String] msg the message to print
|
57
|
+
# @raise [Glyph::MacroError]
|
58
|
+
def macro_error(msg, klass=Glyph::MacroError)
|
59
|
+
src = @node[:source_name]
|
60
|
+
src ||= @node[:source]
|
61
|
+
src ||= "--"
|
62
|
+
message = "#{msg}\n -> source: #{src}\n -> path: #{path}"
|
63
|
+
@node[:document].errors << message
|
64
|
+
message += "\n -> value:\n#{"-"*54}\n#{@value}\n#{"-"*54}" if Glyph.debug?
|
65
|
+
raise klass, message
|
17
66
|
end
|
18
67
|
|
19
68
|
# Raises a macro error
|
20
69
|
# @param [String] msg the message to print
|
21
|
-
# @raise [MacroError]
|
22
|
-
def
|
23
|
-
|
70
|
+
# @raise [Glyph::MacroError]
|
71
|
+
def macro_warning(message)
|
72
|
+
src = @node[:source_name]
|
73
|
+
src ||= @node[:source]
|
74
|
+
src ||= "--"
|
75
|
+
Glyph.warning "#{message}\n -> source: #{src}\n -> path: #{path}"
|
76
|
+
message += %{\n -> value:\n#{"-"*54}\n#{@value}\n#{"-"*54}} if Glyph.debug?
|
24
77
|
end
|
25
78
|
|
26
79
|
# Instantiates a Glyph::Interpreter and interprets a string
|
27
80
|
# @param [String] string the string to interpret
|
28
81
|
# @return [String] the interpreted output
|
29
|
-
# @raise [MacroError] in case of mutual macro inclusion (snippet, include macros)
|
82
|
+
# @raise [Glyph::MacroError] in case of mutual macro inclusion (snippet, include macros)
|
30
83
|
def interpret(string)
|
31
|
-
@node[:source] = "
|
32
|
-
@node[:
|
33
|
-
macro_error "Mutual inclusion" if @node.find_parent {|n| n[:source] == @node[:source] }
|
34
|
-
|
84
|
+
@node[:source] = "#@name[#@value]"
|
85
|
+
@node[:source_name] = "#{@name}[...]"
|
86
|
+
macro_error "Mutual inclusion", Glyph::MutualInclusionError if @node.find_parent {|n| n[:source] == @node[:source] }
|
87
|
+
if @node[:escape] then
|
88
|
+
result = string
|
89
|
+
else
|
90
|
+
@node[:embedded] = true
|
91
|
+
result = Glyph::Interpreter.new(string, @node).document.output
|
92
|
+
end
|
93
|
+
result.gsub(/\\*([\[\]])/){"\\#$1"}
|
94
|
+
end
|
95
|
+
|
96
|
+
# Encodes all macros in a string so that it can be encoded
|
97
|
+
# (and interpreted) later on
|
98
|
+
# @param [String] string the string to encode
|
99
|
+
# @return [String] the encoded string
|
100
|
+
def encode(string)
|
101
|
+
string.gsub(/([\[\]\|])/) { "‡‡¤#{$1.bytes.to_a[0]}¤‡‡" }
|
102
|
+
end
|
103
|
+
|
104
|
+
# Decodes a previously encoded string
|
105
|
+
# so that it can be interpreted
|
106
|
+
# @param [String] string the string to decode
|
107
|
+
# @return [String] the decoded string
|
108
|
+
def decode(string)
|
109
|
+
string.gsub(/‡‡¤(91|93|124)¤‡‡/) { $1.to_i.chr }
|
35
110
|
end
|
36
111
|
|
37
112
|
# @see Glyph::Document#placeholder
|
@@ -61,7 +136,9 @@ module Glyph
|
|
61
136
|
|
62
137
|
# Executes a macro definition in the context of self
|
63
138
|
def execute
|
64
|
-
instance_exec(@node, &Glyph::MACROS[@name]).to_s
|
139
|
+
res = instance_exec(@node, &Glyph::MACROS[@name]).to_s
|
140
|
+
res.gsub!(/\\*([\[\]\|])/){"\\#$1"}
|
141
|
+
res
|
65
142
|
end
|
66
143
|
|
67
144
|
end
|