glyph 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (162) hide show
  1. data/.gitignore +7 -0
  2. data/AUTHORS.textile +8 -7
  3. data/CHANGELOG.textile +89 -8
  4. data/LICENSE.textile +1 -2
  5. data/README.textile +89 -61
  6. data/Rakefile +12 -10
  7. data/VERSION +1 -1
  8. data/benchmark.rb +1 -1
  9. data/book/config.yml +18 -4
  10. data/book/document.glyph +269 -45
  11. data/book/images/glyph/commands_tasks.png +0 -0
  12. data/book/images/{document_generation.png → glyph/document_generation.png} +0 -0
  13. data/book/images/glyph/glyph.eps +123 -0
  14. data/book/images/glyph/glyph.png +0 -0
  15. data/book/images/glyph/glyph.svg +29 -0
  16. data/book/lib/commands/commands.rb +11 -0
  17. data/book/lib/layouts/bookindex.glyph +127 -0
  18. data/book/lib/layouts/bookpage.glyph +129 -0
  19. data/book/lib/layouts/project.glyph +26 -0
  20. data/book/lib/macros/reference.rb +27 -7
  21. data/book/lib/tasks/tasks.rake +52 -0
  22. data/book/snippets.yml +1 -1
  23. data/book/text/{acknowledgement.glyph → acknowledgements.glyph} +4 -2
  24. data/book/text/changelog.glyph +29 -3
  25. data/book/text/compiling/compiling.glyph +44 -20
  26. data/book/text/compiling/lite_mode.glyph +0 -4
  27. data/book/text/compiling/programmatic_usage.glyph +1 -5
  28. data/book/text/config/document.glyph +35 -0
  29. data/book/text/config/filters.glyph +28 -0
  30. data/book/text/config/options.glyph +25 -0
  31. data/book/text/config/output.glyph +83 -0
  32. data/book/text/extending/bookmarks_headers.glyph +0 -5
  33. data/book/text/extending/command.glyph +56 -0
  34. data/book/text/extending/commands_tasks.glyph +39 -0
  35. data/book/text/extending/further_reading.glyph +0 -3
  36. data/book/text/extending/internals.glyph +3 -5
  37. data/book/text/extending/interpreting.glyph +0 -4
  38. data/book/text/extending/layouts.glyph +68 -0
  39. data/book/text/extending/macro_def.glyph +0 -5
  40. data/book/text/extending/output_format.glyph +78 -0
  41. data/book/text/extending/params_attrs.glyph +0 -3
  42. data/book/text/extending/placeholders.glyph +0 -4
  43. data/book/text/extending/task.glyph +46 -0
  44. data/book/text/extending/validators.glyph +5 -6
  45. data/book/text/getting_started/configuration.glyph +1 -5
  46. data/book/text/getting_started/create_project.glyph +1 -5
  47. data/book/text/getting_started/structure.glyph +0 -4
  48. data/book/text/introduction.glyph +100 -75
  49. data/book/text/license.glyph +1 -2
  50. data/book/text/macros/macros_block.glyph +8 -4
  51. data/book/text/macros/macros_core.glyph +0 -3
  52. data/book/text/macros/macros_filters.glyph +2 -7
  53. data/book/text/macros/macros_inline.glyph +0 -4
  54. data/book/text/macros/macros_structure.glyph +0 -4
  55. data/book/text/ref_commands.glyph +29 -7
  56. data/book/text/stats/bookmarks.glyph +49 -0
  57. data/book/text/stats/links.glyph +90 -0
  58. data/book/text/stats/macros.glyph +73 -0
  59. data/book/text/stats/snippets.glyph +50 -0
  60. data/book/text/stats/stats.glyph +79 -0
  61. data/book/text/text_editing/attribute_intro.glyph +22 -0
  62. data/book/text/text_editing/code.glyph +0 -5
  63. data/book/text/text_editing/conditionals.glyph +0 -4
  64. data/book/text/text_editing/esc_quot.glyph +64 -0
  65. data/book/text/text_editing/evaluation.glyph +0 -3
  66. data/book/text/text_editing/glyph_files.glyph +0 -3
  67. data/book/text/text_editing/images.glyph +0 -5
  68. data/book/text/text_editing/inclusions.glyph +0 -4
  69. data/book/text/text_editing/links.glyph +2 -7
  70. data/book/text/text_editing/macro_intro.glyph +1 -98
  71. data/book/text/text_editing/raw_html.glyph +0 -87
  72. data/book/text/text_editing/section_aliases.glyph +28 -0
  73. data/book/text/text_editing/sections.glyph +1 -32
  74. data/book/text/text_editing/stylesheets.glyph +3 -5
  75. data/book/text/text_editing/topics.glyph +33 -0
  76. data/book/text/text_editing/xml_fallback.glyph +73 -0
  77. data/book/text/troubleshooting/errors_command.glyph +0 -3
  78. data/book/text/troubleshooting/errors_generic.glyph +21 -6
  79. data/book/text/troubleshooting/errors_macro.glyph +11 -8
  80. data/book/text/troubleshooting/errors_parser.glyph +0 -3
  81. data/config.yml +60 -25
  82. data/glyph.gemspec +90 -36
  83. data/layouts/web/index.glyph +16 -0
  84. data/layouts/web/topic.glyph +15 -0
  85. data/layouts/web5/index.glyph +16 -0
  86. data/layouts/web5/topic.glyph +17 -0
  87. data/lib/glyph.rb +36 -49
  88. data/lib/glyph/analyzer.rb +253 -0
  89. data/lib/glyph/bookmark.rb +92 -0
  90. data/lib/glyph/commands.rb +9 -221
  91. data/lib/glyph/commands/add.rb +8 -0
  92. data/lib/glyph/commands/compile.rb +93 -0
  93. data/lib/glyph/commands/config.rb +38 -0
  94. data/lib/glyph/commands/init.rb +6 -0
  95. data/lib/glyph/commands/outline.rb +45 -0
  96. data/lib/glyph/commands/stats.rb +48 -0
  97. data/lib/glyph/commands/todo.rb +29 -0
  98. data/lib/glyph/config.rb +2 -0
  99. data/lib/glyph/document.rb +61 -30
  100. data/lib/glyph/interpreter.rb +2 -2
  101. data/lib/glyph/macro.rb +14 -5
  102. data/lib/glyph/macro_helpers.rb +280 -0
  103. data/lib/glyph/macro_validators.rb +37 -2
  104. data/lib/glyph/reporter.rb +182 -0
  105. data/lib/glyph/syntax_node.rb +37 -10
  106. data/lib/glyph/system_extensions.rb +8 -45
  107. data/lib/glyph/utils.rb +148 -0
  108. data/macros/core.rb +10 -15
  109. data/macros/filters.rb +4 -5
  110. data/macros/html/block.rb +46 -30
  111. data/macros/html/inline.rb +9 -35
  112. data/macros/html/structure.rb +59 -72
  113. data/macros/html5/block.rb +69 -0
  114. data/macros/html5/inline.rb +24 -0
  115. data/macros/html5/structure.rb +139 -0
  116. data/macros/xml.rb +1 -1
  117. data/spec/files/custom_command.rb +6 -0
  118. data/spec/files/custom_tasks.rake +6 -0
  119. data/spec/files/document_for_stats.glyph +12 -0
  120. data/spec/files/references.glyph +4 -0
  121. data/spec/files/web1.glyph +11 -0
  122. data/spec/files/web2.glyph +10 -0
  123. data/spec/files/web_doc.glyph +23 -0
  124. data/spec/lib/analyzer_spec.rb +137 -0
  125. data/spec/lib/bookmark_spec.rb +64 -0
  126. data/spec/lib/commands_spec.rb +30 -5
  127. data/spec/lib/document_spec.rb +49 -9
  128. data/spec/lib/glyph_spec.rb +21 -1
  129. data/spec/lib/macro_spec.rb +6 -6
  130. data/spec/lib/macro_validators_spec.rb +24 -0
  131. data/spec/lib/reporter_spec.rb +132 -0
  132. data/spec/macros/core_spec.rb +2 -3
  133. data/spec/macros/filters_spec.rb +2 -2
  134. data/spec/macros/html5_spec.rb +101 -0
  135. data/spec/macros/macros_spec.rb +16 -6
  136. data/spec/macros/web5_spec.rb +32 -0
  137. data/spec/macros/web_spec.rb +59 -0
  138. data/spec/macros/xml_spec.rb +1 -1
  139. data/spec/spec_helper.rb +24 -4
  140. data/spec/tasks/generate_spec.rb +54 -0
  141. data/spec/tasks/load_spec.rb +29 -3
  142. data/spec/tasks/project_spec.rb +21 -3
  143. data/styles/default.css +40 -4
  144. data/styles/pagination.css +59 -41
  145. data/tasks/generate.rake +110 -31
  146. data/tasks/load.rake +39 -7
  147. data/tasks/project.rake +9 -7
  148. metadata +115 -34
  149. data/book/images/glyph.png +0 -0
  150. data/book/images/glyph.svg +0 -351
  151. data/book/output/html/glyph.html +0 -4482
  152. data/book/output/html/images/document_generation.png +0 -0
  153. data/book/output/html/images/glyph.png +0 -0
  154. data/book/output/html/images/glyph.svg +0 -351
  155. data/book/output/pdf/glyph.pdf +4 -10254
  156. data/book/script/authors +0 -1
  157. data/book/script/changelog +0 -1
  158. data/book/script/license +0 -1
  159. data/book/script/readme +0 -1
  160. data/book/text/ref_config.glyph +0 -100
  161. data/book/text/ref_macros.glyph +0 -6
  162. data/book/text/troubleshooting/errors_intro.glyph +0 -3
@@ -0,0 +1,92 @@
1
+ module Glyph
2
+
3
+ # @since 0.4.0
4
+ # This class is used to model bookmarks within a Glyph document. It contains methods to store
5
+ # bookmark data and resolve link paths automatically.
6
+ class Bookmark
7
+
8
+ attr_accessor :title, :file, :definition
9
+
10
+ # Initializes a bookmark object from a hash containing bookmark data.
11
+ # @param [Hash] hash the bookmark hash
12
+ # @option hash [String] :id the bookmark ID
13
+ # @option hash [String] :file the file containing the bookmark
14
+ # @option hash [String] :title the title of the bookmark
15
+ # @option hash [String] :definition the file where the bookmark was defined
16
+ # @raise [RuntimeError] if the bookmark ID is not specified
17
+ # @raise [RuntimeError] if the bookmark ID is invalid (it must contain only letters, numbers, - or _)
18
+ def initialize(hash)
19
+ @id = hash[:id].to_sym rescue nil
20
+ @file = hash[:file]
21
+ @title = hash[:title]
22
+ @definition = hash[:definition]
23
+ raise RuntimeError, "Bookmark ID not specified" unless @id
24
+ raise RuntimeError, "Invalid bookmark ID: #{@id}" unless check_id
25
+ end
26
+
27
+ # Returns the bookmark ID.
28
+ def code
29
+ @id
30
+ end
31
+
32
+ # Returns true if the two bookmarks have the same ID and file
33
+ # @param [Glyph::Bookmark] b the bookmark to compare
34
+ # @raises [RuntimeError] if the parameter supplied is not a bookmark
35
+ def ==(b)
36
+ raise RuntimeError, "#{b.inspect} is not a bookmark" unless b.is_a? Glyph::Bookmark
37
+ self.code == b.code && self.file == b.file
38
+ end
39
+
40
+ # Returns the appropriate link path to the bookmark, depending on the specified file
41
+ # @param [String] file the file where the link to the bookmark must be placed
42
+ # @return [String] the link to the bookmark
43
+ def link(file=nil)
44
+ if multiple_output_files? then
45
+ dest_file = @file.to_s
46
+ dest_file += '.glyph' unless dest_file.match /\..+$/
47
+ dest_file.gsub!(/^text\//, '') unless Glyph.lite?
48
+ external_file = dest_file.to_s.gsub(/\..+$/, Glyph["output.#{Glyph['document.output']}.extension"])
49
+ f = (file.blank? || file != @file) ? "#{Glyph["output.#{Glyph['document.output']}.base"]}#{external_file}" : ""
50
+ "#{f}##{@id}"
51
+ else
52
+ "##{@id}"
53
+ end
54
+ end
55
+
56
+ # Returns the bookmark id
57
+ # @return [String] the bookmark ID
58
+ def to_s
59
+ @id.to_s
60
+ end
61
+
62
+ alias to_str to_s
63
+
64
+ private
65
+
66
+ def check_id
67
+ @id.to_s.match(/[^a-z0-9_-]/i) ? false : true
68
+ end
69
+
70
+ end
71
+
72
+ # This class is used to model bookmark headers
73
+ class Header < Bookmark
74
+
75
+ attr_reader :level
76
+
77
+ # Initializes the bookmark from a hash. The header hash takes two additional options:
78
+ # :level (the header level within the document), :toc (whether the header should appear in the Table of Contents or not)
79
+ def initialize(hash)
80
+ super(hash)
81
+ @level = hash[:level]
82
+ @toc = hash[:toc]
83
+ end
84
+
85
+ # Returns true if the header is displayed in the Table of contents
86
+ def toc?
87
+ @toc
88
+ end
89
+
90
+ end
91
+
92
+ end
@@ -4,226 +4,16 @@ include GLI
4
4
  GLI.desc "Enable debugging"
5
5
  switch [:d, :debug]
6
6
 
7
- GLI.desc 'Create a new Glyph project'
8
- command :init do |c|
9
- c.action do |global_options,options,args|
10
- Glyph.run 'project:create', Dir.pwd
11
- end
12
- end
13
-
14
- GLI.desc 'Add a new text file to the project'
15
- arg_name "file_name"
16
- command :add do |c|
17
- c.action do |global_options,options,args|
18
- raise ArgumentError, "Please specify a file name." if args.blank?
19
- Glyph.run 'project:add', args[0]
20
- end
21
- end
22
-
23
- GLI.desc 'Compile the project'
24
- arg_name "[source_file]"
25
- arg_name "[destination_file]"
26
- command :compile do |c|
27
- c.desc "Specify a glyph file to compile (default: document.glyph)"
28
- c.flag [:s, :source]
29
- c.desc "Specify the format of the output file (default: html)"
30
- c.flag [:f, :format]
31
- c.desc "Auto-regenerate output on file changes"
32
- c.switch [:a, :auto]
33
- c.action do |global_options, options, args|
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
38
- output_targets = Glyph['system.output_targets']
39
- target = nil
40
- Glyph['document.output'] = options[:f] if options[:f]
41
- target = Glyph['document.output']
42
- target = nil if target.blank?
43
- target ||= Glyph['filters.target']
44
- Glyph['document.source'] = options[:s] if options[:s]
45
- raise ArgumentError, "Output target not specified" unless target
46
- raise ArgumentError, "Unknown output target '#{target}'" unless output_targets.include? target.to_sym
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[:a] && !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
110
- end
111
- end
7
+ require Glyph::LIB/'commands/init'
8
+ require Glyph::LIB/'commands/add'
9
+ require Glyph::LIB/'commands/compile'
10
+ require Glyph::LIB/'commands/config'
11
+ require Glyph::LIB/'commands/todo'
12
+ require Glyph::LIB/'commands/outline'
13
+ require Glyph::LIB/'commands/stats'
112
14
 
113
- GLI.desc 'Display all project TODO items'
114
- command :todo do |c|
115
- c.action do |global_options, options, args|
116
- Glyph['system.quiet'] = true
117
- Glyph.run "generate:document"
118
- Glyph['system.quiet'] = false
119
- unless Glyph.document.todos.blank?
120
- puts "====================================="
121
- puts "#{Glyph['document.title']} - TODOs"
122
- puts "====================================="
123
- # Group items
124
- if Glyph.document.todos.respond_to? :group_by then
125
- Glyph.document.todos.group_by{|e| e[:source]}.each_pair do |k, v|
126
- puts
127
- puts "=== #{k} "
128
- v.each do |i|
129
- puts " * #{i[:text]}"
130
- end
131
- end
132
- else
133
- Glyph.document.todos.each do |t|
134
- Glyph.info t
135
- end
136
- end
137
- else
138
- Glyph.info "Nothing left to do."
139
- end
140
- end
141
- end
142
-
143
- GLI.desc 'Display the document outline'
144
- command :outline do |c|
145
- c.desc "Limit to level N"
146
- c.flag :l, :level
147
- c.desc "Show file names"
148
- c.switch :f, :files
149
- c.desc "Show titles"
150
- c.switch :t, :titles
151
- c.desc "Show IDs"
152
- c.switch :i, :ids
153
- c.action do |global_options, options, args|
154
- levels = options[:l]
155
- ids = options[:i]
156
- files = options[:f]
157
- titles = options[:t]
158
- titles = true if !ids && !levels && !files || levels && !ids
159
- Glyph['system.quiet'] = true
160
- Glyph.run "generate:document"
161
- Glyph['system.quiet'] = false
162
- puts "====================================="
163
- puts "#{Glyph['document.title']} - Outline"
164
- puts "====================================="
165
- Glyph.document.structure.descend do |n, level|
166
- if n.is_a?(Glyph::MacroNode) then
167
- case
168
- when n[:name].in?(Glyph['system.structure.headers']) then
169
- header = Glyph.document.header?(n[:header])
170
- next if !header || levels && header[:level]-1 > levels.to_i
171
- last_level = header[:level]
172
- h_id = ids ? "[##{header[:id]}]" : ""
173
- h_title = titles ? "#{header[:title]} " : ""
174
- text = (" "*(header[:level]-1))+"- "+h_title+h_id
175
- puts text unless text.blank?
176
- when n[:name] == :include then
177
- if files && n.find_parent{|p| p[:name] == :document && p.is_a?(Glyph::MacroNode)} then
178
- # When using the book or article macros, includes appear twice:
179
- # * in the macro parameters
180
- # * as children of the document macro
181
- puts "=== #{n.param(0)}"
182
- end
183
- end
184
- end
185
- end
186
- end
187
- end
188
-
189
- GLI.desc 'Get/set configuration settings'
190
- arg_name "setting [new_value]"
191
- command :config do |c|
192
- c.desc "Save to global configuration"
193
- c.switch [:g, :global]
194
- c.action do |global_options,options,args|
195
- Glyph.run 'load:config'
196
- if options[:g] then
197
- config = Glyph::GLOBAL_CONFIG
198
- else
199
- config = Glyph::PROJECT_CONFIG
200
- end
201
- case args.length
202
- when 0 then
203
- raise ArgumentError, "Too few arguments."
204
- when 1 then # read current config
205
- setting = Glyph[args[0]]
206
- raise RuntimeError, "Unknown setting '#{args[0]}'" if setting.blank?
207
- Glyph.info setting
208
- when 2 then
209
- if args[0].match /^system\..+/ then
210
- Glyph.warning "Cannot reset '#@value' setting (system use only)."
211
- else
212
- # Remove all overrides
213
- Glyph.config_reset
214
- # Reload current project config
215
- config.read
216
- config.set args[0], args[1]
217
- # Write changes to file
218
- config.write
219
- # Refresh configuration
220
- Glyph.config_refresh
221
- end
222
- else
223
- raise ArgumentError, "Too many arguments."
224
- end
225
- end
226
- end
15
+ Glyph.run 'load:tasks'
16
+ Glyph.run 'load:commands'
227
17
 
228
18
  pre do |global,command,options,args|
229
19
  # Pre logic here
@@ -261,6 +51,4 @@ on_error do |exception|
261
51
  end
262
52
  true
263
53
  end
264
- # Error logic here
265
- # return false to skip default error handling
266
54
  end
@@ -0,0 +1,8 @@
1
+ GLI.desc 'Add a new text file to the project'
2
+ arg_name "file_name"
3
+ command :add do |c|
4
+ c.action do |global_options,options,args|
5
+ raise ArgumentError, "Please specify a file name." if args.blank?
6
+ Glyph.run 'project:add', args[0]
7
+ end
8
+ end
@@ -0,0 +1,93 @@
1
+ GLI.desc 'Compile the project'
2
+ arg_name "[source_file] [destination_file]"
3
+ command :compile do |c|
4
+ c.desc "Specify a glyph file to compile (default: document.glyph)"
5
+ c.flag [:s, :source]
6
+ c.desc "Specify the format of the output file (default: html)"
7
+ c.flag [:f, :format]
8
+ c.desc "Auto-regenerate output on file changes"
9
+ c.switch [:a, :auto]
10
+ c.action do |global_options, options, args|
11
+ raise ArgumentError, "Too many arguments" if args.length > 2
12
+ Glyph.lite_mode = true unless args.blank?
13
+ Glyph.run! 'load:config'
14
+ original_config = Glyph::CONFIG.dup
15
+ output_targets = Glyph['output'].keys
16
+ target = nil
17
+ Glyph['document.output'] = options[:f] if options[:f]
18
+ target = Glyph['document.output']
19
+ target = nil if target.blank?
20
+ target ||= Glyph["output.#{Glyph['document.output']}.filter_target"]
21
+ Glyph['document.source'] = options[:s] if options[:s]
22
+ if Glyph.multiple_output_files? then
23
+ Glyph["output.#{Glyph['document.output']}.base"] = Glyph::PROJECT/"output/#{Glyph['document.output']}/".to_s if Glyph["output.#{Glyph['document.output']}.base"].blank?
24
+ else
25
+ Glyph["output.#{Glyph['document.output']}.base"] = ""
26
+ end
27
+ raise ArgumentError, "Output target not specified" unless target
28
+ raise ArgumentError, "Unknown output target '#{target}'" unless output_targets.include? target.to_sym
29
+
30
+ # Lite mode
31
+ if Glyph.lite? then
32
+ source_file = Pathname.new args[0]
33
+ filename = source_file.basename(source_file.extname).to_s
34
+ destination_file = Pathname.new(args[1]) rescue nil
35
+ src_extension = Regexp.escape(source_file.extname)
36
+ dst_extension = "."+Glyph['document.output']
37
+ destination_file ||= Pathname.new(source_file.to_s.gsub(/#{src_extension}$/, dst_extension))
38
+ raise ArgumentError, "Source file '#{source_file}' does not exist" unless source_file.exist?
39
+ raise ArgumentError, "Source and destination file are the same" if source_file.to_s == destination_file.to_s
40
+ Glyph['document.filename'] = filename
41
+ Glyph['document.source'] = source_file.to_s
42
+ Glyph['document.output_dir'] = destination_file.parent.to_s # System use only
43
+ Glyph['document.output_file'] = destination_file.basename.to_s # System use only
44
+ end
45
+ begin
46
+ Glyph.run "generate:#{target}"
47
+ rescue Exception => e
48
+ message = e.message
49
+ if Glyph.debug? then
50
+ message << "\n"+"-"*20+"[ Backtrace: ]"+"-"*20
51
+ message << "\n"+e.backtrace.join("\n")
52
+ message << "\n"+"-"*54
53
+ end
54
+ raise RuntimeError, message if Glyph.library?
55
+ Glyph.error message
56
+ end
57
+
58
+ # Auto-regeneration
59
+ if options[:a] && !Glyph.lite? then
60
+ Glyph.lite_mode = false
61
+ begin
62
+ require 'directory_watcher'
63
+ rescue LoadError
64
+ raise RuntimeError, "DirectoryWatcher is not available. Install it with: gem install directory_watcher"
65
+ end
66
+ Glyph.info 'Auto-regeneration enabled'
67
+ Glyph.info 'Use ^C to interrupt'
68
+ glob = ['*.glyph', 'config.yml', 'images/**/*', 'lib/**/*', 'snippets.yml', 'styles/**/*', 'text/**/*']
69
+ dw = DirectoryWatcher.new(Glyph::PROJECT, :glob => glob, :interval => 1, :pre_load => true)
70
+ dw.add_observer do |*args|
71
+ puts "="*50
72
+ Glyph.info "Regeneration started: #{args.size} files changed"
73
+ Glyph.reset
74
+ begin
75
+ Glyph.run! "generate:#{target}"
76
+ rescue Exception => e
77
+ Glyph.error e.message
78
+ if Glyph.debug? then
79
+ puts "-"*20+"[ Backtrace: ]"+"-"*20
80
+ puts e.backtrace
81
+ pits "-"*54
82
+ end
83
+ end
84
+ end
85
+ dw.start
86
+ begin
87
+ sleep
88
+ rescue Interrupt
89
+ end
90
+ dw.stop
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,38 @@
1
+ GLI.desc 'Get/set configuration settings'
2
+ arg_name "setting [new_value]"
3
+ command :config do |c|
4
+ c.desc "Save to global configuration"
5
+ c.switch [:g, :global]
6
+ c.action do |global_options,options,args|
7
+ Glyph.run 'load:config'
8
+ if options[:g] then
9
+ config = Glyph::GLOBAL_CONFIG
10
+ else
11
+ config = Glyph::PROJECT_CONFIG
12
+ end
13
+ case args.length
14
+ when 0 then
15
+ raise ArgumentError, "Too few arguments."
16
+ when 1 then # read current config
17
+ setting = Glyph[args[0]]
18
+ raise RuntimeError, "Unknown setting '#{args[0]}'" if setting.blank?
19
+ Glyph.info setting.inspect
20
+ when 2 then
21
+ if args[0].match /^system\..+/ then
22
+ Glyph.warning "Cannot reset '#@value' setting (system use only)."
23
+ else
24
+ # Remove all overrides
25
+ Glyph.config_reset
26
+ # Reload current project config
27
+ config.read
28
+ config.set args[0], args[1]
29
+ # Write changes to file
30
+ config.write
31
+ # Refresh configuration
32
+ Glyph.config_refresh
33
+ end
34
+ else
35
+ raise ArgumentError, "Too many arguments."
36
+ end
37
+ end
38
+ end