glyph 0.5.1 → 0.5.2

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 (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