nanoc 2.0 → 2.1

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 (99) hide show
  1. data/ChangeLog +54 -0
  2. data/LICENSE +1 -1
  3. data/README +63 -3
  4. data/Rakefile +61 -14
  5. data/bin/nanoc +7 -199
  6. data/lib/nanoc/base/asset.rb +113 -0
  7. data/lib/nanoc/base/asset_defaults.rb +21 -0
  8. data/lib/nanoc/base/asset_rep.rb +277 -0
  9. data/lib/nanoc/base/binary_filter.rb +44 -0
  10. data/lib/nanoc/base/code.rb +41 -0
  11. data/lib/nanoc/base/compiler.rb +46 -34
  12. data/lib/nanoc/base/core_ext/hash.rb +51 -7
  13. data/lib/nanoc/base/core_ext/string.rb +8 -0
  14. data/lib/nanoc/base/data_source.rb +253 -20
  15. data/lib/nanoc/base/defaults.rb +30 -0
  16. data/lib/nanoc/base/enhancements.rb +9 -84
  17. data/lib/nanoc/base/filter.rb +109 -6
  18. data/lib/nanoc/base/layout.rb +91 -0
  19. data/lib/nanoc/base/notification_center.rb +66 -0
  20. data/lib/nanoc/base/page.rb +94 -121
  21. data/lib/nanoc/base/page_defaults.rb +20 -0
  22. data/lib/nanoc/base/page_rep.rb +318 -0
  23. data/lib/nanoc/base/plugin.rb +57 -9
  24. data/lib/nanoc/base/proxies/asset_proxy.rb +29 -0
  25. data/lib/nanoc/base/proxies/asset_rep_proxy.rb +26 -0
  26. data/lib/nanoc/base/proxies/layout_proxy.rb +25 -0
  27. data/lib/nanoc/base/proxies/page_proxy.rb +35 -0
  28. data/lib/nanoc/base/proxies/page_rep_proxy.rb +28 -0
  29. data/lib/nanoc/base/proxy.rb +37 -0
  30. data/lib/nanoc/base/router.rb +72 -0
  31. data/lib/nanoc/base/site.rb +220 -91
  32. data/lib/nanoc/base/template.rb +64 -0
  33. data/lib/nanoc/binary_filters/image_science_thumbnail.rb +28 -0
  34. data/lib/nanoc/cli/base.rb +219 -0
  35. data/lib/nanoc/cli/cli.rb +16 -0
  36. data/lib/nanoc/cli/command.rb +105 -0
  37. data/lib/nanoc/cli/commands/autocompile.rb +80 -0
  38. data/lib/nanoc/cli/commands/compile.rb +273 -0
  39. data/lib/nanoc/cli/commands/create_layout.rb +85 -0
  40. data/lib/nanoc/cli/commands/create_page.rb +85 -0
  41. data/lib/nanoc/cli/commands/create_site.rb +327 -0
  42. data/lib/nanoc/cli/commands/create_template.rb +76 -0
  43. data/lib/nanoc/cli/commands/help.rb +69 -0
  44. data/lib/nanoc/cli/commands/info.rb +114 -0
  45. data/lib/nanoc/cli/commands/switch.rb +141 -0
  46. data/lib/nanoc/cli/commands/update.rb +91 -0
  47. data/lib/nanoc/cli/ext.rb +37 -0
  48. data/lib/nanoc/cli/logger.rb +66 -0
  49. data/lib/nanoc/cli/option_parser.rb +168 -0
  50. data/lib/nanoc/cli.rb +1 -0
  51. data/lib/nanoc/data_sources/filesystem.rb +650 -215
  52. data/lib/nanoc/data_sources/filesystem_combined.rb +495 -0
  53. data/lib/nanoc/extra/auto_compiler.rb +265 -0
  54. data/lib/nanoc/extra/context.rb +22 -0
  55. data/lib/nanoc/extra/core_ext/hash.rb +54 -0
  56. data/lib/nanoc/extra/core_ext/time.rb +13 -0
  57. data/lib/nanoc/extra/file_proxy.rb +29 -0
  58. data/lib/nanoc/extra/vcs.rb +48 -0
  59. data/lib/nanoc/extra/vcses/bazaar.rb +21 -0
  60. data/lib/nanoc/extra/vcses/dummy.rb +20 -0
  61. data/lib/nanoc/extra/vcses/git.rb +21 -0
  62. data/lib/nanoc/extra/vcses/mercurial.rb +21 -0
  63. data/lib/nanoc/extra/vcses/subversion.rb +21 -0
  64. data/lib/nanoc/filters/bluecloth.rb +13 -0
  65. data/lib/nanoc/filters/erb.rb +6 -22
  66. data/lib/nanoc/filters/erubis.rb +14 -0
  67. data/lib/nanoc/filters/haml.rb +11 -6
  68. data/lib/nanoc/filters/markaby.rb +5 -5
  69. data/lib/nanoc/filters/maruku.rb +14 -0
  70. data/lib/nanoc/filters/old.rb +19 -0
  71. data/lib/nanoc/filters/rdiscount.rb +13 -0
  72. data/lib/nanoc/filters/rdoc.rb +5 -4
  73. data/lib/nanoc/filters/redcloth.rb +14 -0
  74. data/lib/nanoc/filters/rubypants.rb +14 -0
  75. data/lib/nanoc/filters/sass.rb +13 -0
  76. data/lib/nanoc/helpers/blogging.rb +170 -0
  77. data/lib/nanoc/helpers/capturing.rb +59 -0
  78. data/lib/nanoc/helpers/html_escape.rb +23 -0
  79. data/lib/nanoc/helpers/link_to.rb +69 -0
  80. data/lib/nanoc/helpers/render.rb +47 -0
  81. data/lib/nanoc/helpers/tagging.rb +52 -0
  82. data/lib/nanoc/helpers/xml_sitemap.rb +58 -0
  83. data/lib/nanoc/routers/default.rb +54 -0
  84. data/lib/nanoc/routers/no_dirs.rb +66 -0
  85. data/lib/nanoc/routers/versioned.rb +79 -0
  86. data/lib/nanoc.rb +83 -12
  87. metadata +144 -47
  88. data/lib/nanoc/base/auto_compiler.rb +0 -124
  89. data/lib/nanoc/base/layout_processor.rb +0 -33
  90. data/lib/nanoc/base/page_proxy.rb +0 -31
  91. data/lib/nanoc/base/plugin_manager.rb +0 -33
  92. data/lib/nanoc/data_sources/database.rb +0 -259
  93. data/lib/nanoc/data_sources/trivial.rb +0 -145
  94. data/lib/nanoc/filters/markdown.rb +0 -13
  95. data/lib/nanoc/filters/smartypants.rb +0 -13
  96. data/lib/nanoc/filters/textile.rb +0 -13
  97. data/lib/nanoc/layout_processors/erb.rb +0 -35
  98. data/lib/nanoc/layout_processors/haml.rb +0 -18
  99. data/lib/nanoc/layout_processors/markaby.rb +0 -16
@@ -1,19 +1,67 @@
1
1
  module Nanoc
2
+
3
+ # Nanoc::Plugin is the superclass for all plugins, such as filters
4
+ # (Nanoc::Filter), binary filters (Nanoc::BinaryFilter), routers
5
+ # (Nanoc::Router), data sources (Nanoc::DataSource) and VCSes
6
+ # (Nanoc::Extra::VCS). Each plugin has one or more unique identifiers, and
7
+ # several methods in this class provides functionality for finding plugins
8
+ # with given identifiers.
2
9
  class Plugin
3
10
 
11
+ MAP = {}
12
+
4
13
  class << self
5
- attr_accessor :_identifiers
6
- end
7
14
 
8
- def self.identifiers(*identifiers)
9
- self._identifiers = [] unless instance_variable_defined?(:@_identifiers)
10
- identifiers.empty? ? self._identifiers || [] : self._identifiers = (self._identifiers || []) + identifiers
11
- end
15
+ # Sets or returns the identifiers for this plugin.
16
+ #
17
+ # When given a list of identifier symbols, sets the identifiers for
18
+ # this plugin. When given nothing, returns an array of identifier
19
+ # symbols for this plugin.
20
+ def identifiers(*identifiers)
21
+ # Initialize
22
+ @identifiers = [] unless instance_variables.include?('@identifiers')
23
+
24
+ if identifiers.empty?
25
+ @identifiers
26
+ else
27
+ @identifiers = identifiers
28
+ @identifiers.each { |i| register(i, self) }
29
+ end
30
+ end
31
+
32
+ # Sets or returns the identifier for this plugin.
33
+ #
34
+ # When given an identifier symbols, sets the identifier for this plugin.
35
+ # When given nothing, returns the identifier for this plugin.
36
+ def identifier(identifier=nil)
37
+ # Initialize
38
+ @identifiers = [] unless instance_variables.include?('@identifiers')
39
+
40
+ if identifier.nil?
41
+ @identifiers.first
42
+ else
43
+ @identifiers = [ identifier ]
44
+ register(identifier, self)
45
+ end
46
+ end
47
+
48
+ # Registers the given class +klass+ with the given name. This will allow
49
+ # the named method to find the class.
50
+ def register(name, klass)
51
+ MAP[klass.superclass] ||= {}
52
+ MAP[klass.superclass][name.to_sym] = klass
53
+ end
54
+
55
+ # Returns the the plugin with the given name. Only subclasses of this
56
+ # class will be searched. For example, calling this method on
57
+ # Nanoc::Filter will cause only Nanoc::Filter subclasses to be searched.
58
+ def named(name)
59
+ MAP[self] ||= {}
60
+ MAP[self][name.to_sym]
61
+ end
12
62
 
13
- def self.identifier(identifier=nil)
14
- self._identifiers = [] unless instance_variable_defined?(:@_identifiers)
15
- identifier.nil? ? self.identifiers.first : self.identifiers(identifier)
16
63
  end
17
64
 
18
65
  end
66
+
19
67
  end
@@ -0,0 +1,29 @@
1
+ module Nanoc
2
+
3
+ # Nanoc::AssetProxy is a proxy object for an asset (Nanoc::Asset).
4
+ class AssetProxy < Proxy
5
+
6
+ # Requests the asset attribute with the given name. +key+ can be a string
7
+ # or a symbol, and it can contain a trailing question mark (which will be
8
+ # stripped).
9
+ def [](key)
10
+ real_key = key.to_s.sub(/\?$/, '').to_sym
11
+
12
+ if real_key == :mtime
13
+ @obj.mtime
14
+ elsif real_key == :path # backward compatibility
15
+ @obj.reps.find { |r| r.name == :default }.web_path
16
+ else
17
+ super(key)
18
+ end
19
+ end
20
+
21
+ # Returns the asset representation with the given name.
22
+ def reps(name)
23
+ rep = @obj.reps.find { |r| r.name == name }
24
+ rep.nil? ? nil : rep.to_proxy
25
+ end
26
+
27
+ end
28
+
29
+ end
@@ -0,0 +1,26 @@
1
+ module Nanoc
2
+
3
+ # Nanoc::AssetRepProxy is a proxy object for an asset representation
4
+ # (Nanoc::AssetRep).
5
+ class AssetRepProxy < Proxy
6
+
7
+ # Requests the asset representation attribute with the given name. +key+
8
+ # can be a string or a symbol, and it can contain a trailing question mark
9
+ # (which will be stripped).
10
+ def [](key)
11
+ real_key = key.to_s.sub(/\?$/, '').to_sym
12
+
13
+ if real_key == :name
14
+ @obj.name
15
+ elsif real_key == :path
16
+ @obj.web_path
17
+ elsif real_key == :asset
18
+ @obj.asset.to_proxy
19
+ else
20
+ super(key)
21
+ end
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,25 @@
1
+ module Nanoc
2
+
3
+ # Nanoc::LayoutProxy is a proxy object for a layout (Nanoc::Layout).
4
+ class LayoutProxy < Proxy
5
+
6
+ # Requests the layout attribute with the given name. +key+ can be a string
7
+ # or a symbol, and it can contain a trailing question mark (which will be
8
+ # stripped).
9
+ def [](key)
10
+ real_key = key.to_s.sub(/\?$/, '').to_sym
11
+
12
+ if real_key == :content
13
+ @obj.content
14
+ elsif real_key == :path
15
+ @obj.path
16
+ elsif real_key == :mtime
17
+ @obj.mtime
18
+ else
19
+ super(key)
20
+ end
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,35 @@
1
+ module Nanoc
2
+
3
+ # Nanoc::PageProxy is a proxy object for a page (Nanoc::Page).
4
+ class PageProxy < Proxy
5
+
6
+ # Requests the page attribute with the given name. +key+ can be a string
7
+ # or a symbol, and it can contain a trailing question mark (which will be
8
+ # stripped).
9
+ def [](key)
10
+ real_key = key.to_s.sub(/\?$/, '').to_sym
11
+
12
+ if real_key == :mtime
13
+ @obj.mtime
14
+ elsif real_key == :parent
15
+ @obj.parent.nil? ? nil : @obj.parent.to_proxy
16
+ elsif real_key == :children
17
+ @obj.children.map { |page| page.to_proxy }
18
+ elsif real_key == :content # backward compatibility
19
+ @obj.reps.find { |r| r.name == :default }.content
20
+ elsif real_key == :path # backward compatibility
21
+ @obj.reps.find { |r| r.name == :default }.web_path
22
+ else
23
+ super(key)
24
+ end
25
+ end
26
+
27
+ # Returns the page representation with the given name.
28
+ def reps(name)
29
+ rep = @obj.reps.find { |r| r.name == name }
30
+ rep.nil? ? nil : rep.to_proxy
31
+ end
32
+
33
+ end
34
+
35
+ end
@@ -0,0 +1,28 @@
1
+ module Nanoc
2
+
3
+ # Nanoc::PageRepProxy is a proxy object for a page representation
4
+ # (Nanoc::PageRep).
5
+ class PageRepProxy < Proxy
6
+
7
+ # Requests the page representation attribute with the given name. +key+
8
+ # can be a string or a symbol, and it can contain a trailing question mark
9
+ # (which will be stripped).
10
+ def [](key)
11
+ real_key = key.to_s.sub(/\?$/, '').to_sym
12
+
13
+ if real_key == :name
14
+ @obj.name
15
+ elsif real_key == :content
16
+ @obj.content
17
+ elsif real_key == :path
18
+ @obj.web_path
19
+ elsif real_key == :page
20
+ @obj.page.to_proxy
21
+ else
22
+ super(key)
23
+ end
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,37 @@
1
+ module Nanoc
2
+
3
+ # Nanoc::Proxy is used when making data available to pages and layouts.
4
+ # It provides an easy way to access data without the risk of accidentally
5
+ # calling destructive methods.
6
+ class Proxy
7
+
8
+ instance_methods.each { |m| undef_method m unless m =~ /^__/ }
9
+
10
+ # Creates a proxy for the given object.
11
+ def initialize(obj)
12
+ @obj = obj
13
+ end
14
+
15
+ # Requests the attribute with the given name. +key+ can be a string or a
16
+ # symbol, and it can contain a trailing question mark (which will be
17
+ # stripped).
18
+ def [](key)
19
+ real_key = key.to_s.sub(/\?$/, '').to_sym
20
+
21
+ @obj.attribute_named(real_key)
22
+ end
23
+
24
+ # Sets a given attribute. The use of setting an object's attributes is not
25
+ # recommended but may be necessary in some cases.
26
+ def []=(key, value)
27
+ @obj.attributes[key.to_sym] = value
28
+ end
29
+
30
+ # Used for requesting attributes without accessing the proxy like a hash.
31
+ def method_missing(method, *args)
32
+ self[method]
33
+ end
34
+
35
+ end
36
+
37
+ end
@@ -0,0 +1,72 @@
1
+ module Nanoc
2
+
3
+ # A Nanoc::Router is an abstract superclass that determines the paths of
4
+ # page and asset representations, both the path on the disk (relative to the
5
+ # site's output directory) and the path as it appears on the web site.
6
+ class Router < Plugin
7
+
8
+ # Creates a new router for the given site.
9
+ def initialize(site)
10
+ @site = site
11
+ end
12
+
13
+ # Returns the routed path for the given page representation, including the
14
+ # filename and the extension. It should start with a slash, and should be
15
+ # relative to the web root (i.e. should not include any references to the
16
+ # output directory). There is no need to let this method handle custom
17
+ # paths.
18
+ #
19
+ # Subclasses must implement this method.
20
+ def path_for_page_rep(page_rep)
21
+ raise NotImplementedError.new("Nanoc::Router subclasses must implement #path_for_page_rep.")
22
+ end
23
+
24
+ # Returns the routed path for the given asset representation, including
25
+ # the filename and the extension. It should start with a slash, and should
26
+ # be relative to the web root (i.e. should not include any references to
27
+ # the output directory). There is no need to let this method handle custom
28
+ # paths.
29
+ #
30
+ # Subclasses must implement this method.
31
+ def path_for_asset_rep(asset_rep)
32
+ raise NotImplementedError.new("Nanoc::Router subclasses must implement #path_for_asset_rep.")
33
+ end
34
+
35
+ # Returns the web path for the given page or asset representation, i.e.
36
+ # the page or asset rep's custom path or routed path with index filenames
37
+ # stripped.
38
+ def web_path_for(obj)
39
+ # Get actual path
40
+ path ||= obj.attribute_named(:custom_path)
41
+ if obj.is_a?(Nanoc::PageRep) # Page rep
42
+ path ||= path_for_page_rep(obj)
43
+ else # Asset rep
44
+ path ||= path_for_asset_rep(obj)
45
+ end
46
+
47
+ # Try stripping each index filename
48
+ @site.config[:index_filenames].each do |index_filename|
49
+ if path[-index_filename.length..-1] == index_filename
50
+ # Strip and stop
51
+ path = path[0..-index_filename.length-1]
52
+ break
53
+ end
54
+ end
55
+
56
+ # Return possibly stripped path
57
+ path
58
+ end
59
+
60
+ # Returns the disk path for the given page or asset representation, i.e.
61
+ # the page or asset's custom path or routed path relative to the output
62
+ # directory.
63
+ def disk_path_for(obj)
64
+ @site.config[:output_dir] + (
65
+ obj.attribute_named(:custom_path) ||
66
+ (obj.is_a?(Nanoc::PageRep) ? path_for_page_rep(obj) : path_for_asset_rep(obj))
67
+ )
68
+ end
69
+
70
+ end
71
+
72
+ end