awestructx 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 (64) hide show
  1. data/bin/awestruct +8 -0
  2. data/lib/awestruct/astruct.rb +22 -0
  3. data/lib/awestruct/astruct_mixin.rb +71 -0
  4. data/lib/awestruct/cli/auto.rb +20 -0
  5. data/lib/awestruct/cli/generate.rb +26 -0
  6. data/lib/awestruct/cli/invoker.rb +109 -0
  7. data/lib/awestruct/cli/options.rb +116 -0
  8. data/lib/awestruct/cli/server.rb +24 -0
  9. data/lib/awestruct/config.rb +30 -0
  10. data/lib/awestruct/context.rb +22 -0
  11. data/lib/awestruct/context_helper.rb +68 -0
  12. data/lib/awestruct/engine.rb +254 -0
  13. data/lib/awestruct/extensions/assets.rb +39 -0
  14. data/lib/awestruct/extensions/atomizer.rb +44 -0
  15. data/lib/awestruct/extensions/cachebuster.rb +12 -0
  16. data/lib/awestruct/extensions/coffeescripttransform.rb +42 -0
  17. data/lib/awestruct/extensions/data_dir.rb +31 -0
  18. data/lib/awestruct/extensions/disqus.rb +62 -0
  19. data/lib/awestruct/extensions/extend_string.rb +97 -0
  20. data/lib/awestruct/extensions/flattr.rb +42 -0
  21. data/lib/awestruct/extensions/google_analytics.rb +38 -0
  22. data/lib/awestruct/extensions/gsub.rb +20 -0
  23. data/lib/awestruct/extensions/indexifier.rb +17 -0
  24. data/lib/awestruct/extensions/intense_debate.rb +38 -0
  25. data/lib/awestruct/extensions/minify.rb +178 -0
  26. data/lib/awestruct/extensions/obfuscate.rb +32 -0
  27. data/lib/awestruct/extensions/paginator.rb +105 -0
  28. data/lib/awestruct/extensions/partial.rb +25 -0
  29. data/lib/awestruct/extensions/pipeline.rb +50 -0
  30. data/lib/awestruct/extensions/posts.rb +70 -0
  31. data/lib/awestruct/extensions/relative.rb +11 -0
  32. data/lib/awestruct/extensions/remotePartial.rb +17 -0
  33. data/lib/awestruct/extensions/sitemap.rb +85 -0
  34. data/lib/awestruct/extensions/sitemap.xml.haml +16 -0
  35. data/lib/awestruct/extensions/tag_cloud.html.haml +7 -0
  36. data/lib/awestruct/extensions/tag_cloud.rb +34 -0
  37. data/lib/awestruct/extensions/tagger.rb +107 -0
  38. data/lib/awestruct/extensions/template.atom.haml +39 -0
  39. data/lib/awestruct/handler_chain.rb +28 -0
  40. data/lib/awestruct/handler_chains.rb +65 -0
  41. data/lib/awestruct/handlers/base_handler.rb +92 -0
  42. data/lib/awestruct/handlers/base_sass_handler.rb +42 -0
  43. data/lib/awestruct/handlers/file_handler.rb +61 -0
  44. data/lib/awestruct/handlers/front_matter_handler.rb +80 -0
  45. data/lib/awestruct/handlers/haml_handler.rb +42 -0
  46. data/lib/awestruct/handlers/interpolation_handler.rb +28 -0
  47. data/lib/awestruct/handlers/layout_handler.rb +61 -0
  48. data/lib/awestruct/handlers/markdown_handler.rb +36 -0
  49. data/lib/awestruct/handlers/no_op_handler.rb +34 -0
  50. data/lib/awestruct/handlers/sass_handler.rb +14 -0
  51. data/lib/awestruct/handlers/scss_handler.rb +14 -0
  52. data/lib/awestruct/handlers/string_handler.rb +29 -0
  53. data/lib/awestruct/handlers/textile_handler.rb +43 -0
  54. data/lib/awestruct/handlers/yaml_handler.rb +25 -0
  55. data/lib/awestruct/layouts.rb +15 -0
  56. data/lib/awestruct/page.rb +128 -0
  57. data/lib/awestruct/page_loader.rb +72 -0
  58. data/lib/awestruct/pipeline.rb +49 -0
  59. data/lib/awestruct/site.rb +51 -0
  60. data/lib/awestruct/util/default_inflections.rb +45 -0
  61. data/lib/awestruct/util/inflector.rb +242 -0
  62. data/lib/awestruct/version.rb +4 -0
  63. data/lib/guard/awestruct.rb +38 -0
  64. metadata +427 -0
@@ -0,0 +1,72 @@
1
+
2
+ module Awestruct
3
+
4
+ class PageLoader
5
+
6
+ attr_reader :site
7
+ attr_reader :root_dir
8
+
9
+ def initialize(site, target=:pages)
10
+ @site = site
11
+ @target = target
12
+
13
+ @root_dir = site.config.dir
14
+ if ( @target == :layouts )
15
+ @root_dir = Pathname.new( File.join( root_dir, '_layouts/' ) )
16
+ end
17
+ end
18
+
19
+ def ignore?(path)
20
+ site.config.ignore.include?( path )
21
+ end
22
+
23
+ def load_all(prepare=:inline)
24
+ pages = []
25
+ root_dir.find do |path|
26
+ if ( path == root_dir )
27
+ next
28
+ end
29
+ basename = File.basename( path )
30
+ if ( basename == '.htaccess' )
31
+ #special case
32
+ elsif ( basename =~ /^[_.]/ )
33
+ Find.prune
34
+ next
35
+ end
36
+ relative_path = path.relative_path_from( root_dir ).to_s
37
+ if ignore?(relative_path)
38
+ Find.prune
39
+ next
40
+ end
41
+ unless path.directory?
42
+ page = load_page( path, prepare )
43
+ if ( page )
44
+ #inherit_front_matter( page )
45
+ site.send( @target ) << page
46
+ pages << page
47
+ end
48
+ end
49
+ end
50
+ if ( prepare == :post )
51
+ pages.each{|p| p.prepare!}
52
+ end
53
+ end
54
+
55
+ def load_page(path,prepare=:inline)
56
+ pathname = case( path )
57
+ when Pathname:
58
+ pathname = path
59
+ else
60
+ pathname = Pathname.new( path )
61
+ end
62
+ chain = site.engine.pipeline.handler_chains[ path ]
63
+ return nil if chain.nil?
64
+ handler = chain.create(site, Pathname.new(path))
65
+ p = Page.new( site, handler )
66
+ p.prepare! if prepare == :inline
67
+ p
68
+ end
69
+
70
+ end
71
+
72
+ end
@@ -0,0 +1,49 @@
1
+
2
+ require 'awestruct/handler_chains'
3
+ require 'awestruct/context_helper'
4
+
5
+ module Awestruct
6
+
7
+ class Pipeline
8
+
9
+ attr_reader :handler_chains
10
+
11
+ def initialize()
12
+ @handler_chains = HandlerChains.new
13
+ @extensions = []
14
+ @helpers = []
15
+ @transformers = []
16
+ end
17
+
18
+ def extension(e)
19
+ @extensions << e
20
+ end
21
+
22
+ def helper(h)
23
+ @helpers << h
24
+ end
25
+
26
+ def transformer(t)
27
+ @transformers << t
28
+ end
29
+
30
+ def execute(site)
31
+ execute_extensions(site)
32
+ end
33
+
34
+ def execute_extensions(site)
35
+ @extensions.each do |e|
36
+ e.execute(site)
37
+ end
38
+ end
39
+
40
+ def mixin_helpers(context)
41
+ context.extend( Awestruct::ContextHelper )
42
+ @helpers.each do |h|
43
+ context.extend(h)
44
+ end
45
+ end
46
+
47
+ end
48
+
49
+ end
@@ -0,0 +1,51 @@
1
+
2
+ #require 'hashery/open_cascade'
3
+ require 'awestruct/layouts'
4
+ require 'awestruct/astruct'
5
+
6
+ module Awestruct
7
+
8
+ class Site < Awestruct::AStruct
9
+
10
+ attr_reader :dir
11
+ attr_reader :output_dir
12
+ attr_reader :tmp_dir
13
+
14
+ attr_reader :pages
15
+ attr_reader :layouts
16
+
17
+ attr_reader :config
18
+ attr_reader :engine
19
+
20
+ def initialize(engine, config)
21
+ @engine = engine
22
+ @pages = []
23
+ @layouts = Layouts.new
24
+ @config = config
25
+ self.encoding = false
26
+ end
27
+
28
+ def inspect
29
+ "Site{:dir=>#{dir}}"
30
+ end
31
+
32
+ def dir
33
+ @config.dir
34
+ end
35
+
36
+ def output_dir
37
+ @config.output_dir
38
+ end
39
+
40
+ def tmp_dir
41
+ @config.tmp_dir
42
+ end
43
+
44
+ def load_page(path)
45
+ engine.load_path( self, path )
46
+ end
47
+
48
+
49
+ end
50
+
51
+ end
@@ -0,0 +1,45 @@
1
+ # Proc that is instance evaled to create the default inflections for both the
2
+ # model inflector and the inflector extension.
3
+ unless defined?( DEFAULT_INFLECTIONS_PROC )
4
+ DEFAULT_INFLECTIONS_PROC = proc do
5
+ plural(/$/, 's')
6
+ plural(/s$/i, 's')
7
+ plural(/(alias|(?:stat|octop|vir|b)us)$/i, '\1es')
8
+ plural(/(buffal|tomat)o$/i, '\1oes')
9
+ plural(/([ti])um$/i, '\1a')
10
+ plural(/sis$/i, 'ses')
11
+ plural(/(?:([^f])fe|([lr])f)$/i, '\1\2ves')
12
+ plural(/(hive)$/i, '\1s')
13
+ plural(/([^aeiouy]|qu)y$/i, '\1ies')
14
+ plural(/(x|ch|ss|sh)$/i, '\1es')
15
+ plural(/(matr|vert|ind)ix|ex$/i, '\1ices')
16
+ plural(/([m|l])ouse$/i, '\1ice')
17
+
18
+ singular(/s$/i, '')
19
+ singular(/([ti])a$/i, '\1um')
20
+ singular(/(analy|ba|cri|diagno|parenthe|progno|synop|the)ses$/i, '\1sis')
21
+ singular(/([^f])ves$/i, '\1fe')
22
+ singular(/([h|t]ive)s$/i, '\1')
23
+ singular(/([lr])ves$/i, '\1f')
24
+ singular(/([^aeiouy]|qu)ies$/i, '\1y')
25
+ singular(/(m)ovies$/i, '\1ovie')
26
+ singular(/(x|ch|ss|sh)es$/i, '\1')
27
+ singular(/([m|l])ice$/i, '\1ouse')
28
+ singular(/buses$/i, 'bus')
29
+ singular(/oes$/i, 'o')
30
+ singular(/shoes$/i, 'shoe')
31
+ singular(/(alias|(?:stat|octop|vir|b)us)es$/i, '\1')
32
+ singular(/(vert|ind)ices$/i, '\1ex')
33
+ singular(/matrices$/i, 'matrix')
34
+
35
+ irregular('person', 'people')
36
+ irregular('man', 'men')
37
+ irregular('child', 'children')
38
+ irregular('sex', 'sexes')
39
+ irregular('move', 'moves')
40
+ irregular('quiz', 'quizzes')
41
+ irregular('testis', 'testes')
42
+
43
+ uncountable(%w(equipment information rice money species series fish sheep news))
44
+ end
45
+ end
@@ -0,0 +1,242 @@
1
+ # The inflector extension adds inflection instance methods to String, which allows the easy transformation of
2
+ # words from singular to plural, class names to table names, modularized class
3
+ # names to ones without, and class names to foreign keys. It exists for
4
+ # backwards compatibility to legacy Sequel code.
5
+
6
+ class String
7
+ # This module acts as a singleton returned/yielded by String.inflections,
8
+ # which is used to override or specify additional inflection rules. Examples:
9
+ #
10
+ # String.inflections do |inflect|
11
+ # inflect.plural /^(ox)$/i, '\1\2en'
12
+ # inflect.singular /^(ox)en/i, '\1'
13
+ #
14
+ # inflect.irregular 'octopus', 'octopi'
15
+ #
16
+ # inflect.uncountable "equipment"
17
+ # end
18
+ #
19
+ # New rules are added at the top. So in the example above, the irregular rule for octopus will now be the first of the
20
+ # pluralization and singularization rules that is runs. This guarantees that your rules run before any of the rules that may
21
+ # already have been loaded.
22
+ module Inflections
23
+ @plurals, @singulars, @uncountables = [], [], []
24
+
25
+ class << self
26
+ # Array of 2 element arrays, first containing a regex, and the second containing a substitution pattern, used for plurization.
27
+ attr_reader :plurals
28
+
29
+ # Array of 2 element arrays, first containing a regex, and the second containing a substitution pattern, used for singularization.
30
+ attr_reader :singulars
31
+
32
+ # Array of strings for words were the singular form is the same as the plural form
33
+ attr_reader :uncountables
34
+ end
35
+
36
+ # Clears the loaded inflections within a given scope (default is :all). Give the scope as a symbol of the inflection type,
37
+ # the options are: :plurals, :singulars, :uncountables
38
+ #
39
+ # Examples:
40
+ # clear :all
41
+ # clear :plurals
42
+ def self.clear(scope = :all)
43
+ case scope
44
+ when :all
45
+ @plurals, @singulars, @uncountables = [], [], []
46
+ else
47
+ instance_variable_set("@#{scope}", [])
48
+ end
49
+ end
50
+
51
+ # Specifies a new irregular that applies to both pluralization and singularization at the same time. This can only be used
52
+ # for strings, not regular expressions. You simply pass the irregular in singular and plural form.
53
+ #
54
+ # Examples:
55
+ # irregular 'octopus', 'octopi'
56
+ # irregular 'person', 'people'
57
+ def self.irregular(singular, plural)
58
+ plural(Regexp.new("(#{singular[0,1]})#{singular[1..-1]}$", "i"), '\1' + plural[1..-1])
59
+ singular(Regexp.new("(#{plural[0,1]})#{plural[1..-1]}$", "i"), '\1' + singular[1..-1])
60
+ end
61
+
62
+ # Specifies a new pluralization rule and its replacement. The rule can either be a string or a regular expression.
63
+ # The replacement should always be a string that may include references to the matched data from the rule.
64
+ #
65
+ # Example:
66
+ # plural(/(x|ch|ss|sh)$/i, '\1es')
67
+ def self.plural(rule, replacement)
68
+ @plurals.insert(0, [rule, replacement])
69
+ end
70
+
71
+ # Specifies a new singularization rule and its replacement. The rule can either be a string or a regular expression.
72
+ # The replacement should always be a string that may include references to the matched data from the rule.
73
+ #
74
+ # Example:
75
+ # singular(/([^aeiouy]|qu)ies$/i, '\1y')
76
+ def self.singular(rule, replacement)
77
+ @singulars.insert(0, [rule, replacement])
78
+ end
79
+
80
+ # Add uncountable words that shouldn't be attempted inflected.
81
+ #
82
+ # Examples:
83
+ # uncountable "money"
84
+ # uncountable "money", "information"
85
+ # uncountable %w( money information rice )
86
+ def self.uncountable(*words)
87
+ (@uncountables << words).flatten!
88
+ end
89
+
90
+ load( File.join( File.dirname(__FILE__), 'default_inflections.rb' ) )
91
+ instance_eval(&DEFAULT_INFLECTIONS_PROC)
92
+ end
93
+
94
+ # Yield the Inflections module if a block is given, and return
95
+ # the Inflections module.
96
+ def self.inflections
97
+ yield Inflections if block_given?
98
+ Inflections
99
+ end
100
+
101
+ # By default, camelize converts the string to UpperCamelCase. If the argument to camelize
102
+ # is set to :lower then camelize produces lowerCamelCase.
103
+ #
104
+ # camelize will also convert '/' to '::' which is useful for converting paths to namespaces
105
+ #
106
+ # Examples
107
+ # "active_record".camelize #=> "ActiveRecord"
108
+ # "active_record".camelize(:lower) #=> "activeRecord"
109
+ # "active_record/errors".camelize #=> "ActiveRecord::Errors"
110
+ # "active_record/errors".camelize(:lower) #=> "activeRecord::Errors"
111
+ def camelize(first_letter_in_uppercase = :upper)
112
+ s = gsub(/\/(.?)/){|x| "::#{x[-1..-1].upcase unless x == '/'}"}.gsub(/(^|_)(.)/){|x| x[-1..-1].upcase}
113
+ s[0...1] = s[0...1].downcase unless first_letter_in_uppercase == :upper
114
+ s
115
+ end
116
+ alias_method :camelcase, :camelize
117
+
118
+ # Singularizes and camelizes the string. Also strips out all characters preceding
119
+ # and including a period (".").
120
+ #
121
+ # Examples
122
+ # "egg_and_hams".classify #=> "EggAndHam"
123
+ # "post".classify #=> "Post"
124
+ # "schema.post".classify #=> "Post"
125
+ def classify
126
+ sub(/.*\./, '').singularize.camelize
127
+ end
128
+
129
+ # Constantize tries to find a declared constant with the name specified
130
+ # in the string. It raises a NameError when the name is not in CamelCase
131
+ # or is not initialized.
132
+ #
133
+ # Examples
134
+ # "Module".constantize #=> Module
135
+ # "Class".constantize #=> Class
136
+ def constantize
137
+ raise(NameError, "#{inspect} is not a valid constant name!") unless m = /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/.match(self)
138
+ Object.module_eval("::#{m[1]}", __FILE__, __LINE__)
139
+ end
140
+
141
+ # Replaces underscores with dashes in the string.
142
+ #
143
+ # Example
144
+ # "puni_puni".dasherize #=> "puni-puni"
145
+ def dasherize
146
+ gsub(/_/, '-')
147
+ end
148
+
149
+ # Removes the module part from the expression in the string
150
+ #
151
+ # Examples
152
+ # "ActiveRecord::CoreExtensions::String::Inflections".demodulize #=> "Inflections"
153
+ # "Inflections".demodulize #=> "Inflections"
154
+ def demodulize
155
+ gsub(/^.*::/, '')
156
+ end
157
+
158
+ # Creates a foreign key name from a class name.
159
+ # +use_underscore+ sets whether the method should put '_' between the name and 'id'.
160
+ #
161
+ # Examples
162
+ # "Message".foreign_key #=> "message_id"
163
+ # "Message".foreign_key(false) #=> "messageid"
164
+ # "Admin::Post".foreign_key #=> "post_id"
165
+ def foreign_key(use_underscore = true)
166
+ "#{demodulize.underscore}#{'_' if use_underscore}id"
167
+ end
168
+
169
+ # Capitalizes the first word and turns underscores into spaces and strips _id.
170
+ # Like titleize, this is meant for creating pretty output.
171
+ #
172
+ # Examples
173
+ # "employee_salary" #=> "Employee salary"
174
+ # "author_id" #=> "Author"
175
+ def humanize
176
+ gsub(/_id$/, "").gsub(/_/, " ").capitalize
177
+ end
178
+
179
+ # Returns the plural form of the word in the string.
180
+ #
181
+ # Examples
182
+ # "post".pluralize #=> "posts"
183
+ # "octopus".pluralize #=> "octopi"
184
+ # "sheep".pluralize #=> "sheep"
185
+ # "words".pluralize #=> "words"
186
+ # "the blue mailman".pluralize #=> "the blue mailmen"
187
+ # "CamelOctopus".pluralize #=> "CamelOctopi"
188
+ def pluralize
189
+ result = dup
190
+ Inflections.plurals.each{|(rule, replacement)| break if result.gsub!(rule, replacement)} unless Inflections.uncountables.include?(downcase)
191
+ result
192
+ end
193
+
194
+ # The reverse of pluralize, returns the singular form of a word in a string.
195
+ #
196
+ # Examples
197
+ # "posts".singularize #=> "post"
198
+ # "octopi".singularize #=> "octopus"
199
+ # "sheep".singluarize #=> "sheep"
200
+ # "word".singluarize #=> "word"
201
+ # "the blue mailmen".singularize #=> "the blue mailman"
202
+ # "CamelOctopi".singularize #=> "CamelOctopus"
203
+ def singularize
204
+ result = dup
205
+ Inflections.singulars.each{|(rule, replacement)| break if result.gsub!(rule, replacement)} unless Inflections.uncountables.include?(downcase)
206
+ result
207
+ end
208
+
209
+ # Underscores and pluralizes the string.
210
+ #
211
+ # Examples
212
+ # "RawScaledScorer".tableize #=> "raw_scaled_scorers"
213
+ # "egg_and_ham".tableize #=> "egg_and_hams"
214
+ # "fancyCategory".tableize #=> "fancy_categories"
215
+ def tableize
216
+ underscore.pluralize
217
+ end
218
+
219
+ # Capitalizes all the words and replaces some characters in the string to create
220
+ # a nicer looking title. Titleize is meant for creating pretty output.
221
+ #
222
+ # titleize is also aliased as as titlecase
223
+ #
224
+ # Examples
225
+ # "man from the boondocks".titleize #=> "Man From The Boondocks"
226
+ # "x-men: the last stand".titleize #=> "X Men: The Last Stand"
227
+ def titleize
228
+ underscore.humanize.gsub(/\b([a-z])/){|x| x[-1..-1].upcase}
229
+ end
230
+ alias_method :titlecase, :titleize
231
+
232
+ # The reverse of camelize. Makes an underscored form from the expression in the string.
233
+ # Also changes '::' to '/' to convert namespaces to paths.
234
+ #
235
+ # Examples
236
+ # "ActiveRecord".underscore #=> "active_record"
237
+ # "ActiveRecord::Errors".underscore #=> active_record/errors
238
+ def underscore
239
+ gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
240
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').tr("-", "_").downcase
241
+ end
242
+ end