glyph 0.3.0 → 0.4.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 (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