glyph 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/book/config.yml +1 -1
  2. data/book/document.glyph +5 -5
  3. data/book/lib/layouts/bookindex.glyph +4 -27
  4. data/book/lib/layouts/bookpage.glyph +5 -28
  5. data/book/lib/macros/reference.rb +4 -12
  6. data/book/text/changelog.glyph +10 -2
  7. data/book/text/compiling/compiling.glyph +0 -1
  8. data/book/text/extending/interpreting.glyph +1 -1
  9. data/book/text/introduction.glyph +21 -29
  10. data/book/text/license.glyph +1 -1
  11. data/book/text/macros/macros_core.glyph +0 -3
  12. data/book/text/ref_commands.glyph +32 -24
  13. data/book/text/stats/stats.glyph +1 -1
  14. data/book/text/text_editing/code.glyph +2 -2
  15. data/book/text/text_editing/evaluation.glyph +6 -6
  16. data/book/text/text_editing/inclusions.glyph +2 -2
  17. data/book/text/text_editing/links.glyph +3 -3
  18. data/config.yml +8 -1
  19. data/glyph-0.5.1.gem +0 -0
  20. data/glyph.gemspec +7 -7
  21. data/lib/glyph.rb +2 -2
  22. data/lib/glyph/commands.rb +9 -16
  23. data/lib/glyph/commands/add.rb +1 -1
  24. data/lib/glyph/commands/compile.rb +1 -1
  25. data/lib/glyph/commands/config.rb +1 -1
  26. data/lib/glyph/commands/init.rb +1 -1
  27. data/lib/glyph/commands/outline.rb +1 -1
  28. data/lib/glyph/commands/stats.rb +1 -1
  29. data/lib/glyph/commands/todo.rb +1 -1
  30. data/lib/glyph/utils.rb +200 -175
  31. data/macros/block.rb +2 -2
  32. data/macros/reps/html.rb +4 -3
  33. data/macros/reps/html5.rb +4 -3
  34. data/macros/structure.rb +1 -0
  35. data/spec/config.yml +3 -3
  36. data/spec/lib/commands_spec.rb +15 -28
  37. data/spec/macros/core_spec.rb +4 -4
  38. data/spec/macros/filters_spec.rb +3 -3
  39. data/spec/macros/html5_spec.rb +3 -3
  40. data/spec/macros/macros_spec.rb +28 -3
  41. data/spec/macros/textile_spec.rb +2 -2
  42. data/spec/macros/web5_spec.rb +4 -4
  43. data/spec/macros/web_spec.rb +4 -4
  44. data/spec/spec_helper.rb +12 -1
  45. data/spec/tasks/generate_spec.rb +1 -1
  46. data/styles/coderay.css +9 -7
  47. data/styles/coderay.scss +7 -7
  48. data/styles/default.css +60 -43
  49. data/styles/default.scss +68 -40
  50. data/styles/definitions.scss +1 -1
  51. data/styles/pagination.css +16 -13
  52. data/styles/pagination.scss +18 -18
  53. data/tasks/generate.rake +3 -3
  54. data/tasks/load.rake +1 -4
  55. metadata +98 -47
@@ -2,7 +2,7 @@ def:[stats_for|
2
2
  section[
3
3
  @title[Displaying stats about {{title}}]
4
4
  txt[To display statistics about {{object}}, execute code[glyph stats {{command}}]. Glyph displays something like this:]
5
- highlight[=html|
5
+ highlight[=plain|
6
6
  {{example}}
7
7
  =]
8
8
  section[
@@ -3,7 +3,7 @@ If you're a programmer, chances are that you're going to include some source cod
3
3
 
4
4
  Cosider the following piece of ruby code:
5
5
  ]
6
- highlight[=mediawiki|
6
+ highlight[=text|
7
7
  def find_child(&block)
8
8
  children.each do \|c\|
9
9
  c.descend do \|node, level\|
@@ -14,7 +14,7 @@ def find_child(&block)
14
14
  end
15
15
  =]
16
16
  p[It can be wrapped in a highlight macro, like so:]
17
- highlight[=mediawiki|
17
+ highlight[=text|
18
18
  highlight[\=ruby\|
19
19
  def find_child(&block)
20
20
  children.each do \\\/\|c\\\/\|
@@ -8,14 +8,14 @@ As of version 0.5.0, Glyph can be considered _Turing-complete_, as it satisfies
8
8
  * A memory model which emulates an infinite store: there are no enforced limits on attribute/snippets allocations and number of algorithms or parameters.
9
9
  ]
10
10
 
11
- §txt[
11
+ §[
12
12
  @title[Operations on integer values]
13
13
 
14
- Glyph can be used to perform operation on integer values (additions, subtractions and multiplications). For example, code[=\/add[2\|3\|7]=] will evaluate to @12@, and code[=\/multiply[add[3\|7]\|subtract[5\|1\|2]]=] will return 20.
14
+ p[Glyph can be used to perform operation on integer values (additions, subtractions and multiplications). For example, code[=\/add[2\|3\|7]=] will evaluate to @12@, and code[=\/multiply[add[3\|7]\|subtract[5\|1\|2]]=] will return 20.]
15
15
 
16
- As a more complex example, consider the following @factorial@ macro, which is able to calculate the factorial of a number recursively:
16
+ p[As a more complex example, consider the following @factorial@ macro, which is able to calculate the factorial of a number recursively:]
17
17
 
18
- highlight[=html|
18
+ highlight[=html|
19
19
  def:[factorial\|
20
20
  ?[
21
21
  eq[{{0}}\|0]\|1\|
@@ -24,9 +24,9 @@ def:[factorial\|
24
24
  ]
25
25
  ]
26
26
  ]
27
- =]
27
+ =]
28
28
 
29
- If you try executing code[=factorial[5]=], it will evaluate to @120@.
29
+ p[If you try executing code[=factorial[5]=], it will evaluate to @120@.]
30
30
 
31
31
  ]
32
32
  §txt[
@@ -28,7 +28,7 @@ While including the context of an entire file is definitely a useful feature for
28
28
 
29
29
  Snippets can be defined using the %>[snippet:] (aliased by @&:@) and called by using the %>[snippet] (aliased by @&@). Consider the following simple example:
30
30
  ]
31
- highlight[=html|
31
+ highlight[=plain|
32
32
  &:[markups\|Textile or Markdown]
33
33
 
34
34
  Glyph supports &[markups].
@@ -44,7 +44,7 @@ Snippets (or any other macro) can be nested within other snippets. Glyph takes c
44
44
  @id[fragments]
45
45
  txt[As an even simpler alternative to snippets, consider using _fragments_. The %>[fragment:] (aliased by @##@) can be used to mark a section of Glyph code as a fragment that can then be _embedded_ using the %>[embed] (aliased by @<=@), like this:]
46
46
 
47
- highlight[=html|
47
+ highlight[=plain|
48
48
  Snippets and fragments ##[good_way\|are a good way to reuse] small chunks of content, while the include and load macros <=[good_way] entire files.
49
49
  =]
50
50
  ]
@@ -9,7 +9,7 @@ If you care about link validation and you want to save some keystrokes, then you
9
9
  ]
10
10
  box[Example|
11
11
  p[&[gcode]]
12
- highlight[=html|
12
+ highlight[=plain|
13
13
  This is a link to link[#test].
14
14
  ...
15
15
  This is link[#wrong].
@@ -23,7 +23,7 @@ This is a #[test\\\|test anchor].
23
23
  <p>This is a <a id="test">test anchor</a>.</p>
24
24
  =]
25
25
  p[Additionally, the following warning message is displayed when =>[#compile|compiling]:]
26
- highlight[=html|
26
+ highlight[=plain|
27
27
  warning: Bookmark 'wrong' does not exist
28
28
  -> source: @: authoring.textile
29
29
  -> path: document/body/bodymatter/chapter/@/textile/section/section/box/link
@@ -37,7 +37,7 @@ Basically, if you use the %>[link] and the %>[anchor], Glyph makes sure that:
37
37
 
38
38
  Besides using the %>[anchor], you can also create an anchor for a header by passing an code[@id] attribute the the %>[section], like this:
39
39
  ]
40
- highlight[=html|
40
+ highlight[=plain|
41
41
  section[
42
42
  @title[My Section]
43
43
  @id[my_section]
data/config.yml CHANGED
@@ -37,23 +37,27 @@
37
37
  :extension: .html
38
38
  :filter_target: html
39
39
  :macro_reps: html
40
+ :clean_source: true
40
41
  :html5:
41
42
  :multifile: false
42
43
  :extension: .html
43
44
  :filter_target: html
44
45
  :macro_reps: html5
46
+ :clean_source: true
45
47
  :pdf:
46
48
  :multifile: false
47
49
  :extension: .pdf
48
50
  :filter_target: html
49
51
  :through: html
50
- :generator: wkhtmltopdf
52
+ :generator: prince
51
53
  :macro_reps: html
54
+ :clean_source: false
52
55
  :web:
53
56
  :multifile: true
54
57
  :extension: .html
55
58
  :filter_target: html
56
59
  :macro_reps: html
60
+ :clean_source: true
57
61
  :layout_dir: web
58
62
  :layouts:
59
63
  :topic: topic
@@ -64,6 +68,7 @@
64
68
  :extension: .html
65
69
  :filter_target: html
66
70
  :macro_reps: html5
71
+ :clean_source: true
67
72
  :layout_dir: web5
68
73
  :layouts:
69
74
  :topic: topic
@@ -74,6 +79,7 @@
74
79
  :extension: .epub
75
80
  :filter_target: html
76
81
  :generator: calibre
82
+ :clean_source: false
77
83
  :calibre:
78
84
  # See options at http://calibre-ebook.com/user_manual/cli/ebook-convert-3.html
79
85
  "output-profile": nook
@@ -83,6 +89,7 @@
83
89
  :extension: .mobi
84
90
  :filter_target: html
85
91
  :generator: calibre
92
+ :clean_source: false
86
93
  :calibre:
87
94
  # See options at http://calibre-ebook.com/user_manual/cli/ebook-convert-3.html
88
95
  "no-inline-toc":
Binary file
@@ -2,13 +2,13 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "glyph"
5
- s.version = "0.5.1"
5
+ s.version = "0.5.2"
6
6
  s.summary = "Glyph -- A Ruby-powered Document Authoring Framework"
7
7
  s.description = "Glyph is a framework for structured document authoring."
8
8
  s.homepage = "http://www.h3rald.com/glyph/"
9
9
  s.authors = ["Fabio Cevasco"]
10
10
  s.email = "h3rald@h3rald.com"
11
- s.date = "2011-11-04"
11
+ s.date = "2012-11-10"
12
12
  s.license = "MIT"
13
13
 
14
14
  s.files = ["Rakefile"]
@@ -32,15 +32,15 @@ Gem::Specification.new do |s|
32
32
  s.default_executable = "glyph"
33
33
  s.extra_rdoc_files = Dir.glob "*.textile"
34
34
 
35
- s.add_runtime_dependency("gli", [">= 1.4.0"])
35
+ s.add_runtime_dependency("gli", [">= 2.4.1"])
36
36
  s.add_runtime_dependency("extlib", [">= 0.9.15"])
37
37
  s.add_runtime_dependency("rake", [">= 0.9.2.2"])
38
38
 
39
- s.add_development_dependency("rspec", [">= 2.5.1"])
40
- s.add_development_dependency("yard", [">= 0.7.4"])
39
+ s.add_development_dependency("rspec", [">= 2.11.0"])
40
+ s.add_development_dependency("yard", [">= 0.8.3"])
41
41
  s.add_development_dependency("directory_watcher", [">= 1.4.1"])
42
- s.add_development_dependency("sass", [">= 3.1.11"])
42
+ s.add_development_dependency("sass", [">= 3.2.1"])
43
43
  s.add_development_dependency("RedCloth", [">= 4.2.9"])
44
44
  s.add_development_dependency("bluecloth", [">= 2.2.0"])
45
- s.add_development_dependency("coderay", [">= 1.0.4"])
45
+ s.add_development_dependency("coderay", [">= 1.0.8"])
46
46
  end
@@ -72,7 +72,7 @@ module Glyph
72
72
  class MutualInclusionError < MacroError; end
73
73
 
74
74
  # The current version of Glyph
75
- VERSION = "0.5.1"
75
+ VERSION = "0.5.2"
76
76
 
77
77
  # All the currently-loaded macros
78
78
  MACROS = {}
@@ -278,7 +278,7 @@ module Glyph
278
278
  require 'glyph/commands'
279
279
  self['system.quiet'] = true
280
280
  self.library_mode = true
281
- GLI.run ["compile", src.to_s, out].compact
281
+ TOPLEVEL_BINDING.eval('self').run ["compile", src.to_s, out].compact
282
282
  rescue Exception => e
283
283
  raise
284
284
  ensure
@@ -1,20 +1,17 @@
1
1
  # encoding: utf-8
2
2
 
3
- include GLI
3
+ include GLI::App
4
4
 
5
- GLI.desc "Enable debugging"
5
+ version Glyph::VERSION
6
+ program_desc "A rapid document authoring framework"
7
+
8
+ d "Enable debugging"
6
9
  switch [:d, :debug]
7
10
 
8
- GLI.desc "Prints the version of the program"
9
- switch [:v, :version]
11
+ d "Display documentation"
12
+ switch [:h, :help]
10
13
 
11
- require Glyph::LIB/'commands/init'
12
- require Glyph::LIB/'commands/add'
13
- require Glyph::LIB/'commands/compile'
14
- require Glyph::LIB/'commands/config'
15
- require Glyph::LIB/'commands/todo'
16
- require Glyph::LIB/'commands/outline'
17
- require Glyph::LIB/'commands/stats'
14
+ commands_from Glyph::LIB/"commands"
18
15
 
19
16
  Glyph.run 'load:tasks'
20
17
  Glyph.run 'load:commands'
@@ -26,11 +23,7 @@ pre do |global,command,options,args|
26
23
  if global[:d] then
27
24
  Glyph.debug_mode = true
28
25
  end
29
- if global[:v] || !command || command.name == :help then
30
- puts "Glyph v#{Glyph::VERSION}"
31
- puts
32
- end
33
- global[:v] ? false : true
26
+ true
34
27
  end
35
28
 
36
29
  post do |global,command,options,args|
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- GLI.desc 'Add a new text file to the project'
3
+ d 'Add a new text file to the project'
4
4
  arg_name "file_name"
5
5
  command :add do |c|
6
6
  c.action do |global_options,options,args|
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- GLI.desc 'Compile the project'
3
+ d 'Compile the project'
4
4
  arg_name "[source_file] [destination_file]"
5
5
  command :compile do |c|
6
6
  c.desc "Specify a glyph file to compile (default: document.glyph)"
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- GLI.desc 'Get/set configuration settings'
3
+ d 'Get/set configuration settings'
4
4
  arg_name "setting [new_value]"
5
5
  command :config do |c|
6
6
  c.desc "Read from/Save to global configuration"
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- GLI.desc 'Create a new Glyph project'
3
+ d 'Create a new Glyph project'
4
4
  command :init do |c|
5
5
  c.action do |global_options,options,args|
6
6
  Glyph.run 'project:create', Dir.pwd
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- GLI.desc 'Display the document outline'
3
+ d 'Display the document outline'
4
4
  command :outline do |c|
5
5
  c.desc "Limit to level N"
6
6
  c.flag :l, :level
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- GLI.desc 'Display statistics'
3
+ d 'Display statistics'
4
4
  command :stats do |c|
5
5
  c.desc "Display stats about macros"
6
6
  c.switch [:m, :macros]
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- GLI.desc 'Display all project TODO items'
3
+ d 'Display all project TODO items'
4
4
  command :todo do |c|
5
5
  c.action do |global_options, options, args|
6
6
  Glyph['system.quiet'] = true
@@ -1,179 +1,204 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Glyph
4
- #@since 0.4.0
5
- module Utils
6
-
7
- # Prints a message
8
- # @param [String] message the message to print
9
- def msg(message)
10
- puts message unless Glyph['system.quiet']
11
- end
12
-
13
- # Prints an informational message
14
- # @param [String] message the message to print
15
- def info(message)
16
- puts "-- #{message}" unless Glyph['system.quiet']
17
- end
18
-
19
- # Prints a warning
20
- # @param [String] message the message to print
21
- def warning(message)
22
- puts "-> warning: #{message}" unless Glyph['system.quiet']
23
- end
24
-
25
- # Prints an error
26
- # @param [String] message the message to print
27
- def error(message)
28
- puts "=> error: #{message}" unless Glyph['system.quiet']
29
- end
30
-
31
- # Prints a message if running in debug mode
32
- # @param [String] message the message to print
33
- def debug(message)
34
- puts message if Glyph.debug?
35
- end
36
-
37
- # Dumps and serialize an object to a YAML file
38
- # @param [#to_s] file the file to write to
39
- # @param [Object] obj the object to serialize
40
- def yaml_dump(file, obj)
41
- File.open(file.to_s, 'w+') {|f| f.write obj.to_yaml}
42
- end
43
-
44
- # Loads and deserialiaze the contents of a YAML file
45
- # @param [#to_s] file the YAML file to load
46
- # @return [Object] the contents of the YAML file, deserialized
47
- def yaml_load(file)
48
- YAML.load_file(file.to_s)
49
- end
50
-
51
- # Loads the contents of a file
52
- # @param [#to_s] file the file to load
53
- # @return [String] the contents of the file
54
- def file_load(file)
55
- result = ""
56
- File.open(file.to_s, 'r:utf-8') do |f|
57
- while l = f.gets
58
- result << l
59
- end
60
- end
61
- result
62
- end
63
-
64
- # Writes a string to a file
65
- # @param [#to_s] file the file to write
66
- # @param [String] contents the string to write
67
- # @return [String] the string written to the file
68
- def file_write(file, contents="")
69
- File.open(file.to_s, 'w+:utf-8') do |f|
70
- f.print contents
71
- end
72
- contents
73
- end
74
-
75
- # An alias for FileUtils#cp
76
- # @param [String] source the source file
77
- # @param [String] dest the destination file or directory
78
- # @param [Hash] options copy options
79
- def file_copy(source, dest, options={})
80
- FileUtils.cp source, dest, options
81
- end
82
-
83
- # Loads all child elements of the given directory, matching a given extension
84
- # @param [Pathname] dir the directory containing the files
85
- # @param [String] extension the file extension to check
86
- # @yield [file, contents] the file (Pathname) and its contents
87
- # @since 0.4.0
88
- def load_files_from_dir(dir, extension, &block)
89
- if dir.exist? then
90
- dir.children.each do |c|
91
- block.call(c, file_load(c)) unless c.directory? || c.extname != extension
92
- end
93
- end
94
- end
95
-
96
- # Iterates through the files in a source directory recursively
97
- # @param [String] dir the directory to operate on (mirrored in the output directory)
98
- # @yield [src, dest] the source file and the corresponding output file
99
- # @since 0.4.0
100
- def with_files_from(dir, &block)
101
- output = complex_output? ? 'tmp' : Glyph['document.output']
102
- dir_path = Glyph::PROJECT/"output/#{output}/#{dir}"
103
- dir_path.mkpath
104
- (Glyph::PROJECT/dir).find do |i|
105
- if i.file? then
106
- dest = "#{Glyph::PROJECT/"output/#{output}/#{dir}"}/#{i.relative_path_from(Glyph::PROJECT/dir)}"
107
- src = i.to_s
108
- Pathname.new(dest).parent.mkpath
109
- block.call src, dest
110
- end
111
- end
112
- end
113
-
114
- # Returns true if Glyph['document.output'] requires two or more conversions
115
- # @since 0.5.0
116
- def complex_output?
117
- out = Glyph['document.output']
118
- !Glyph["output.#{out}.generator"].blank? || !Glyph["output.#{out}.through"].blank?
119
- end
120
-
121
- # Returns true if the macro name is used as an alias
122
- # @param [String, Symbol] name the macro name to check
123
- def macro_alias?(name)
124
- ALIASES[:by_alias].include? name.to_sym
125
- end
126
-
127
- # Returns the name of the macro definition referenced by the supplied alias
128
- # @param [String, Symbol] name the alias name to check
129
- def macro_definition_for(name)
130
- ALIASES[:by_alias][name.to_sym]
131
- end
132
-
133
- # Returns the names of the macro aliases referencing the supplied definition
134
- # @param [String, Symbol] name the macro name to check
135
- def macro_aliases_for(name)
136
- ALIASES[:by_def][name.to_sym]
137
- end
138
-
139
- # Returns a list of macro names corresponding to sections
140
- # that commonly have a title
141
- def titled_sections
142
- (Glyph['system.structure.frontmatter']+
143
- Glyph['system.structure.bodymatter']+
144
- Glyph['system.structure.backmatter']+
145
- [:section]).uniq
146
- end
147
-
148
- # Returns true if the macro names point to the same definition
149
- # @param [String, Symbol] ident1 the first macro to compare
150
- # @param [String, Symbol] ident2 the second macro to compare
151
- def macro_eq?(ident1, ident2)
152
- Glyph::MACROS[ident1.to_sym] == Glyph::MACROS[ident2.to_sym]
153
- end
154
-
155
- # Returns true if the PROJECT constant is set to a valid Glyph project directory
156
- def project?
157
- children = ["text", "config.yml", "document.glyph"].sort
158
- actual_children = PROJECT.children.map{|c| c.basename.to_s}.sort
159
- (actual_children & children) == children
160
- end
161
-
162
- # Returns true if multiple output files are being generated
163
- def multiple_output_files?
164
- Glyph["output.#{Glyph['document.output']}.multifile"]
165
- end
166
-
167
- # Execute an external command
168
- # @since 0.5.0
169
- def run_external_command(cmd)
170
- IO.popen(cmd+" 2>&1") do |pipe|
171
- pipe.sync = true
172
- while str = pipe.gets do
173
- puts str
174
- end
175
- end
176
- end
177
-
178
- end
4
+ #@since 0.4.0
5
+ module Utils
6
+
7
+ # Prints a message
8
+ # @param [String] message the message to print
9
+ def msg(message)
10
+ puts message unless Glyph['system.quiet']
11
+ end
12
+
13
+ # Prints an informational message
14
+ # @param [String] message the message to print
15
+ def info(message)
16
+ puts "-- #{message}" unless Glyph['system.quiet']
17
+ end
18
+
19
+ # Prints a warning
20
+ # @param [String] message the message to print
21
+ def warning(message)
22
+ puts "-> warning: #{message}" unless Glyph['system.quiet']
23
+ end
24
+
25
+ # Prints an error
26
+ # @param [String] message the message to print
27
+ def error(message)
28
+ puts "=> error: #{message}" unless Glyph['system.quiet']
29
+ end
30
+
31
+ # Prints a message if running in debug mode
32
+ # @param [String] message the message to print
33
+ def debug(message)
34
+ puts message if Glyph.debug?
35
+ end
36
+
37
+ # Dumps and serialize an object to a YAML file
38
+ # @param [#to_s] file the file to write to
39
+ # @param [Object] obj the object to serialize
40
+ def yaml_dump(file, obj)
41
+ File.open(file.to_s, 'w+') {|f| f.write obj.to_yaml}
42
+ end
43
+
44
+ # Loads and deserialiaze the contents of a YAML file
45
+ # @param [#to_s] file the YAML file to load
46
+ # @return [Object] the contents of the YAML file, deserialized
47
+ def yaml_load(file)
48
+ YAML.load_file(file.to_s)
49
+ end
50
+
51
+ # Loads the contents of a file
52
+ # @param [#to_s] file the file to load
53
+ # @return [String] the contents of the file
54
+ def file_load(file)
55
+ result = ""
56
+ File.open(file.to_s, 'r:utf-8') do |f|
57
+ while l = f.gets
58
+ result << l
59
+ end
60
+ end
61
+ result
62
+ end
63
+
64
+ # Writes a string to a file
65
+ # @param [#to_s] file the file to write
66
+ # @param [String] contents the string to write
67
+ # @return [String] the string written to the file
68
+ def file_write(file, contents="")
69
+ File.open(file.to_s, 'w+:utf-8') do |f|
70
+ f.print contents
71
+ end
72
+ contents
73
+ end
74
+
75
+ # An alias for FileUtils#cp
76
+ # @param [String] source the source file
77
+ # @param [String] dest the destination file or directory
78
+ # @param [Hash] options copy options
79
+ def file_copy(source, dest, options={})
80
+ FileUtils.cp source, dest, options
81
+ end
82
+
83
+ # Loads all child elements of the given directory, matching a given extension
84
+ # @param [Pathname] dir the directory containing the files
85
+ # @param [String] extension the file extension to check
86
+ # @yield [file, contents] the file (Pathname) and its contents
87
+ # @since 0.4.0
88
+ def load_files_from_dir(dir, extension, &block)
89
+ if dir.exist? then
90
+ dir.children.each do |c|
91
+ block.call(c, file_load(c)) unless c.directory? || c.extname != extension
92
+ end
93
+ end
94
+ end
95
+
96
+ # Iterates through the files in a source directory recursively
97
+ # @param [String] dir the directory to operate on (mirrored in the output directory)
98
+ # @yield [src, dest] the source file and the corresponding output file
99
+ # @since 0.4.0
100
+ def with_files_from(dir, &block)
101
+ output = complex_output? ? 'tmp' : Glyph['document.output']
102
+ dir_path = Glyph::PROJECT/"output/#{output}/#{dir}"
103
+ dir_path.mkpath
104
+ (Glyph::PROJECT/dir).find do |i|
105
+ if i.file? then
106
+ dest = "#{Glyph::PROJECT/"output/#{output}/#{dir}"}/#{i.relative_path_from(Glyph::PROJECT/dir)}"
107
+ src = i.to_s
108
+ Pathname.new(dest).parent.mkpath
109
+ block.call src, dest
110
+ end
111
+ end
112
+ end
113
+
114
+ # Returns the value of a setting referred to the current output format
115
+ # @param [String, Symbol] the name of the setting to retrieve
116
+ # @since 0.6.0
117
+ def current_output_setting(setting)
118
+ Glyph["output.#{Glyph['document.output']}.#{setting}"]
119
+ end
120
+
121
+ # Returns true if Glyph['document.output'] requires two or more conversions
122
+ # @since 0.5.0
123
+ def complex_output?
124
+ out = Glyph['document.output']
125
+ !Glyph["output.#{out}.generator"].blank? || !Glyph["output.#{out}.through"].blank?
126
+ end
127
+
128
+ # Returns true if the macro name is used as an alias
129
+ # @param [String, Symbol] name the macro name to check
130
+ def macro_alias?(name)
131
+ ALIASES[:by_alias].include? name.to_sym
132
+ end
133
+
134
+ # Returns the name of the macro definition referenced by the supplied alias
135
+ # @param [String, Symbol] name the alias name to check
136
+ def macro_definition_for(name)
137
+ ALIASES[:by_alias][name.to_sym]
138
+ end
139
+
140
+ # Returns the names of the macro aliases referencing the supplied definition
141
+ # @param [String, Symbol] name the macro name to check
142
+ def macro_aliases_for(name)
143
+ ALIASES[:by_def][name.to_sym]
144
+ end
145
+
146
+ # Returns a list of macro names corresponding to sections
147
+ # that commonly have a title
148
+ def titled_sections
149
+ (Glyph.macro_aliases_for(:section)+
150
+ [:section]-[:frontmatter, :bodymatter, :backmatter]).uniq
151
+ end
152
+
153
+ # Returns true if the macro names point to the same definition
154
+ # @param [String, Symbol] ident1 the first macro to compare
155
+ # @param [String, Symbol] ident2 the second macro to compare
156
+ def macro_eq?(ident1, ident2)
157
+ Glyph::MACROS[ident1.to_sym] == Glyph::MACROS[ident2.to_sym]
158
+ end
159
+
160
+ # Returns true if the PROJECT constant is set to a valid Glyph project directory
161
+ def project?
162
+ children = ["text", "config.yml", "document.glyph"].sort
163
+ actual_children = PROJECT.children.map{|c| c.basename.to_s}.sort
164
+ (actual_children & children) == children
165
+ end
166
+
167
+ # Returns true if multiple output files are being generated
168
+ def multiple_output_files?
169
+ Glyph["output.#{Glyph['document.output']}.multifile"]
170
+ end
171
+
172
+ # Execute an external command
173
+ # @since 0.5.0
174
+ def run_external_command(cmd)
175
+ IO.popen(cmd+" 2>&1") do |pipe|
176
+ pipe.sync = true
177
+ while str = pipe.gets do
178
+ puts str
179
+ end
180
+ end
181
+ end
182
+
183
+ # Re-indents source code and removes unnecessary spacing
184
+ # @param [String] the XML document to clean up
185
+ # @since 0.6.0
186
+ def clean_xml_document(doc)
187
+ return doc unless current_output_setting :clean_source
188
+ begin
189
+ require 'nokogiri'
190
+ rescue Exception
191
+ warning "Cannot clean source because Nokogiri is not installed. Please run: gem install nokogiri"
192
+ return doc
193
+ end
194
+ begin
195
+ Nokogiri.XML(doc.to_s, &:noblanks).to_xml :indent => 2
196
+ rescue Exception => e
197
+ warning "Unable to clean up source"
198
+ debug e.message
199
+ debug e.backtrace.join("\n")
200
+ doc
201
+ end
202
+ end
203
+ end
179
204
  end