nanoc2 2.2.3

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 (100) hide show
  1. data/ChangeLog +3 -0
  2. data/LICENSE +19 -0
  3. data/README +75 -0
  4. data/Rakefile +76 -0
  5. data/bin/nanoc2 +26 -0
  6. data/lib/nanoc2.rb +73 -0
  7. data/lib/nanoc2/base.rb +26 -0
  8. data/lib/nanoc2/base/asset.rb +117 -0
  9. data/lib/nanoc2/base/asset_defaults.rb +21 -0
  10. data/lib/nanoc2/base/asset_rep.rb +282 -0
  11. data/lib/nanoc2/base/binary_filter.rb +44 -0
  12. data/lib/nanoc2/base/code.rb +41 -0
  13. data/lib/nanoc2/base/compiler.rb +67 -0
  14. data/lib/nanoc2/base/core_ext.rb +2 -0
  15. data/lib/nanoc2/base/core_ext/hash.rb +78 -0
  16. data/lib/nanoc2/base/core_ext/string.rb +8 -0
  17. data/lib/nanoc2/base/data_source.rb +286 -0
  18. data/lib/nanoc2/base/defaults.rb +30 -0
  19. data/lib/nanoc2/base/filter.rb +93 -0
  20. data/lib/nanoc2/base/layout.rb +91 -0
  21. data/lib/nanoc2/base/notification_center.rb +66 -0
  22. data/lib/nanoc2/base/page.rb +132 -0
  23. data/lib/nanoc2/base/page_defaults.rb +20 -0
  24. data/lib/nanoc2/base/page_rep.rb +324 -0
  25. data/lib/nanoc2/base/plugin.rb +71 -0
  26. data/lib/nanoc2/base/proxies.rb +5 -0
  27. data/lib/nanoc2/base/proxies/asset_proxy.rb +29 -0
  28. data/lib/nanoc2/base/proxies/asset_rep_proxy.rb +26 -0
  29. data/lib/nanoc2/base/proxies/layout_proxy.rb +25 -0
  30. data/lib/nanoc2/base/proxies/page_proxy.rb +35 -0
  31. data/lib/nanoc2/base/proxies/page_rep_proxy.rb +28 -0
  32. data/lib/nanoc2/base/proxy.rb +37 -0
  33. data/lib/nanoc2/base/router.rb +72 -0
  34. data/lib/nanoc2/base/site.rb +274 -0
  35. data/lib/nanoc2/base/template.rb +64 -0
  36. data/lib/nanoc2/binary_filters.rb +1 -0
  37. data/lib/nanoc2/binary_filters/image_science_thumbnail.rb +28 -0
  38. data/lib/nanoc2/cli.rb +9 -0
  39. data/lib/nanoc2/cli/base.rb +132 -0
  40. data/lib/nanoc2/cli/commands.rb +10 -0
  41. data/lib/nanoc2/cli/commands/autocompile.rb +80 -0
  42. data/lib/nanoc2/cli/commands/compile.rb +312 -0
  43. data/lib/nanoc2/cli/commands/create_layout.rb +85 -0
  44. data/lib/nanoc2/cli/commands/create_page.rb +85 -0
  45. data/lib/nanoc2/cli/commands/create_site.rb +323 -0
  46. data/lib/nanoc2/cli/commands/create_template.rb +76 -0
  47. data/lib/nanoc2/cli/commands/help.rb +69 -0
  48. data/lib/nanoc2/cli/commands/info.rb +125 -0
  49. data/lib/nanoc2/cli/commands/switch.rb +141 -0
  50. data/lib/nanoc2/cli/commands/update.rb +91 -0
  51. data/lib/nanoc2/cli/logger.rb +72 -0
  52. data/lib/nanoc2/data_sources.rb +2 -0
  53. data/lib/nanoc2/data_sources/filesystem.rb +707 -0
  54. data/lib/nanoc2/data_sources/filesystem_combined.rb +495 -0
  55. data/lib/nanoc2/extra.rb +6 -0
  56. data/lib/nanoc2/extra/auto_compiler.rb +285 -0
  57. data/lib/nanoc2/extra/context.rb +22 -0
  58. data/lib/nanoc2/extra/core_ext.rb +2 -0
  59. data/lib/nanoc2/extra/core_ext/hash.rb +54 -0
  60. data/lib/nanoc2/extra/core_ext/time.rb +13 -0
  61. data/lib/nanoc2/extra/file_proxy.rb +29 -0
  62. data/lib/nanoc2/extra/vcs.rb +48 -0
  63. data/lib/nanoc2/extra/vcses.rb +5 -0
  64. data/lib/nanoc2/extra/vcses/bazaar.rb +21 -0
  65. data/lib/nanoc2/extra/vcses/dummy.rb +20 -0
  66. data/lib/nanoc2/extra/vcses/git.rb +21 -0
  67. data/lib/nanoc2/extra/vcses/mercurial.rb +21 -0
  68. data/lib/nanoc2/extra/vcses/subversion.rb +21 -0
  69. data/lib/nanoc2/filters.rb +16 -0
  70. data/lib/nanoc2/filters/bluecloth.rb +13 -0
  71. data/lib/nanoc2/filters/erb.rb +19 -0
  72. data/lib/nanoc2/filters/erubis.rb +14 -0
  73. data/lib/nanoc2/filters/haml.rb +21 -0
  74. data/lib/nanoc2/filters/markaby.rb +14 -0
  75. data/lib/nanoc2/filters/maruku.rb +14 -0
  76. data/lib/nanoc2/filters/old.rb +19 -0
  77. data/lib/nanoc2/filters/rainpress.rb +13 -0
  78. data/lib/nanoc2/filters/rdiscount.rb +13 -0
  79. data/lib/nanoc2/filters/rdoc.rb +23 -0
  80. data/lib/nanoc2/filters/redcloth.rb +14 -0
  81. data/lib/nanoc2/filters/relativize_paths.rb +16 -0
  82. data/lib/nanoc2/filters/relativize_paths_in_css.rb +16 -0
  83. data/lib/nanoc2/filters/relativize_paths_in_html.rb +16 -0
  84. data/lib/nanoc2/filters/rubypants.rb +14 -0
  85. data/lib/nanoc2/filters/sass.rb +18 -0
  86. data/lib/nanoc2/helpers.rb +9 -0
  87. data/lib/nanoc2/helpers/blogging.rb +217 -0
  88. data/lib/nanoc2/helpers/capturing.rb +63 -0
  89. data/lib/nanoc2/helpers/filtering.rb +54 -0
  90. data/lib/nanoc2/helpers/html_escape.rb +25 -0
  91. data/lib/nanoc2/helpers/link_to.rb +113 -0
  92. data/lib/nanoc2/helpers/render.rb +49 -0
  93. data/lib/nanoc2/helpers/tagging.rb +56 -0
  94. data/lib/nanoc2/helpers/text.rb +38 -0
  95. data/lib/nanoc2/helpers/xml_sitemap.rb +63 -0
  96. data/lib/nanoc2/routers.rb +3 -0
  97. data/lib/nanoc2/routers/default.rb +54 -0
  98. data/lib/nanoc2/routers/no_dirs.rb +66 -0
  99. data/lib/nanoc2/routers/versioned.rb +79 -0
  100. metadata +185 -0
@@ -0,0 +1,76 @@
1
+ module Nanoc2::CLI
2
+
3
+ class CreateTemplateCommand < Cri::Command # :nodoc:
4
+
5
+ def name
6
+ 'create_template'
7
+ end
8
+
9
+ def aliases
10
+ [ 'ct' ]
11
+ end
12
+
13
+ def short_desc
14
+ 'create a template'
15
+ end
16
+
17
+ def long_desc
18
+ 'Create a new template in the current site.'
19
+ end
20
+
21
+ def usage
22
+ "nanoc2 create_template [name]"
23
+ end
24
+
25
+ def option_definitions
26
+ [
27
+ # --vcs
28
+ {
29
+ :long => 'vcs', :short => 'c', :argument => :required,
30
+ :desc => 'select the VCS to use'
31
+ }
32
+ ]
33
+ end
34
+
35
+ def run(options, arguments)
36
+ # Check arguments
37
+ if arguments.length != 1
38
+ $stderr.puts "usage: #{usage}"
39
+ exit 1
40
+ end
41
+
42
+ # Extract arguments
43
+ name = arguments[0]
44
+
45
+ # Check template name
46
+ if name.include?('/')
47
+ $stderr.puts 'Template names cannot contain slashes; aborting.'
48
+ exit 1
49
+ end
50
+
51
+ # Make sure we are in a nanoc site directory
52
+ @base.require_site
53
+
54
+ # Set VCS if possible
55
+ @base.set_vcs(options[:vcs])
56
+
57
+ # Setup notifications
58
+ Nanoc2::NotificationCenter.on(:file_created) do |file_path|
59
+ Nanoc2::CLI::Logger.instance.file(:high, :create, file_path)
60
+ end
61
+
62
+ # Create template
63
+ template = Nanoc2::Template.new(
64
+ "Hi, I'm a new template. Please edit me!",
65
+ { :title => "A Title" },
66
+ name
67
+ )
68
+ template.site = @base.site
69
+ template.save
70
+
71
+ puts "A template named '#{name}' has been created."
72
+ end
73
+
74
+ end
75
+
76
+ end
@@ -0,0 +1,69 @@
1
+ module Nanoc2::CLI
2
+
3
+ class HelpCommand < Cri::Command # :nodoc:
4
+
5
+ def name
6
+ 'help'
7
+ end
8
+
9
+ def aliases
10
+ []
11
+ end
12
+
13
+ def short_desc
14
+ 'show help for a command'
15
+ end
16
+
17
+ def long_desc
18
+ 'Show help for the given command, or show general help. When no ' +
19
+ 'command is given, a list of available commands is displayed, as ' +
20
+ 'well as a list of global commandline options. When a command is ' +
21
+ 'given, a command description as well as command-specific ' +
22
+ 'commandline options are shown.'
23
+ end
24
+
25
+ def usage
26
+ "nanoc2 help [command]"
27
+ end
28
+
29
+ def run(options, arguments)
30
+ # Check arguments
31
+ if arguments.size > 1
32
+ $stderr.puts "usage: #{usage}"
33
+ exit 1
34
+ end
35
+
36
+ if arguments.length == 0
37
+ # Build help text
38
+ text = ''
39
+
40
+ # Add title
41
+ text << "nanoc, a static site compiler written in Ruby.\n"
42
+
43
+ # Add available commands
44
+ text << "\n"
45
+ text << "Available commands:\n"
46
+ text << "\n"
47
+ @base.commands.sort.each do |command|
48
+ text << sprintf(" %-20s %s\n", command.name, command.short_desc)
49
+ end
50
+
51
+ # Add global options
52
+ text << "\n"
53
+ text << "Global options:\n"
54
+ text << "\n"
55
+ @base.global_option_definitions.sort { |x,y| x[:long] <=> y[:long] }.each do |opt_def|
56
+ text << sprintf(" -%1s --%-15s %s\n", opt_def[:short], opt_def[:long], opt_def[:desc])
57
+ end
58
+
59
+ # Display text
60
+ puts text
61
+ elsif arguments.length == 1
62
+ command = @base.command_named(arguments[0])
63
+ puts command.help
64
+ end
65
+ end
66
+
67
+ end
68
+
69
+ end
@@ -0,0 +1,125 @@
1
+ module Nanoc2::CLI
2
+
3
+ class InfoCommand < Cri::Command # :nodoc:
4
+
5
+ def name
6
+ 'info'
7
+ end
8
+
9
+ def aliases
10
+ []
11
+ end
12
+
13
+ def short_desc
14
+ 'show info about available plugins'
15
+ end
16
+
17
+ def long_desc
18
+ 'Show a list of available plugins, including filters, data sources ' +
19
+ 'and routers. If the current directory contains a nanoc web site, ' +
20
+ 'the plugins defined in this site will be shown as well.'
21
+ end
22
+
23
+ def usage
24
+ "nanoc2 info"
25
+ end
26
+
27
+ def option_definitions
28
+ []
29
+ end
30
+
31
+ def run(options, arguments)
32
+ # Check arguments
33
+ if arguments.size != 0
34
+ $stderr.puts "usage: #{usage}"
35
+ exit 1
36
+ end
37
+
38
+ # Get list of plugins (before and after)
39
+ plugins_before = find_all_plugins
40
+ @base.site
41
+ plugins_after = find_all_plugins
42
+
43
+ # Get structured list of plugins
44
+ plugins = {}
45
+ plugin_classes.each do |klass|
46
+ plugins[klass] = {
47
+ :builtin => plugins_before[klass],
48
+ :custom => plugins_after[klass] - plugins_before[klass]
49
+ }
50
+ end
51
+
52
+ # Find longest name
53
+ max_length = plugins.values.map { |k| k.values }.flatten.map { |k| k.identifiers.join(', ').length }.max + 2
54
+
55
+ PLUGIN_CLASS_ORDER.each do |superclass|
56
+ structured_plugins = plugins[superclass]
57
+
58
+ # Print kind
59
+ kind = name_for_plugin_class(superclass)
60
+ puts "#{kind}:"
61
+ puts
62
+
63
+ # Print plugins organised by subtype
64
+ [ :builtin, :custom ].each do |type|
65
+ # Find relevant plugins
66
+ subclasses = structured_plugins[type]
67
+
68
+ # Print type
69
+ puts " #{type}:"
70
+ if subclasses.empty?
71
+ puts " (none)"
72
+ next
73
+ end
74
+
75
+ # Print plugins
76
+ subclasses.sort_by { |k| k.identifier.to_s }.each do |klass|
77
+ # Get data
78
+ is_custom = !plugins_before[superclass].include?(klass)
79
+ klass_name = klass.to_s
80
+ klass_id = klass.identifiers.join(', ')
81
+
82
+ # Display
83
+ puts sprintf(" %-#{max_length}s (%s)", klass_id, klass_name)
84
+ end
85
+ end
86
+
87
+ puts
88
+ end
89
+ end
90
+
91
+ private
92
+
93
+ PLUGIN_CLASS_ORDER = [
94
+ Nanoc2::Filter,
95
+ Nanoc2::BinaryFilter,
96
+ Nanoc2::Router,
97
+ Nanoc2::Extra::VCS,
98
+ Nanoc2::DataSource
99
+ ]
100
+
101
+ PLUGIN_CLASSES = {
102
+ Nanoc2::BinaryFilter => 'Binary Filters',
103
+ Nanoc2::Filter => 'Filters',
104
+ Nanoc2::DataSource => 'Data Sources',
105
+ Nanoc2::Router => 'Routers',
106
+ Nanoc2::Extra::VCS => 'VCSes'
107
+ }
108
+
109
+ def find_all_plugins
110
+ plugin_classes.inject({}) do |memo, klass|
111
+ memo.merge(klass => Nanoc2::Plugin::MAP[klass].values.uniq)
112
+ end
113
+ end
114
+
115
+ def plugin_classes
116
+ PLUGIN_CLASSES.keys
117
+ end
118
+
119
+ def name_for_plugin_class(klass)
120
+ PLUGIN_CLASSES[klass]
121
+ end
122
+
123
+ end
124
+
125
+ end
@@ -0,0 +1,141 @@
1
+ module Nanoc2::CLI
2
+
3
+ class SwitchCommand < Cri::Command # :nodoc:
4
+
5
+ def name
6
+ 'switch'
7
+ end
8
+
9
+ def aliases
10
+ []
11
+ end
12
+
13
+ def short_desc
14
+ 'switch the site to a new data source'
15
+ end
16
+
17
+ def long_desc
18
+ 'Move the data stored in the site to a new, given data source.' +
19
+ "\n" +
20
+ 'The given new data source may need additional configuration ' +
21
+ 'parameters that cannot be specified on the commandline. These ' +
22
+ 'should be stored in the configuration file (config.yaml) BEFORE ' +
23
+ 'executing the switch command.' +
24
+ "\n" +
25
+ 'This command first loads all existing data into memory, destroys ' +
26
+ 'the on-disk data, changes the site\'s data source, and finally ' +
27
+ 'writes the data back to the disk using the new data source. Because ' +
28
+ 'of this action\'s destructive nature, THIS OPERATION SHOULD NOT BE ' +
29
+ 'INTERRUPTED as interruption could result in data loss.' +
30
+ "\n" +
31
+ 'This command will change data, and it is therefore recommended to ' +
32
+ 'make a backup in case something goes wrong.'
33
+ end
34
+
35
+ def usage
36
+ "nanoc2 switch [options]"
37
+ end
38
+
39
+ def option_definitions
40
+ [
41
+ # --vcs
42
+ {
43
+ :long => 'vcs', :short => 'c', :argument => :required,
44
+ :desc => 'select the VCS to use'
45
+ },
46
+ # --yes
47
+ {
48
+ :long => 'yes', :short => 'y', :argument => :forbidden,
49
+ :desc => 'switches the data source without warning'
50
+ },
51
+ # --datasource
52
+ {
53
+ :long => 'datasource', :short => 'd', :argument => :required,
54
+ :desc => 'specify the new data source for the site'
55
+ }
56
+ ]
57
+ end
58
+
59
+ def run(options, arguments)
60
+ # Check arguments
61
+ if arguments.size != 0
62
+ $stderr.puts "usage: #{usage}"
63
+ exit 1
64
+ end
65
+
66
+ # Check options
67
+ unless options.has_key?(:datasource)
68
+ $stderr.puts 'A new data source should be specified using the ' +
69
+ '-d/--datasource option.'
70
+ exit 1
71
+ end
72
+
73
+ # Find data source
74
+ data_source = Nanoc2::DataSource.named(options[:datasource])
75
+ if data_source.nil?
76
+ $stderr.puts "Unrecognised data source: #{options[:datasource]}"
77
+ exit 1
78
+ end
79
+
80
+ # Make sure we are in a nanoc site directory
81
+ @base.require_site
82
+
83
+ # Set VCS if possible
84
+ @base.set_vcs(options[:vcs])
85
+
86
+ # Check for -y switch
87
+ unless options.has_key?(:yes)
88
+ $stderr.puts '*************'
89
+ $stderr.puts '** WARNING **'
90
+ $stderr.puts '*************'
91
+ $stderr.puts
92
+ $stderr.puts 'Are you absolutely sure you want to set up the data ' +
93
+ 'source for this site? Setting up the data source ' +
94
+ 'will remove existing data. This operation is ' +
95
+ 'destructive and cannot be reverted. Please do not ' +
96
+ 'interrupt this operation; doing so can result in ' +
97
+ 'data loss. As always, consider making a backup copy.'
98
+ $stderr.puts
99
+ $stderr.puts 'To continue, use the -y/--yes option, like "nanoc2 ' +
100
+ 'switch -y".'
101
+ exit 1
102
+ end
103
+
104
+ # Setup notifications
105
+ Nanoc2::NotificationCenter.on(:file_created) do |file_path|
106
+ Nanoc2::CLI::Logger.instance.file(:high, :create, file_path)
107
+ end
108
+ Nanoc2::NotificationCenter.on(:file_updated) do |file_path|
109
+ Nanoc2::CLI::Logger.instance.file(:high, :update, file_path)
110
+ end
111
+
112
+ # Load data
113
+ @base.site.load_data
114
+
115
+ # Destroy existing data
116
+ @base.site.data_source.destroy
117
+
118
+ # Update configuration
119
+ @base.site.config[:data_source] = options[:datasource]
120
+ @base.site.instance_eval { @data_source = data_source.new(self) }
121
+ File.open('config.yaml', 'w') { |io| io.write(YAML.dump(@base.site.config.stringify_keys)) }
122
+
123
+ # Set VCS on new data source if possible
124
+ @base.set_vcs(options[:vcs])
125
+
126
+ @base.site.data_source.loading do
127
+ # Create initial data source
128
+ @base.site.data_source.setup
129
+
130
+ # Store all data
131
+ @base.site.pages.each { |p| @base.site.data_source.save_page(p) }
132
+ @base.site.data_source.save_page_defaults(@base.site.page_defaults)
133
+ @base.site.layouts.each { |l| @base.site.data_source.save_layout(l) }
134
+ @base.site.templates.each { |t| @base.site.data_source.save_template(t) }
135
+ @base.site.data_source.save_code(@base.site.code)
136
+ end
137
+ end
138
+
139
+ end
140
+
141
+ end
@@ -0,0 +1,91 @@
1
+ module Nanoc2::CLI
2
+
3
+ class UpdateCommand < Cri::Command # :nodoc:
4
+
5
+ def name
6
+ 'update'
7
+ end
8
+
9
+ def aliases
10
+ []
11
+ end
12
+
13
+ def short_desc
14
+ 'update the data stored by the data source to a newer version'
15
+ end
16
+
17
+ def long_desc
18
+ 'Update the data stored by the data source to a newer format. The ' +
19
+ 'format in which data is stored can change between releases, and ' +
20
+ 'even though backward compatibility is usually preserved, it is ' +
21
+ 'often a good idea to store the site data in a newer format so newer ' +
22
+ 'features can be taken advantage of.' +
23
+ "\n" +
24
+ 'This command will change data, and it is therefore recommended to ' +
25
+ 'make a backup in case something goes wrong.'
26
+ end
27
+
28
+ def usage
29
+ "nanoc2 update [options]"
30
+ end
31
+
32
+ def option_definitions
33
+ [
34
+ # --vcs
35
+ {
36
+ :long => 'vcs', :short => 'c', :argument => :required,
37
+ :desc => 'select the VCS to use'
38
+ },
39
+ # --yes
40
+ {
41
+ :long => 'yes', :short => 'y', :argument => :forbidden,
42
+ :desc => 'updates the data without warning'
43
+ }
44
+ ]
45
+ end
46
+
47
+ def run(options, arguments)
48
+ # Check arguments
49
+ if arguments.size != 0
50
+ $stderr.puts "usage: #{usage}"
51
+ exit 1
52
+ end
53
+
54
+ # Make sure we are in a nanoc site directory
55
+ @base.require_site
56
+
57
+ # Set VCS if possible
58
+ @base.set_vcs(options[:vcs])
59
+
60
+ # Check for -y switch
61
+ unless options.has_key?(:yes)
62
+ $stderr.puts '*************'
63
+ $stderr.puts '** WARNING **'
64
+ $stderr.puts '*************'
65
+ $stderr.puts
66
+ $stderr.puts 'Are you absolutely sure you want to update the ' +
67
+ 'content for this site? Updating the site content ' +
68
+ 'will change the structure of existing data. This ' +
69
+ 'operation is destructive and cannot be reverted. ' +
70
+ 'Please do not interrupt this operation; doing so can ' +
71
+ 'result in data loss. As always, consider making a ' +
72
+ 'backup copy.'
73
+ $stderr.puts
74
+ $stderr.puts 'If this nanoc site is versioned using a VCS ' +
75
+ 'supported by nanoc, consider using the --vcs option ' +
76
+ 'to have nanoc perform add/delete/move operations ' +
77
+ 'using the specified VCS. To get a list of VCSes ' +
78
+ 'supported by nanoc, issue the "info" command.'
79
+ $stderr.puts
80
+ $stderr.puts 'To continue, use the -y/--yes option, like "nanoc2 ' +
81
+ 'update -y".'
82
+ exit 1
83
+ end
84
+
85
+ # Update
86
+ @base.site.data_source.update
87
+ end
88
+
89
+ end
90
+
91
+ end