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
@@ -77,6 +77,18 @@ module Glyph
77
77
  end
78
78
  end
79
79
 
80
+ # Ensures that the macro receives the specified attribute
81
+ # @param [String, Symbol] name the name of the attribute
82
+ # @param [Hash] options a hash containing validation options
83
+ # @option options :level the error level (:error, :warning)
84
+ # @return [Boolean] whether the validation passed or not
85
+ # @since 0.4.0
86
+ def required_attribute(name, options={:level=>:error})
87
+ validate("Macro '#{@name}' requires a '#{name}' attribute", options) do
88
+ !raw_attribute(name.to_sym).blank?
89
+ end
90
+ end
91
+
80
92
  # Ensures that the macro receives no parameters.
81
93
  # @param [Hash] options a hash containing validation options
82
94
  # @option options :level the error level (:error, :warning)
@@ -133,8 +145,31 @@ module Glyph
133
145
  macro_error "Mutual Inclusion in #{check_type}(#{arg}): '#{check_value}'", Glyph::MutualInclusionError
134
146
  end
135
147
  end
136
- end
137
148
 
138
- end
149
+ # Ensure that the macros is within another
150
+ # @param [String, Symbol] arg the name of the container macro
151
+ # @param [Hash] options a hash containing validation options
152
+ # @option options :level the error level (:error, :warning)
153
+ # @return [Boolean] whether the validation passed or not
154
+ # @since 0.4.0
155
+ def within(arg, options={:level => :error})
156
+ validate("Macro '#{@name}' must be within a '#{arg}' macro", options) do
157
+ @node.find_parent {|n| Glyph.macro_eq? arg.to_sym, n[:name]}
158
+ end
159
+ end
160
+
161
+ # Ensure that the macros is _not_ within another
162
+ # @param [String, Symbol] arg the name of the container macro
163
+ # @param [Hash] options a hash containing validation options
164
+ # @option options :level the error level (:error, :warning)
165
+ # @return [Boolean] whether the validation passed or not
166
+ # @since 0.4.0
167
+ def not_within(arg, options={:level => :error})
168
+ validate("Macro '#{@name}' must not be within a '#{arg}' macro", options) do
169
+ !@node.find_parent {|n| Glyph.macro_eq? arg.to_sym, n[:name]}
170
+ end
171
+ end
139
172
 
173
+ end
174
+ end
140
175
  end
@@ -0,0 +1,182 @@
1
+ module Glyph
2
+
3
+ # This class is used to display statistics collected by a Glyph::Analyzer.
4
+ # @since 0.4.0
5
+ class Reporter
6
+
7
+ include Glyph::Utils
8
+
9
+ attr_accessor :detailed
10
+
11
+ # Initializes the reporter
12
+ # @param [Hash] stats the collected statistics
13
+ def initialize(stats)
14
+ @stats = stats
15
+ @detailed = true
16
+ end
17
+
18
+ # Displays the statistics
19
+ def display
20
+ [:files, :macros, :snippets, :bookmarks, :links,
21
+ :macro, :snippet, :bookmark, :link].each do |s|
22
+ unless @stats[s].blank? then
23
+ send :"display_#{s}"
24
+ puts
25
+ end
26
+ end
27
+ end
28
+
29
+ protected
30
+
31
+ def display_macros
32
+ s = @stats[:macros]
33
+ section :macros
34
+ total :macro_instances, s[:instances].length
35
+ total :macro_definitions, s[:definitions].length
36
+ total :macro_aliases, s[:aliases].length
37
+ total :used_macro_definitions, s[:used_definitions].length
38
+ if @detailed then
39
+ inline_list :macro_definitions, s[:definitions]
40
+ inline_list :used_macro_definitions, s[:used_definitions]
41
+ end
42
+ end
43
+
44
+ def display_macro
45
+ s = @stats[:macro]
46
+ alias_for = s[:alias_for] ? " (alias for: #{s[:alias_for]})" : " "
47
+ section "Macro '#{s[:param]}'#{alias_for}"
48
+ total :instances, s[:instances].length
49
+ occurrences s[:files] if @detailed
50
+ end
51
+
52
+ def display_bookmarks
53
+ s = @stats[:bookmarks]
54
+ section :bookmarks
55
+ total :bookmarks, s[:codes].length
56
+ total :referenced_bookmarks, s[:referenced].length
57
+ total :unreferenced_bookmarks, s[:unreferenced].length
58
+ if @detailed then
59
+ inline_list :bookmarks, s[:codes]
60
+ occurrences s[:referenced], "Referenced Bookmarks:"
61
+ inline_list :unreferenced_bookmarks, s[:unreferenced]
62
+ end
63
+ end
64
+
65
+ def display_bookmark
66
+ s = @stats[:bookmark]
67
+ b_type = (s[:type] != :bookmark) ? " (#{s[:type]})" : " "
68
+ section "Bookmark '#{s[:param]}'#{b_type}"
69
+ if s[:file] == s[:definition] then
70
+ info "Defined in: #{s[:file]}"
71
+ else
72
+ info "Defined in: #{s[:definition]} (pointing to: #{s[:file]})"
73
+ end
74
+ occurrences s[:references], "Referenced in:" if @detailed
75
+ end
76
+
77
+ def display_snippets
78
+ s = @stats[:snippets]
79
+ section :snippets
80
+ total :snippets, s[:definitions].length
81
+ total :used_snippets, s[:used].length
82
+ total :unused_snippets, s[:unused].length
83
+ if @detailed then
84
+ inline_list :snippets, s[:definitions]
85
+ inline_list :used_snippets, s[:used]
86
+ inline_list :unused_snippets, s[:unused]
87
+ end
88
+ end
89
+
90
+ def display_snippet
91
+ s = @stats[:snippet]
92
+ section "Snippet '#{s[:param]}'"
93
+ info "Definition:"
94
+ puts "-------------------"
95
+ puts SNIPPETS[s[:param]]
96
+ puts "-------------------"
97
+ total :used_instances, s[:stats][:total]
98
+ occurrences s[:stats][:files], "Usage Details:" if @detailed
99
+ end
100
+
101
+ def display_links
102
+ s = @stats[:links]
103
+ section :links
104
+ total :internal_links, s[:internal].length
105
+ occurrences s[:internal], "Internal Links" if @detailed
106
+ total :external_links, s[:external].length
107
+ occurrences s[:external], "External Links" if @detailed
108
+ end
109
+
110
+ def display_link
111
+ s = @stats[:link]
112
+ section "Links matching /#{s[:param]}/"
113
+ total :links, s[:stats].length
114
+ occurrences s[:stats], "Link Targets:"
115
+ grouped_occurrences s[:stats], "Details:" if @detailed
116
+ end
117
+
118
+ def display_files
119
+ s = @stats[:files]
120
+ section :files
121
+ total :files, s.values.inject{|sum, n| sum+n}
122
+ total "/text --", s[:text]
123
+ total "/images --", s[:images]
124
+ total "/styles --", s[:styles]
125
+ total "/layouts --", s[:layouts]
126
+ total "/lib --", s[:lib]
127
+ end
128
+
129
+
130
+ private
131
+
132
+ def total(objects, total)
133
+ label = objects.is_a?(Symbol) ? "Total #{objects.to_s.title_case}:" : objects
134
+ info "#{label} #{total}"
135
+ end
136
+
137
+ def section(name)
138
+ puts "===== #{(name.is_a? Symbol) ? name.to_s.title_case : name}"
139
+ end
140
+
141
+ def inline_list(name, arr)
142
+ return if arr.blank?
143
+ label = name.to_s.title_case
144
+ columns = 5
145
+ max = arr.map{|e| e.to_s.length}.max
146
+ if arr.length < columns+1 then
147
+ info "#{label}: #{arr.join(', ')}"
148
+ else
149
+ info "#{label}:"
150
+ count = 0
151
+ arr.each do |i|
152
+ print " " if count%columns == 0
153
+ print "#{i}#{' '*(max-i.to_s.length+1)}"
154
+ print "\n" if count%columns == 4
155
+ count +=1
156
+ end
157
+ puts
158
+ end
159
+ end
160
+
161
+ def occurrences(arr, label="Occurrences:")
162
+ return if arr.blank?
163
+ info label
164
+ arr.each do |f|
165
+ total = f[1].is_a?(Numeric) ? "(#{f[1]})" : ""
166
+ puts " - #{f[0]} #{total}"
167
+ end
168
+ end
169
+
170
+ def grouped_occurrences(arr, label="Details:")
171
+ return if arr.blank?
172
+ info label
173
+ arr.each do |f|
174
+ puts " - #{f[0]} (#{f[1][:total]})"
175
+ f[1][:files].each do |i|
176
+ puts " - #{i[0]} (#{i[1]})"
177
+ end
178
+ end
179
+ end
180
+
181
+ end
182
+ end
@@ -11,6 +11,18 @@ module Glyph
11
11
  ""
12
12
  end
13
13
 
14
+ # @return [String] a textual representation of self
15
+ # @since 0.4.0
16
+ def inspect
17
+ string = ""
18
+ descend do |e, level|
19
+ # Remove document key to avoid endless resursion
20
+ hash = e.to_hash.reject{|k,v| k == :document}
21
+ string << " "*level+"(#{e.class})"+hash.inspect+"\n"
22
+ end
23
+ string.chomp
24
+ end
25
+
14
26
  # @return [String] the value of the :value key
15
27
  # @since 0.3.0
16
28
  def evaluate(context, options={})
@@ -49,7 +61,7 @@ module Glyph
49
61
  e = self[:escape] ? "=" : ""
50
62
  "#{self[:name]}["+e+attributes.join+parameters.join("|")+e+"]"
51
63
  end
52
-
64
+
53
65
  # Expands the macro
54
66
  # @return [String] the value of the macro
55
67
  # @since 0.3.0
@@ -63,7 +75,16 @@ module Glyph
63
75
  children.select{|n| n.is_a? ParameterNode }
64
76
  end
65
77
 
66
- #
78
+ # @return [Array<Glyph::MacroNode>] an array of the child macro nodes
79
+ # @since 0.4.0
80
+ def child_macros
81
+ macros = []
82
+ parameters.each do |p|
83
+ macros += p.children.select{|n| n.is_a? MacroNode }
84
+ end
85
+ macros
86
+ end
87
+
67
88
  # Returns the parameter syntax node at the specified index
68
89
  # @param [Fixnum] n the index of the parameter
69
90
  # @return [Glyph::ParameterNode, nil] a parameter node
@@ -103,15 +124,21 @@ module Glyph
103
124
  # @since 0.3.0
104
125
  def expand(context)
105
126
  xml_element(context)
106
- self.merge!({
107
- :source => context[:source],
108
- :document => context[:document],
109
- :info => context[:info],
110
- :value => ""
111
- })
127
+ self[:source] = context[:source]
128
+ self[:document] = context[:document]
129
+ self[:info] = context[:info]
130
+ self[:value] = ""
112
131
  Glyph::Macro.new(self).expand
113
132
  end
114
133
 
134
+ # Returns where the macro was used (used in Glyph::Analyzer)
135
+ # @since 0.4.0
136
+ def source
137
+ s = self[:source][:file] rescue nil
138
+ s ||= self[:source][:name] rescue nil
139
+ s
140
+ end
141
+
115
142
  protected
116
143
 
117
144
  def xml_element(context)
@@ -123,11 +150,11 @@ module Glyph
123
150
  end
124
151
  case
125
152
  # Use XML syntax
126
- when Glyph['language.set'] == 'xml' then
153
+ when Glyph['options.macro_set'] == 'xml' then
127
154
  self[:element] = name
128
155
  self[:name] = :"|xml|"
129
156
  # Fallback to XML syntax
130
- when Glyph['language.options.xml_fallback'] then
157
+ when Glyph["options.xml_fallback"] then
131
158
  unless known_macro then
132
159
  self[:element] = name
133
160
  self[:fallback] = true
@@ -1,49 +1,12 @@
1
- module Kernel
2
-
3
- # Dumps and serialize an object to a YAML file
4
- # @param [#to_s] file the file to write to
5
- # @param [Object] obj the object to serialize
6
- def yaml_dump(file, obj)
7
- File.open(file.to_s, 'w+') {|f| f.write obj.to_yaml}
8
- end
9
-
10
- # Loads and deserialiaze the contents of a YAML file
11
- # @param [#to_s] file the YAML file to load
12
- # @return [Object] the contents of the YAML file, deserialized
13
- def yaml_load(file)
14
- YAML.load_file(file.to_s)
15
- end
16
-
17
- # Loads the contents of a file
18
- # @param [#to_s] file the file to load
19
- # @return [String] the contents of the file
20
- def file_load(file)
21
- result = ""
22
- File.open(file.to_s, 'r') do |f|
23
- while l = f.gets
24
- result << l
25
- end
26
- end
27
- result
28
- end
29
-
30
- # Writes a string to a file
31
- # @param [#to_s] file the file to write
32
- # @param [String] contents the string to write
33
- # @return [String] the string written to the file
34
- def file_write(file, contents="")
35
- File.open(file.to_s, 'w+') do |f|
36
- f.print contents
37
- end
38
- contents
1
+ class Symbol
2
+ def <=>(b)
3
+ self.to_s <=> b.to_s
39
4
  end
5
+ end
40
6
 
41
- # An alias for FileUtils#cp
42
- # @param [String] source the source file
43
- # @param [String] dest the destination file or directory
44
- # @param [Hash] options copy options
45
- def file_copy(source, dest, options={})
46
- FileUtils.cp source, dest, options
7
+ class String
8
+ def title_case
9
+ self.snake_case.split('_').map{|s| s.capitalize}.join(' ')
47
10
  end
48
-
49
11
  end
12
+
@@ -0,0 +1,148 @@
1
+ module Glyph
2
+ #@since 0.4.0
3
+ module Utils
4
+
5
+ # Prints a message
6
+ # @param [String] message the message to print
7
+ def msg(message)
8
+ puts message unless Glyph['system.quiet']
9
+ end
10
+
11
+ # Prints an informational message
12
+ # @param [String] message the message to print
13
+ def info(message)
14
+ puts "-- #{message}" unless Glyph['system.quiet']
15
+ end
16
+
17
+ # Prints a warning
18
+ # @param [String] message the message to print
19
+ def warning(message)
20
+ puts "-> warning: #{message}" unless Glyph['system.quiet']
21
+ end
22
+
23
+ # Prints an error
24
+ # @param [String] message the message to print
25
+ def error(message)
26
+ puts "=> error: #{message}" unless Glyph['system.quiet']
27
+ end
28
+
29
+ # Prints a message if running in debug mode
30
+ # @param [String] message the message to print
31
+ def debug(message)
32
+ puts message if Glyph.debug?
33
+ end
34
+
35
+ # Dumps and serialize an object to a YAML file
36
+ # @param [#to_s] file the file to write to
37
+ # @param [Object] obj the object to serialize
38
+ def yaml_dump(file, obj)
39
+ File.open(file.to_s, 'w+') {|f| f.write obj.to_yaml}
40
+ end
41
+
42
+ # Loads and deserialiaze the contents of a YAML file
43
+ # @param [#to_s] file the YAML file to load
44
+ # @return [Object] the contents of the YAML file, deserialized
45
+ def yaml_load(file)
46
+ YAML.load_file(file.to_s)
47
+ end
48
+
49
+ # Loads the contents of a file
50
+ # @param [#to_s] file the file to load
51
+ # @return [String] the contents of the file
52
+ def file_load(file)
53
+ result = ""
54
+ File.open(file.to_s, 'r') do |f|
55
+ while l = f.gets
56
+ result << l
57
+ end
58
+ end
59
+ result
60
+ end
61
+
62
+ # Writes a string to a file
63
+ # @param [#to_s] file the file to write
64
+ # @param [String] contents the string to write
65
+ # @return [String] the string written to the file
66
+ def file_write(file, contents="")
67
+ File.open(file.to_s, 'w+') do |f|
68
+ f.print contents
69
+ end
70
+ contents
71
+ end
72
+
73
+ # An alias for FileUtils#cp
74
+ # @param [String] source the source file
75
+ # @param [String] dest the destination file or directory
76
+ # @param [Hash] options copy options
77
+ def file_copy(source, dest, options={})
78
+ FileUtils.cp source, dest, options
79
+ end
80
+
81
+ # Loads all child elements of the given directory, matching a given extension
82
+ # @param [Pathname] dir the directory containing the files
83
+ # @param [String] extension the file extension to check
84
+ # @yield [file, contents] the file (Pathname) and its contents
85
+ # @since 0.4.0
86
+ def load_files_from_dir(dir, extension, &block)
87
+ if dir.exist? then
88
+ dir.children.each do |c|
89
+ block.call(c, file_load(c)) unless c.directory? || c.extname != extension
90
+ end
91
+ end
92
+ end
93
+
94
+ # Iterates through the files in a source directory recursively
95
+ # @param [String] dir the directory to operate on (mirrored in the output directory)
96
+ # @yield [src, dest] the source file and the corresponding output file
97
+ # @since 0.4.0
98
+ def with_files_from(dir, &block)
99
+ output = (Glyph['document.output'] == 'pdf') ? 'html' : Glyph['document.output']
100
+ dir_path = Glyph::PROJECT/"output/#{output}/#{dir}"
101
+ dir_path.mkpath
102
+ (Glyph::PROJECT/dir).find do |i|
103
+ if i.file? then
104
+ dest = "#{Glyph::PROJECT/"output/#{output}/#{dir}"}/#{i.relative_path_from(Glyph::PROJECT/dir)}"
105
+ src = i.to_s
106
+ Pathname.new(dest).parent.mkpath
107
+ block.call src, dest
108
+ end
109
+ end
110
+ end
111
+
112
+ # Returns true if the macro name is used as an alias
113
+ # @param [String, Symbol] name the macro name to check
114
+ def macro_alias?(name)
115
+ ALIASES[:by_alias].include? name.to_sym
116
+ end
117
+
118
+ # Returns the name of the macro definition referenced by the supplied alias
119
+ # @param [String, Symbol] name the alias name to check
120
+ def macro_definition_for(name)
121
+ ALIASES[:by_alias][name.to_sym]
122
+ end
123
+
124
+ def macro_aliases_for(name)
125
+ ALIASES[:by_def][name.to_sym]
126
+ end
127
+
128
+ # Returns true if the macro names point to the same definition
129
+ # @param [String, Symbol] ident1 the first macro to compare
130
+ # @param [String, Symbol] ident2 the second macro to compare
131
+ def macro_eq?(ident1, ident2)
132
+ Glyph::MACROS[ident1.to_sym] == Glyph::MACROS[ident2.to_sym]
133
+ end
134
+
135
+ # Returns true if the PROJECT constant is set to a valid Glyph project directory
136
+ def project?
137
+ children = ["text", "snippets.yml", "config.yml", "document.glyph"].sort
138
+ actual_children = PROJECT.children.map{|c| c.basename.to_s}.sort
139
+ (actual_children & children) == children
140
+ end
141
+
142
+ # Returns true if multiple output files are being generated
143
+ def multiple_output_files?
144
+ Glyph["output.#{Glyph['document.output']}.multifile"]
145
+ end
146
+
147
+ end
148
+ end