glyph 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/AUTHORS.textile +8 -7
- data/CHANGELOG.textile +89 -8
- data/LICENSE.textile +1 -2
- data/README.textile +89 -61
- data/Rakefile +12 -10
- data/VERSION +1 -1
- data/benchmark.rb +1 -1
- data/book/config.yml +18 -4
- data/book/document.glyph +269 -45
- data/book/images/glyph/commands_tasks.png +0 -0
- data/book/images/{document_generation.png → glyph/document_generation.png} +0 -0
- data/book/images/glyph/glyph.eps +123 -0
- data/book/images/glyph/glyph.png +0 -0
- data/book/images/glyph/glyph.svg +29 -0
- data/book/lib/commands/commands.rb +11 -0
- data/book/lib/layouts/bookindex.glyph +127 -0
- data/book/lib/layouts/bookpage.glyph +129 -0
- data/book/lib/layouts/project.glyph +26 -0
- data/book/lib/macros/reference.rb +27 -7
- data/book/lib/tasks/tasks.rake +52 -0
- data/book/snippets.yml +1 -1
- data/book/text/{acknowledgement.glyph → acknowledgements.glyph} +4 -2
- data/book/text/changelog.glyph +29 -3
- data/book/text/compiling/compiling.glyph +44 -20
- data/book/text/compiling/lite_mode.glyph +0 -4
- data/book/text/compiling/programmatic_usage.glyph +1 -5
- data/book/text/config/document.glyph +35 -0
- data/book/text/config/filters.glyph +28 -0
- data/book/text/config/options.glyph +25 -0
- data/book/text/config/output.glyph +83 -0
- data/book/text/extending/bookmarks_headers.glyph +0 -5
- data/book/text/extending/command.glyph +56 -0
- data/book/text/extending/commands_tasks.glyph +39 -0
- data/book/text/extending/further_reading.glyph +0 -3
- data/book/text/extending/internals.glyph +3 -5
- data/book/text/extending/interpreting.glyph +0 -4
- data/book/text/extending/layouts.glyph +68 -0
- data/book/text/extending/macro_def.glyph +0 -5
- data/book/text/extending/output_format.glyph +78 -0
- data/book/text/extending/params_attrs.glyph +0 -3
- data/book/text/extending/placeholders.glyph +0 -4
- data/book/text/extending/task.glyph +46 -0
- data/book/text/extending/validators.glyph +5 -6
- data/book/text/getting_started/configuration.glyph +1 -5
- data/book/text/getting_started/create_project.glyph +1 -5
- data/book/text/getting_started/structure.glyph +0 -4
- data/book/text/introduction.glyph +100 -75
- data/book/text/license.glyph +1 -2
- data/book/text/macros/macros_block.glyph +8 -4
- data/book/text/macros/macros_core.glyph +0 -3
- data/book/text/macros/macros_filters.glyph +2 -7
- data/book/text/macros/macros_inline.glyph +0 -4
- data/book/text/macros/macros_structure.glyph +0 -4
- data/book/text/ref_commands.glyph +29 -7
- data/book/text/stats/bookmarks.glyph +49 -0
- data/book/text/stats/links.glyph +90 -0
- data/book/text/stats/macros.glyph +73 -0
- data/book/text/stats/snippets.glyph +50 -0
- data/book/text/stats/stats.glyph +79 -0
- data/book/text/text_editing/attribute_intro.glyph +22 -0
- data/book/text/text_editing/code.glyph +0 -5
- data/book/text/text_editing/conditionals.glyph +0 -4
- data/book/text/text_editing/esc_quot.glyph +64 -0
- data/book/text/text_editing/evaluation.glyph +0 -3
- data/book/text/text_editing/glyph_files.glyph +0 -3
- data/book/text/text_editing/images.glyph +0 -5
- data/book/text/text_editing/inclusions.glyph +0 -4
- data/book/text/text_editing/links.glyph +2 -7
- data/book/text/text_editing/macro_intro.glyph +1 -98
- data/book/text/text_editing/raw_html.glyph +0 -87
- data/book/text/text_editing/section_aliases.glyph +28 -0
- data/book/text/text_editing/sections.glyph +1 -32
- data/book/text/text_editing/stylesheets.glyph +3 -5
- data/book/text/text_editing/topics.glyph +33 -0
- data/book/text/text_editing/xml_fallback.glyph +73 -0
- data/book/text/troubleshooting/errors_command.glyph +0 -3
- data/book/text/troubleshooting/errors_generic.glyph +21 -6
- data/book/text/troubleshooting/errors_macro.glyph +11 -8
- data/book/text/troubleshooting/errors_parser.glyph +0 -3
- data/config.yml +60 -25
- data/glyph.gemspec +90 -36
- data/layouts/web/index.glyph +16 -0
- data/layouts/web/topic.glyph +15 -0
- data/layouts/web5/index.glyph +16 -0
- data/layouts/web5/topic.glyph +17 -0
- data/lib/glyph.rb +36 -49
- data/lib/glyph/analyzer.rb +253 -0
- data/lib/glyph/bookmark.rb +92 -0
- data/lib/glyph/commands.rb +9 -221
- data/lib/glyph/commands/add.rb +8 -0
- data/lib/glyph/commands/compile.rb +93 -0
- data/lib/glyph/commands/config.rb +38 -0
- data/lib/glyph/commands/init.rb +6 -0
- data/lib/glyph/commands/outline.rb +45 -0
- data/lib/glyph/commands/stats.rb +48 -0
- data/lib/glyph/commands/todo.rb +29 -0
- data/lib/glyph/config.rb +2 -0
- data/lib/glyph/document.rb +61 -30
- data/lib/glyph/interpreter.rb +2 -2
- data/lib/glyph/macro.rb +14 -5
- data/lib/glyph/macro_helpers.rb +280 -0
- data/lib/glyph/macro_validators.rb +37 -2
- data/lib/glyph/reporter.rb +182 -0
- data/lib/glyph/syntax_node.rb +37 -10
- data/lib/glyph/system_extensions.rb +8 -45
- data/lib/glyph/utils.rb +148 -0
- data/macros/core.rb +10 -15
- data/macros/filters.rb +4 -5
- data/macros/html/block.rb +46 -30
- data/macros/html/inline.rb +9 -35
- data/macros/html/structure.rb +59 -72
- data/macros/html5/block.rb +69 -0
- data/macros/html5/inline.rb +24 -0
- data/macros/html5/structure.rb +139 -0
- data/macros/xml.rb +1 -1
- data/spec/files/custom_command.rb +6 -0
- data/spec/files/custom_tasks.rake +6 -0
- data/spec/files/document_for_stats.glyph +12 -0
- data/spec/files/references.glyph +4 -0
- data/spec/files/web1.glyph +11 -0
- data/spec/files/web2.glyph +10 -0
- data/spec/files/web_doc.glyph +23 -0
- data/spec/lib/analyzer_spec.rb +137 -0
- data/spec/lib/bookmark_spec.rb +64 -0
- data/spec/lib/commands_spec.rb +30 -5
- data/spec/lib/document_spec.rb +49 -9
- data/spec/lib/glyph_spec.rb +21 -1
- data/spec/lib/macro_spec.rb +6 -6
- data/spec/lib/macro_validators_spec.rb +24 -0
- data/spec/lib/reporter_spec.rb +132 -0
- data/spec/macros/core_spec.rb +2 -3
- data/spec/macros/filters_spec.rb +2 -2
- data/spec/macros/html5_spec.rb +101 -0
- data/spec/macros/macros_spec.rb +16 -6
- data/spec/macros/web5_spec.rb +32 -0
- data/spec/macros/web_spec.rb +59 -0
- data/spec/macros/xml_spec.rb +1 -1
- data/spec/spec_helper.rb +24 -4
- data/spec/tasks/generate_spec.rb +54 -0
- data/spec/tasks/load_spec.rb +29 -3
- data/spec/tasks/project_spec.rb +21 -3
- data/styles/default.css +40 -4
- data/styles/pagination.css +59 -41
- data/tasks/generate.rake +110 -31
- data/tasks/load.rake +39 -7
- data/tasks/project.rake +9 -7
- metadata +115 -34
- data/book/images/glyph.png +0 -0
- data/book/images/glyph.svg +0 -351
- data/book/output/html/glyph.html +0 -4482
- data/book/output/html/images/document_generation.png +0 -0
- data/book/output/html/images/glyph.png +0 -0
- data/book/output/html/images/glyph.svg +0 -351
- data/book/output/pdf/glyph.pdf +4 -10254
- data/book/script/authors +0 -1
- data/book/script/changelog +0 -1
- data/book/script/license +0 -1
- data/book/script/readme +0 -1
- data/book/text/ref_config.glyph +0 -100
- data/book/text/ref_macros.glyph +0 -6
- data/book/text/troubleshooting/errors_intro.glyph +0 -3
data/lib/glyph.rb
CHANGED
@@ -25,18 +25,25 @@ module Glyph
|
|
25
25
|
TASKS_DIR = Pathname(__FILE__).dirname.expand_path/'../tasks'
|
26
26
|
|
27
27
|
require LIB/'system_extensions'
|
28
|
+
require LIB/'utils'
|
28
29
|
require LIB/'config'
|
29
30
|
require LIB/'node'
|
31
|
+
require LIB/'bookmark'
|
30
32
|
require LIB/'document'
|
31
33
|
require LIB/'macro_validators'
|
34
|
+
require LIB/'macro_helpers'
|
32
35
|
require LIB/'macro'
|
33
36
|
require LIB/'syntax_node'
|
34
37
|
require LIB/'parser'
|
35
38
|
require LIB/'interpreter'
|
39
|
+
require LIB/'analyzer'
|
40
|
+
require LIB/'reporter'
|
41
|
+
extend Glyph::Utils
|
36
42
|
|
37
43
|
class Error < RuntimeError; end
|
38
44
|
class SyntaxError < Error; end
|
39
45
|
class MacroError < Error
|
46
|
+
include Glyph::Utils
|
40
47
|
attr_reader :macro
|
41
48
|
|
42
49
|
# Initializes a new Glyph::MacroError
|
@@ -49,9 +56,10 @@ module Glyph
|
|
49
56
|
|
50
57
|
# Displays the error message, source, path and node value (if debugging)
|
51
58
|
def display
|
52
|
-
|
53
|
-
|
54
|
-
|
59
|
+
warning exception.message
|
60
|
+
path = @macro.path.blank? ? "" : "\n path: #{@macro.path}"
|
61
|
+
msg " source: #{@macro.source_name}#{path}"
|
62
|
+
msg "#{"-"*54}\n#{@macro.node.to_s.gsub(/\t/, ' ')}\n#{"-"*54}" if Glyph.debug?
|
55
63
|
end
|
56
64
|
end
|
57
65
|
class MutualInclusionError < MacroError; end
|
@@ -65,6 +73,9 @@ module Glyph
|
|
65
73
|
# All the currently-loaded macros
|
66
74
|
MACROS = {}
|
67
75
|
|
76
|
+
# All macro aliases
|
77
|
+
ALIASES = {:by_alias => {}, :by_def => {}}
|
78
|
+
|
68
79
|
begin
|
69
80
|
unless const_defined? :MODE then
|
70
81
|
MODE = {
|
@@ -139,6 +150,7 @@ module Glyph
|
|
139
150
|
# Restores Glyph configuration (keeping all overrides and project settings)
|
140
151
|
def self.config_refresh
|
141
152
|
CONFIG.merge!(SYSTEM_CONFIG.merge(GLOBAL_CONFIG.merge(PROJECT_CONFIG)))
|
153
|
+
Glyph.safe_mode = Glyph['options.safe_mode']
|
142
154
|
end
|
143
155
|
|
144
156
|
# Resets Glyph configuration (removing all overrides and project settings)
|
@@ -148,13 +160,6 @@ module Glyph
|
|
148
160
|
self.config_refresh
|
149
161
|
end
|
150
162
|
|
151
|
-
# Returns true if the PROJECT constant is set to a valid Glyph project directory
|
152
|
-
def self.project?
|
153
|
-
children = ["text", "output", "snippets.yml", "config.yml", "document.glyph"].sort
|
154
|
-
actual_children = PROJECT.children.map{|c| c.basename.to_s}.sort
|
155
|
-
(actual_children & children) == children
|
156
|
-
end
|
157
|
-
|
158
163
|
# Resets Glyph completely, i.e.:
|
159
164
|
# * Re-enables all Glyph Rake tasks
|
160
165
|
# * Resets the configuration to system defaults
|
@@ -198,9 +203,22 @@ module Glyph
|
|
198
203
|
MACROS[name.to_sym] = block
|
199
204
|
end
|
200
205
|
|
201
|
-
|
202
|
-
|
203
|
-
|
206
|
+
#@since 0.4.0
|
207
|
+
# Creates a new macro by rewriting.
|
208
|
+
# @param [Symbol, String] name the name of the macro
|
209
|
+
# @param [String] text the Glyph code used to define the macro
|
210
|
+
def self.rewrite(name, text)
|
211
|
+
macro name do
|
212
|
+
body = text.dup
|
213
|
+
# Parameters
|
214
|
+
body.gsub!(/\{\{(\d+)\}\}/) do
|
215
|
+
raw_param($1.to_i).strip
|
216
|
+
end
|
217
|
+
# Attributes
|
218
|
+
body.gsub!(/\{\{([^\[\]\|\\\s]+)\}\}/) do
|
219
|
+
raw_attr($1.to_sym).strip
|
220
|
+
end
|
221
|
+
interpret body
|
204
222
|
end
|
205
223
|
end
|
206
224
|
|
@@ -210,12 +228,11 @@ module Glyph
|
|
210
228
|
# {:old_name => :new_name}
|
211
229
|
def self.macro_alias(pair)
|
212
230
|
name = pair.keys[0].to_sym
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
MACROS[name] = MACROS[pair.values[0].to_sym]
|
231
|
+
orig = pair.values[0].to_sym
|
232
|
+
ALIASES[:by_def][orig] = [] unless ALIASES[:by_def][orig]
|
233
|
+
ALIASES[:by_def][orig] << name unless ALIASES[:by_def][orig].include? name
|
234
|
+
ALIASES[:by_alias][name] = orig
|
235
|
+
MACROS[name] = MACROS[orig]
|
219
236
|
end
|
220
237
|
|
221
238
|
# Compiles a single Glyph file
|
@@ -267,36 +284,6 @@ module Glyph
|
|
267
284
|
end
|
268
285
|
|
269
286
|
|
270
|
-
# Prints a message
|
271
|
-
# @param [String] message the message to print
|
272
|
-
def self.msg(message)
|
273
|
-
puts message unless Glyph['system.quiet']
|
274
|
-
end
|
275
|
-
|
276
|
-
# Prints an informational message
|
277
|
-
# @param [String] message the message to print
|
278
|
-
def self.info(message)
|
279
|
-
puts "-- #{message}" unless Glyph['system.quiet']
|
280
|
-
end
|
281
|
-
|
282
|
-
# Prints a warning
|
283
|
-
# @param [String] message the message to print
|
284
|
-
def self.warning(message)
|
285
|
-
puts "-> warning: #{message}" unless Glyph['system.quiet']
|
286
|
-
end
|
287
|
-
|
288
|
-
# Prints an error
|
289
|
-
# @param [String] message the message to print
|
290
|
-
def self.error(message)
|
291
|
-
puts "=> error: #{message}" unless Glyph['system.quiet']
|
292
|
-
end
|
293
|
-
|
294
|
-
# Prints a message if running in debug mode
|
295
|
-
# @param [String] message the message to print
|
296
|
-
def self.debug(message)
|
297
|
-
puts message if Glyph.debug?
|
298
|
-
end
|
299
|
-
|
300
287
|
end
|
301
288
|
|
302
289
|
Glyph.setup
|
@@ -0,0 +1,253 @@
|
|
1
|
+
module Glyph
|
2
|
+
|
3
|
+
# @since 0.4.0
|
4
|
+
# This class is used to collect statistics about a Glyph document.
|
5
|
+
class Analyzer
|
6
|
+
|
7
|
+
include Glyph::Utils
|
8
|
+
|
9
|
+
attr_reader :stats
|
10
|
+
|
11
|
+
# Initializes a new Analyzer
|
12
|
+
# @param [Glyph::Document] doc the document to analyze
|
13
|
+
def initialize(doc=Glyph.document)
|
14
|
+
@doc = doc
|
15
|
+
@stats = {}
|
16
|
+
@macros = []
|
17
|
+
@macros_by_def = {}
|
18
|
+
end
|
19
|
+
|
20
|
+
# Helper method used to return an array of specific macro instances
|
21
|
+
# @param [String, Symbol] name the name of the macro definition
|
22
|
+
def macro_array_for(name)
|
23
|
+
return @macros_by_def[name.to_sym] if @macros_by_def[name.to_sym]
|
24
|
+
key = @macros_by_def.keys.select{|k| macro_eq?(k, name.to_sym) }[0] || name.to_sym
|
25
|
+
@macros_by_def[key] = [] unless @macros_by_def[key]
|
26
|
+
@macros_by_def[key]
|
27
|
+
end
|
28
|
+
|
29
|
+
# Iterator over specific macro instances
|
30
|
+
# @param [String, Symbol] name the name of the macro definition (if left blank, iterates over all macro instances)
|
31
|
+
# @yieldparam [Glyph::MacroNode] n the macro node
|
32
|
+
def with_macros(name=nil, &block)
|
33
|
+
raise ArgumentError, "No block given" unless block_given?
|
34
|
+
name = name.to_sym if name
|
35
|
+
if !name then
|
36
|
+
unless @macros.blank? then
|
37
|
+
@macros.each(&block)
|
38
|
+
else
|
39
|
+
@doc.structure.descend do |n, level|
|
40
|
+
if n.is_a?(Glyph::MacroNode) && n.source
|
41
|
+
@macros << n
|
42
|
+
macro_array_for(n[:name]) << n
|
43
|
+
block.call n
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
else
|
48
|
+
existing = @macros_by_def[name]
|
49
|
+
if existing then
|
50
|
+
existing.each(&block)
|
51
|
+
else
|
52
|
+
macros = []
|
53
|
+
@doc.structure.descend do |n, level|
|
54
|
+
if n.is_a?(Glyph::MacroNode) && macro_eq?(name, n[:name]) && n.source
|
55
|
+
macros << n
|
56
|
+
block.call n
|
57
|
+
end
|
58
|
+
end
|
59
|
+
@macros_by_def[name] = macros
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Retrieves statistics of a given type
|
65
|
+
# @param [String, Symbol] stats_type the type of stats to retrieve
|
66
|
+
# (:macros, :bookmarks, :links, :snippets, :files, :global, :macro, :bookmark, :snippet, :link)
|
67
|
+
# @param [String, Symbol] *args Stats parameter(s) (e.g. a macro name, bookmark ID, etc.)
|
68
|
+
def stats_for(stats_type, *args)
|
69
|
+
begin
|
70
|
+
send :"stats_#{stats_type}", *args
|
71
|
+
rescue NoMethodError => e
|
72
|
+
raise RuntimeError, "Unable to calculate #{stats_type} stats"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
protected
|
77
|
+
|
78
|
+
def stats_global
|
79
|
+
stats_macros
|
80
|
+
stats_bookmarks
|
81
|
+
stats_links
|
82
|
+
stats_snippets
|
83
|
+
stats_files
|
84
|
+
end
|
85
|
+
|
86
|
+
def stats_macros
|
87
|
+
c = @stats[:macros] = {}
|
88
|
+
c[:aliases] = Glyph::ALIASES[:by_alias].keys.sort
|
89
|
+
c[:definitions] = (Glyph::MACROS.keys - c[:aliases]).uniq.sort
|
90
|
+
c[:instances] = []
|
91
|
+
with_macros {|n| c[:instances] << n[:name]}
|
92
|
+
c[:used_definitions] = c[:instances].map{|m| macro_definition_for(m) || m}.uniq.sort
|
93
|
+
end
|
94
|
+
|
95
|
+
def stats_macro(name)
|
96
|
+
name = name.to_sym
|
97
|
+
raise ArgumentError, "Unknown macro '#{name}'" unless Glyph::MACROS.include? name
|
98
|
+
c = @stats[:macro] = {}
|
99
|
+
c[:param] = name
|
100
|
+
c[:instances] = []
|
101
|
+
c[:alias_for] = macro_definition_for name
|
102
|
+
files = {}
|
103
|
+
with_macros(name) do |n|
|
104
|
+
unless n.source.blank? then
|
105
|
+
c[:instances] << n[:name]
|
106
|
+
files[n.source] ||= 0
|
107
|
+
files[n.source] += 1
|
108
|
+
end
|
109
|
+
end
|
110
|
+
raise ArgumentError, "Macro '#{name}' is not used in this document" if c[:instances].blank?
|
111
|
+
if c[:alias_for] && !name.in?(c[:instances]) then
|
112
|
+
raise ArgumentError, "Macro '#{name}' is not used in this document, did you mean '#{c[:alias_for]}'?"
|
113
|
+
end
|
114
|
+
c[:files] = files.to_a.sort
|
115
|
+
end
|
116
|
+
|
117
|
+
def stats_bookmarks
|
118
|
+
c = @stats[:bookmarks] = {}
|
119
|
+
c[:codes] = []
|
120
|
+
files = {}
|
121
|
+
@doc.bookmarks.each_pair do |k, v|
|
122
|
+
c[:codes] << k
|
123
|
+
files[v.file] ||= 0
|
124
|
+
files[v.file] +=1
|
125
|
+
end
|
126
|
+
c[:codes].sort!
|
127
|
+
referenced = {}
|
128
|
+
with_macros(:link) do |n|
|
129
|
+
target =n.parameters[0][:value].to_s
|
130
|
+
if target.match(/^#/) then
|
131
|
+
code = target.gsub(/^#/, '').to_sym
|
132
|
+
referenced[code] ||= 0
|
133
|
+
referenced[code] += 1
|
134
|
+
end
|
135
|
+
end
|
136
|
+
c[:referenced] = referenced.to_a.sort
|
137
|
+
c[:unreferenced] = c[:codes] - c[:referenced].map{|e| e[0]}
|
138
|
+
end
|
139
|
+
|
140
|
+
def stats_bookmark(name)
|
141
|
+
code = name.to_s.gsub(/^#/, '').to_sym
|
142
|
+
raise ArgumentError, "Bookmark '#{code}' does not exist" unless @doc.bookmark? code
|
143
|
+
c = @stats[:bookmark] = {}
|
144
|
+
bmk = @doc.bookmark? code
|
145
|
+
c[:param] = name
|
146
|
+
c[:definition] = bmk.definition.to_s
|
147
|
+
c[:file] = bmk.file.to_s
|
148
|
+
c[:type] = bmk.is_a?(Glyph::Header) ? :header : :anchor
|
149
|
+
references = {}
|
150
|
+
with_macros(:link) do |n|
|
151
|
+
target = n.parameters[0].to_s.gsub(/^#/, '').to_sym
|
152
|
+
count_occurrences_for references, target, n if target == code
|
153
|
+
end
|
154
|
+
c[:references]= references[code][:files] rescue []
|
155
|
+
end
|
156
|
+
|
157
|
+
def stats_links
|
158
|
+
c = @stats[:links] = {}
|
159
|
+
internal = {}
|
160
|
+
external = {}
|
161
|
+
with_macros(:link) do |n|
|
162
|
+
target = n.parameters[0].to_s
|
163
|
+
collection = target.match(/^#/) ? internal : external
|
164
|
+
#code = target.gsub(/^#/, '').to_sym
|
165
|
+
count_occurrences_for collection, target, n
|
166
|
+
end
|
167
|
+
c[:internal] = internal.to_a.sort
|
168
|
+
c[:external] = external.to_a.sort
|
169
|
+
end
|
170
|
+
|
171
|
+
def stats_link(name)
|
172
|
+
regexp = /#{name}/
|
173
|
+
links = {}
|
174
|
+
with_macros(:link) do |n|
|
175
|
+
target = n.parameters[0].to_s
|
176
|
+
if target.match regexp then
|
177
|
+
count_occurrences_for links, target, n
|
178
|
+
end
|
179
|
+
end
|
180
|
+
raise ArgumentError, "No link matching /#{name}/ was found" if links.blank?
|
181
|
+
@stats[:link] = {}
|
182
|
+
@stats[:link][:stats] = links.to_a.sort
|
183
|
+
@stats[:link][:param] = name
|
184
|
+
end
|
185
|
+
|
186
|
+
def stats_snippets
|
187
|
+
c = @stats[:snippets] = {}
|
188
|
+
snippets = {}
|
189
|
+
c[:definitions] = Glyph::SNIPPETS.keys.sort
|
190
|
+
c[:used] = []
|
191
|
+
c[:unused] = []
|
192
|
+
c[:total] = 0
|
193
|
+
with_macros(:snippet) do |n|
|
194
|
+
code = n.parameters[0].to_s.to_sym
|
195
|
+
c[:used] << code unless c[:used].include? code
|
196
|
+
c[:total] += 1
|
197
|
+
#count_occurrences_for snippets, code, n
|
198
|
+
end
|
199
|
+
#c[:used_details] = snippets.to_a.sort
|
200
|
+
c[:used].sort!
|
201
|
+
c[:unused] = (c[:definitions] - c[:used]).sort
|
202
|
+
end
|
203
|
+
|
204
|
+
def stats_snippet(name)
|
205
|
+
name = name.to_sym
|
206
|
+
snippets = {}
|
207
|
+
raise ArgumentError, "Snippet '#{name}' does not exist" unless Glyph::SNIPPETS[name]
|
208
|
+
with_macros(:snippet) do |n|
|
209
|
+
code = n.parameters[0].to_s.to_sym
|
210
|
+
if code == name then
|
211
|
+
count_occurrences_for snippets, code, n
|
212
|
+
end
|
213
|
+
end
|
214
|
+
raise ArgumentError, "Snippet '#{name}' is not used in this document" if snippets.blank?
|
215
|
+
@stats[:snippet] = {}
|
216
|
+
@stats[:snippet][:stats] = snippets[name]
|
217
|
+
@stats[:snippet][:param] = name
|
218
|
+
end
|
219
|
+
|
220
|
+
def stats_files
|
221
|
+
@stats[:files] = {}
|
222
|
+
count_files_in = lambda do |dir|
|
223
|
+
files = []
|
224
|
+
(Glyph::PROJECT/"#{dir}").find{|f| files << f if f.file? } rescue nil
|
225
|
+
files.length
|
226
|
+
end
|
227
|
+
@stats[:files][:text] = count_files_in.call 'text'
|
228
|
+
@stats[:files][:lib] = count_files_in.call 'lib'
|
229
|
+
@stats[:files][:styles] = count_files_in.call 'styles'
|
230
|
+
@stats[:files][:layouts] = count_files_in.call 'layouts'
|
231
|
+
@stats[:files][:images] = count_files_in.call 'images'
|
232
|
+
end
|
233
|
+
|
234
|
+
private
|
235
|
+
|
236
|
+
def count_occurrences_for(collection, code, n)
|
237
|
+
collection[code] ||= {:total => 0, :files =>[]} unless collection[code]
|
238
|
+
collection[code][:total] += 1
|
239
|
+
coll = collection[code][:files]
|
240
|
+
added = false
|
241
|
+
coll.each do |file|
|
242
|
+
if file[0] == n.source then
|
243
|
+
file[1] += 1
|
244
|
+
added = true
|
245
|
+
break
|
246
|
+
end
|
247
|
+
end
|
248
|
+
coll << [n.source, 1] unless added
|
249
|
+
coll.sort!
|
250
|
+
end
|
251
|
+
|
252
|
+
end
|
253
|
+
end
|