glyph 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (162) hide show
  1. data/.gitignore +7 -0
  2. data/AUTHORS.textile +8 -7
  3. data/CHANGELOG.textile +89 -8
  4. data/LICENSE.textile +1 -2
  5. data/README.textile +89 -61
  6. data/Rakefile +12 -10
  7. data/VERSION +1 -1
  8. data/benchmark.rb +1 -1
  9. data/book/config.yml +18 -4
  10. data/book/document.glyph +269 -45
  11. data/book/images/glyph/commands_tasks.png +0 -0
  12. data/book/images/{document_generation.png → glyph/document_generation.png} +0 -0
  13. data/book/images/glyph/glyph.eps +123 -0
  14. data/book/images/glyph/glyph.png +0 -0
  15. data/book/images/glyph/glyph.svg +29 -0
  16. data/book/lib/commands/commands.rb +11 -0
  17. data/book/lib/layouts/bookindex.glyph +127 -0
  18. data/book/lib/layouts/bookpage.glyph +129 -0
  19. data/book/lib/layouts/project.glyph +26 -0
  20. data/book/lib/macros/reference.rb +27 -7
  21. data/book/lib/tasks/tasks.rake +52 -0
  22. data/book/snippets.yml +1 -1
  23. data/book/text/{acknowledgement.glyph → acknowledgements.glyph} +4 -2
  24. data/book/text/changelog.glyph +29 -3
  25. data/book/text/compiling/compiling.glyph +44 -20
  26. data/book/text/compiling/lite_mode.glyph +0 -4
  27. data/book/text/compiling/programmatic_usage.glyph +1 -5
  28. data/book/text/config/document.glyph +35 -0
  29. data/book/text/config/filters.glyph +28 -0
  30. data/book/text/config/options.glyph +25 -0
  31. data/book/text/config/output.glyph +83 -0
  32. data/book/text/extending/bookmarks_headers.glyph +0 -5
  33. data/book/text/extending/command.glyph +56 -0
  34. data/book/text/extending/commands_tasks.glyph +39 -0
  35. data/book/text/extending/further_reading.glyph +0 -3
  36. data/book/text/extending/internals.glyph +3 -5
  37. data/book/text/extending/interpreting.glyph +0 -4
  38. data/book/text/extending/layouts.glyph +68 -0
  39. data/book/text/extending/macro_def.glyph +0 -5
  40. data/book/text/extending/output_format.glyph +78 -0
  41. data/book/text/extending/params_attrs.glyph +0 -3
  42. data/book/text/extending/placeholders.glyph +0 -4
  43. data/book/text/extending/task.glyph +46 -0
  44. data/book/text/extending/validators.glyph +5 -6
  45. data/book/text/getting_started/configuration.glyph +1 -5
  46. data/book/text/getting_started/create_project.glyph +1 -5
  47. data/book/text/getting_started/structure.glyph +0 -4
  48. data/book/text/introduction.glyph +100 -75
  49. data/book/text/license.glyph +1 -2
  50. data/book/text/macros/macros_block.glyph +8 -4
  51. data/book/text/macros/macros_core.glyph +0 -3
  52. data/book/text/macros/macros_filters.glyph +2 -7
  53. data/book/text/macros/macros_inline.glyph +0 -4
  54. data/book/text/macros/macros_structure.glyph +0 -4
  55. data/book/text/ref_commands.glyph +29 -7
  56. data/book/text/stats/bookmarks.glyph +49 -0
  57. data/book/text/stats/links.glyph +90 -0
  58. data/book/text/stats/macros.glyph +73 -0
  59. data/book/text/stats/snippets.glyph +50 -0
  60. data/book/text/stats/stats.glyph +79 -0
  61. data/book/text/text_editing/attribute_intro.glyph +22 -0
  62. data/book/text/text_editing/code.glyph +0 -5
  63. data/book/text/text_editing/conditionals.glyph +0 -4
  64. data/book/text/text_editing/esc_quot.glyph +64 -0
  65. data/book/text/text_editing/evaluation.glyph +0 -3
  66. data/book/text/text_editing/glyph_files.glyph +0 -3
  67. data/book/text/text_editing/images.glyph +0 -5
  68. data/book/text/text_editing/inclusions.glyph +0 -4
  69. data/book/text/text_editing/links.glyph +2 -7
  70. data/book/text/text_editing/macro_intro.glyph +1 -98
  71. data/book/text/text_editing/raw_html.glyph +0 -87
  72. data/book/text/text_editing/section_aliases.glyph +28 -0
  73. data/book/text/text_editing/sections.glyph +1 -32
  74. data/book/text/text_editing/stylesheets.glyph +3 -5
  75. data/book/text/text_editing/topics.glyph +33 -0
  76. data/book/text/text_editing/xml_fallback.glyph +73 -0
  77. data/book/text/troubleshooting/errors_command.glyph +0 -3
  78. data/book/text/troubleshooting/errors_generic.glyph +21 -6
  79. data/book/text/troubleshooting/errors_macro.glyph +11 -8
  80. data/book/text/troubleshooting/errors_parser.glyph +0 -3
  81. data/config.yml +60 -25
  82. data/glyph.gemspec +90 -36
  83. data/layouts/web/index.glyph +16 -0
  84. data/layouts/web/topic.glyph +15 -0
  85. data/layouts/web5/index.glyph +16 -0
  86. data/layouts/web5/topic.glyph +17 -0
  87. data/lib/glyph.rb +36 -49
  88. data/lib/glyph/analyzer.rb +253 -0
  89. data/lib/glyph/bookmark.rb +92 -0
  90. data/lib/glyph/commands.rb +9 -221
  91. data/lib/glyph/commands/add.rb +8 -0
  92. data/lib/glyph/commands/compile.rb +93 -0
  93. data/lib/glyph/commands/config.rb +38 -0
  94. data/lib/glyph/commands/init.rb +6 -0
  95. data/lib/glyph/commands/outline.rb +45 -0
  96. data/lib/glyph/commands/stats.rb +48 -0
  97. data/lib/glyph/commands/todo.rb +29 -0
  98. data/lib/glyph/config.rb +2 -0
  99. data/lib/glyph/document.rb +61 -30
  100. data/lib/glyph/interpreter.rb +2 -2
  101. data/lib/glyph/macro.rb +14 -5
  102. data/lib/glyph/macro_helpers.rb +280 -0
  103. data/lib/glyph/macro_validators.rb +37 -2
  104. data/lib/glyph/reporter.rb +182 -0
  105. data/lib/glyph/syntax_node.rb +37 -10
  106. data/lib/glyph/system_extensions.rb +8 -45
  107. data/lib/glyph/utils.rb +148 -0
  108. data/macros/core.rb +10 -15
  109. data/macros/filters.rb +4 -5
  110. data/macros/html/block.rb +46 -30
  111. data/macros/html/inline.rb +9 -35
  112. data/macros/html/structure.rb +59 -72
  113. data/macros/html5/block.rb +69 -0
  114. data/macros/html5/inline.rb +24 -0
  115. data/macros/html5/structure.rb +139 -0
  116. data/macros/xml.rb +1 -1
  117. data/spec/files/custom_command.rb +6 -0
  118. data/spec/files/custom_tasks.rake +6 -0
  119. data/spec/files/document_for_stats.glyph +12 -0
  120. data/spec/files/references.glyph +4 -0
  121. data/spec/files/web1.glyph +11 -0
  122. data/spec/files/web2.glyph +10 -0
  123. data/spec/files/web_doc.glyph +23 -0
  124. data/spec/lib/analyzer_spec.rb +137 -0
  125. data/spec/lib/bookmark_spec.rb +64 -0
  126. data/spec/lib/commands_spec.rb +30 -5
  127. data/spec/lib/document_spec.rb +49 -9
  128. data/spec/lib/glyph_spec.rb +21 -1
  129. data/spec/lib/macro_spec.rb +6 -6
  130. data/spec/lib/macro_validators_spec.rb +24 -0
  131. data/spec/lib/reporter_spec.rb +132 -0
  132. data/spec/macros/core_spec.rb +2 -3
  133. data/spec/macros/filters_spec.rb +2 -2
  134. data/spec/macros/html5_spec.rb +101 -0
  135. data/spec/macros/macros_spec.rb +16 -6
  136. data/spec/macros/web5_spec.rb +32 -0
  137. data/spec/macros/web_spec.rb +59 -0
  138. data/spec/macros/xml_spec.rb +1 -1
  139. data/spec/spec_helper.rb +24 -4
  140. data/spec/tasks/generate_spec.rb +54 -0
  141. data/spec/tasks/load_spec.rb +29 -3
  142. data/spec/tasks/project_spec.rb +21 -3
  143. data/styles/default.css +40 -4
  144. data/styles/pagination.css +59 -41
  145. data/tasks/generate.rake +110 -31
  146. data/tasks/load.rake +39 -7
  147. data/tasks/project.rake +9 -7
  148. metadata +115 -34
  149. data/book/images/glyph.png +0 -0
  150. data/book/images/glyph.svg +0 -351
  151. data/book/output/html/glyph.html +0 -4482
  152. data/book/output/html/images/document_generation.png +0 -0
  153. data/book/output/html/images/glyph.png +0 -0
  154. data/book/output/html/images/glyph.svg +0 -351
  155. data/book/output/pdf/glyph.pdf +4 -10254
  156. data/book/script/authors +0 -1
  157. data/book/script/changelog +0 -1
  158. data/book/script/license +0 -1
  159. data/book/script/readme +0 -1
  160. data/book/text/ref_config.glyph +0 -100
  161. data/book/text/ref_macros.glyph +0 -6
  162. data/book/text/troubleshooting/errors_intro.glyph +0 -3
@@ -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