nanoc 3.2.4 → 3.3.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 (230) hide show
  1. data/.gemtest +0 -0
  2. data/ChangeLog +3 -0
  3. data/Gemfile +32 -0
  4. data/LICENSE +19 -0
  5. data/NEWS.md +470 -0
  6. data/README.md +114 -0
  7. data/Rakefile +14 -0
  8. data/bin/nanoc +7 -27
  9. data/bin/nanoc3 +3 -0
  10. data/doc/yardoc_templates/default/layout/html/footer.erb +10 -0
  11. data/lib/nanoc.rb +41 -0
  12. data/lib/nanoc/base.rb +49 -0
  13. data/lib/nanoc/base/compilation/checksum_store.rb +57 -0
  14. data/lib/nanoc/base/compilation/compiled_content_cache.rb +62 -0
  15. data/lib/nanoc/base/compilation/compiler.rb +458 -0
  16. data/lib/nanoc/base/compilation/compiler_dsl.rb +214 -0
  17. data/lib/nanoc/base/compilation/dependency_tracker.rb +200 -0
  18. data/lib/nanoc/base/compilation/filter.rb +165 -0
  19. data/lib/nanoc/base/compilation/item_rep_proxy.rb +103 -0
  20. data/lib/nanoc/base/compilation/item_rep_recorder_proxy.rb +102 -0
  21. data/lib/nanoc/base/compilation/outdatedness_checker.rb +223 -0
  22. data/lib/nanoc/base/compilation/outdatedness_reasons.rb +46 -0
  23. data/lib/nanoc/base/compilation/rule.rb +73 -0
  24. data/lib/nanoc/base/compilation/rule_context.rb +84 -0
  25. data/lib/nanoc/base/compilation/rule_memory_calculator.rb +40 -0
  26. data/lib/nanoc/base/compilation/rule_memory_store.rb +53 -0
  27. data/lib/nanoc/base/compilation/rules_collection.rb +243 -0
  28. data/lib/nanoc/base/context.rb +47 -0
  29. data/lib/nanoc/base/core_ext.rb +6 -0
  30. data/lib/nanoc/base/core_ext/array.rb +62 -0
  31. data/lib/nanoc/base/core_ext/hash.rb +63 -0
  32. data/lib/nanoc/base/core_ext/pathname.rb +26 -0
  33. data/lib/nanoc/base/core_ext/string.rb +46 -0
  34. data/lib/nanoc/base/directed_graph.rb +275 -0
  35. data/lib/nanoc/base/errors.rb +211 -0
  36. data/lib/nanoc/base/memoization.rb +67 -0
  37. data/lib/nanoc/base/notification_center.rb +84 -0
  38. data/lib/nanoc/base/ordered_hash.rb +200 -0
  39. data/lib/nanoc/base/plugin_registry.rb +181 -0
  40. data/lib/nanoc/base/result_data/item_rep.rb +492 -0
  41. data/lib/nanoc/base/source_data/code_snippet.rb +58 -0
  42. data/lib/nanoc/base/source_data/configuration.rb +24 -0
  43. data/lib/nanoc/base/source_data/data_source.rb +234 -0
  44. data/lib/nanoc/base/source_data/item.rb +301 -0
  45. data/lib/nanoc/base/source_data/layout.rb +130 -0
  46. data/lib/nanoc/base/source_data/site.rb +361 -0
  47. data/lib/nanoc/base/store.rb +135 -0
  48. data/lib/nanoc/cli.rb +137 -0
  49. data/lib/nanoc/cli/command_runner.rb +104 -0
  50. data/lib/nanoc/cli/commands/autocompile.rb +58 -0
  51. data/lib/nanoc/cli/commands/compile.rb +297 -0
  52. data/lib/nanoc/cli/commands/create_item.rb +60 -0
  53. data/lib/nanoc/cli/commands/create_layout.rb +73 -0
  54. data/lib/nanoc/cli/commands/create_site.rb +411 -0
  55. data/lib/nanoc/cli/commands/debug.rb +117 -0
  56. data/lib/nanoc/cli/commands/deploy.rb +79 -0
  57. data/lib/nanoc/cli/commands/info.rb +98 -0
  58. data/lib/nanoc/cli/commands/nanoc.rb +38 -0
  59. data/lib/nanoc/cli/commands/prune.rb +50 -0
  60. data/lib/nanoc/cli/commands/update.rb +70 -0
  61. data/lib/nanoc/cli/commands/view.rb +82 -0
  62. data/lib/nanoc/cli/commands/watch.rb +124 -0
  63. data/lib/nanoc/cli/error_handler.rb +199 -0
  64. data/lib/nanoc/cli/logger.rb +92 -0
  65. data/lib/nanoc/data_sources.rb +29 -0
  66. data/lib/nanoc/data_sources/deprecated/delicious.rb +42 -0
  67. data/lib/nanoc/data_sources/deprecated/last_fm.rb +87 -0
  68. data/lib/nanoc/data_sources/deprecated/twitter.rb +38 -0
  69. data/lib/nanoc/data_sources/filesystem.rb +299 -0
  70. data/lib/nanoc/data_sources/filesystem_unified.rb +121 -0
  71. data/lib/nanoc/data_sources/filesystem_verbose.rb +91 -0
  72. data/lib/nanoc/extra.rb +24 -0
  73. data/lib/nanoc/extra/auto_compiler.rb +103 -0
  74. data/lib/nanoc/extra/chick.rb +125 -0
  75. data/lib/nanoc/extra/core_ext.rb +6 -0
  76. data/lib/nanoc/extra/core_ext/enumerable.rb +33 -0
  77. data/lib/nanoc/extra/core_ext/pathname.rb +30 -0
  78. data/lib/nanoc/extra/core_ext/time.rb +19 -0
  79. data/lib/nanoc/extra/deployer.rb +47 -0
  80. data/lib/nanoc/extra/deployers.rb +15 -0
  81. data/lib/nanoc/extra/deployers/fog.rb +98 -0
  82. data/lib/nanoc/extra/deployers/rsync.rb +70 -0
  83. data/lib/nanoc/extra/file_proxy.rb +40 -0
  84. data/lib/nanoc/extra/pruner.rb +86 -0
  85. data/lib/nanoc/extra/validators.rb +12 -0
  86. data/lib/nanoc/extra/validators/links.rb +268 -0
  87. data/lib/nanoc/extra/validators/w3c.rb +95 -0
  88. data/lib/nanoc/extra/vcs.rb +66 -0
  89. data/lib/nanoc/extra/vcses.rb +17 -0
  90. data/lib/nanoc/extra/vcses/bazaar.rb +25 -0
  91. data/lib/nanoc/extra/vcses/dummy.rb +24 -0
  92. data/lib/nanoc/extra/vcses/git.rb +25 -0
  93. data/lib/nanoc/extra/vcses/mercurial.rb +25 -0
  94. data/lib/nanoc/extra/vcses/subversion.rb +25 -0
  95. data/lib/nanoc/filters.rb +59 -0
  96. data/lib/nanoc/filters/asciidoc.rb +38 -0
  97. data/lib/nanoc/filters/bluecloth.rb +19 -0
  98. data/lib/nanoc/filters/coderay.rb +21 -0
  99. data/lib/nanoc/filters/coffeescript.rb +20 -0
  100. data/lib/nanoc/filters/colorize_syntax.rb +298 -0
  101. data/lib/nanoc/filters/erb.rb +38 -0
  102. data/lib/nanoc/filters/erubis.rb +34 -0
  103. data/lib/nanoc/filters/haml.rb +27 -0
  104. data/lib/nanoc/filters/kramdown.rb +20 -0
  105. data/lib/nanoc/filters/less.rb +53 -0
  106. data/lib/nanoc/filters/markaby.rb +20 -0
  107. data/lib/nanoc/filters/maruku.rb +20 -0
  108. data/lib/nanoc/filters/mustache.rb +24 -0
  109. data/lib/nanoc/filters/rainpress.rb +19 -0
  110. data/lib/nanoc/filters/rdiscount.rb +22 -0
  111. data/lib/nanoc/filters/rdoc.rb +33 -0
  112. data/lib/nanoc/filters/redcarpet.rb +62 -0
  113. data/lib/nanoc/filters/redcloth.rb +47 -0
  114. data/lib/nanoc/filters/relativize_paths.rb +94 -0
  115. data/lib/nanoc/filters/rubypants.rb +20 -0
  116. data/lib/nanoc/filters/sass.rb +74 -0
  117. data/lib/nanoc/filters/slim.rb +25 -0
  118. data/lib/nanoc/filters/typogruby.rb +23 -0
  119. data/lib/nanoc/filters/uglify_js.rb +42 -0
  120. data/lib/nanoc/filters/xsl.rb +46 -0
  121. data/lib/nanoc/filters/yui_compressor.rb +23 -0
  122. data/lib/nanoc/helpers.rb +16 -0
  123. data/lib/nanoc/helpers/blogging.rb +319 -0
  124. data/lib/nanoc/helpers/breadcrumbs.rb +40 -0
  125. data/lib/nanoc/helpers/capturing.rb +138 -0
  126. data/lib/nanoc/helpers/filtering.rb +50 -0
  127. data/lib/nanoc/helpers/html_escape.rb +55 -0
  128. data/lib/nanoc/helpers/link_to.rb +151 -0
  129. data/lib/nanoc/helpers/rendering.rb +140 -0
  130. data/lib/nanoc/helpers/tagging.rb +71 -0
  131. data/lib/nanoc/helpers/text.rb +44 -0
  132. data/lib/nanoc/helpers/xml_sitemap.rb +76 -0
  133. data/lib/nanoc/tasks.rb +10 -0
  134. data/lib/nanoc/tasks/clean.rake +16 -0
  135. data/lib/nanoc/tasks/clean.rb +29 -0
  136. data/lib/nanoc/tasks/deploy/rsync.rake +16 -0
  137. data/lib/nanoc/tasks/validate.rake +92 -0
  138. data/nanoc.gemspec +49 -0
  139. data/tasks/doc.rake +16 -0
  140. data/tasks/test.rake +46 -0
  141. data/test/base/core_ext/array_spec.rb +73 -0
  142. data/test/base/core_ext/hash_spec.rb +98 -0
  143. data/test/base/core_ext/pathname_spec.rb +27 -0
  144. data/test/base/core_ext/string_spec.rb +37 -0
  145. data/test/base/test_checksum_store.rb +35 -0
  146. data/test/base/test_code_snippet.rb +31 -0
  147. data/test/base/test_compiler.rb +403 -0
  148. data/test/base/test_compiler_dsl.rb +161 -0
  149. data/test/base/test_context.rb +31 -0
  150. data/test/base/test_data_source.rb +46 -0
  151. data/test/base/test_dependency_tracker.rb +262 -0
  152. data/test/base/test_directed_graph.rb +288 -0
  153. data/test/base/test_filter.rb +83 -0
  154. data/test/base/test_item.rb +179 -0
  155. data/test/base/test_item_rep.rb +579 -0
  156. data/test/base/test_layout.rb +59 -0
  157. data/test/base/test_memoization.rb +90 -0
  158. data/test/base/test_notification_center.rb +34 -0
  159. data/test/base/test_outdatedness_checker.rb +394 -0
  160. data/test/base/test_plugin.rb +30 -0
  161. data/test/base/test_rule.rb +19 -0
  162. data/test/base/test_rule_context.rb +65 -0
  163. data/test/base/test_site.rb +190 -0
  164. data/test/cli/commands/test_compile.rb +33 -0
  165. data/test/cli/commands/test_create_item.rb +14 -0
  166. data/test/cli/commands/test_create_layout.rb +28 -0
  167. data/test/cli/commands/test_create_site.rb +24 -0
  168. data/test/cli/commands/test_deploy.rb +74 -0
  169. data/test/cli/commands/test_help.rb +12 -0
  170. data/test/cli/commands/test_info.rb +11 -0
  171. data/test/cli/commands/test_prune.rb +98 -0
  172. data/test/cli/commands/test_update.rb +10 -0
  173. data/test/cli/test_cli.rb +102 -0
  174. data/test/cli/test_error_handler.rb +29 -0
  175. data/test/cli/test_logger.rb +10 -0
  176. data/test/data_sources/test_filesystem.rb +433 -0
  177. data/test/data_sources/test_filesystem_unified.rb +536 -0
  178. data/test/data_sources/test_filesystem_verbose.rb +357 -0
  179. data/test/extra/core_ext/test_enumerable.rb +30 -0
  180. data/test/extra/core_ext/test_pathname.rb +17 -0
  181. data/test/extra/core_ext/test_time.rb +15 -0
  182. data/test/extra/deployers/test_fog.rb +67 -0
  183. data/test/extra/deployers/test_rsync.rb +100 -0
  184. data/test/extra/test_auto_compiler.rb +417 -0
  185. data/test/extra/test_file_proxy.rb +19 -0
  186. data/test/extra/test_vcs.rb +22 -0
  187. data/test/extra/validators/test_links.rb +62 -0
  188. data/test/extra/validators/test_w3c.rb +47 -0
  189. data/test/filters/test_asciidoc.rb +22 -0
  190. data/test/filters/test_bluecloth.rb +18 -0
  191. data/test/filters/test_coderay.rb +44 -0
  192. data/test/filters/test_coffeescript.rb +18 -0
  193. data/test/filters/test_colorize_syntax.rb +379 -0
  194. data/test/filters/test_erb.rb +105 -0
  195. data/test/filters/test_erubis.rb +78 -0
  196. data/test/filters/test_haml.rb +96 -0
  197. data/test/filters/test_kramdown.rb +18 -0
  198. data/test/filters/test_less.rb +113 -0
  199. data/test/filters/test_markaby.rb +24 -0
  200. data/test/filters/test_maruku.rb +18 -0
  201. data/test/filters/test_mustache.rb +25 -0
  202. data/test/filters/test_rainpress.rb +29 -0
  203. data/test/filters/test_rdiscount.rb +31 -0
  204. data/test/filters/test_rdoc.rb +18 -0
  205. data/test/filters/test_redcarpet.rb +73 -0
  206. data/test/filters/test_redcloth.rb +33 -0
  207. data/test/filters/test_relativize_paths.rb +533 -0
  208. data/test/filters/test_rubypants.rb +18 -0
  209. data/test/filters/test_sass.rb +229 -0
  210. data/test/filters/test_slim.rb +35 -0
  211. data/test/filters/test_typogruby.rb +21 -0
  212. data/test/filters/test_uglify_js.rb +30 -0
  213. data/test/filters/test_xsl.rb +105 -0
  214. data/test/filters/test_yui_compressor.rb +44 -0
  215. data/test/gem_loader.rb +11 -0
  216. data/test/helper.rb +207 -0
  217. data/test/helpers/test_blogging.rb +754 -0
  218. data/test/helpers/test_breadcrumbs.rb +81 -0
  219. data/test/helpers/test_capturing.rb +41 -0
  220. data/test/helpers/test_filtering.rb +106 -0
  221. data/test/helpers/test_html_escape.rb +32 -0
  222. data/test/helpers/test_link_to.rb +249 -0
  223. data/test/helpers/test_rendering.rb +89 -0
  224. data/test/helpers/test_tagging.rb +87 -0
  225. data/test/helpers/test_text.rb +24 -0
  226. data/test/helpers/test_xml_sitemap.rb +103 -0
  227. data/test/tasks/test_clean.rb +67 -0
  228. metadata +327 -15
  229. data/bin/nanoc-select +0 -86
  230. data/lib/nanoc-select.rb +0 -11
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ module Nanoc::Extra::VCSes
4
+
5
+ # @see Nanoc::Extra::VCS
6
+ class Bazaar < Nanoc::Extra::VCS
7
+
8
+ # @see Nanoc::Extra::VCS#add
9
+ def add(filename)
10
+ system('bzr', 'add', filename)
11
+ end
12
+
13
+ # @see Nanoc::Extra::VCS#remove
14
+ def remove(filename)
15
+ system('bzr', 'rm', filename)
16
+ end
17
+
18
+ # @see Nanoc::Extra::VCS#move
19
+ def move(src, dst)
20
+ system('bzr', 'mv', src, dst)
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+
3
+ module Nanoc::Extra::VCSes
4
+
5
+ # @see Nanoc::Extra::VCS
6
+ class Dummy < Nanoc::Extra::VCS
7
+
8
+ # @see Nanoc::Extra::VCS#add
9
+ def add(filename)
10
+ end
11
+
12
+ # @see Nanoc::Extra::VCS#remove
13
+ def remove(filename)
14
+ FileUtils.rm_rf(filename)
15
+ end
16
+
17
+ # @see Nanoc::Extra::VCS#move
18
+ def move(src, dst)
19
+ FileUtils.move(src, dst)
20
+ end
21
+
22
+ end
23
+
24
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ module Nanoc::Extra::VCSes
4
+
5
+ # @see Nanoc::Extra::VCS
6
+ class Git < Nanoc::Extra::VCS
7
+
8
+ # @see Nanoc::Extra::VCS#add
9
+ def add(filename)
10
+ system('git', 'add', filename)
11
+ end
12
+
13
+ # @see Nanoc::Extra::VCS#remove
14
+ def remove(filename)
15
+ system('git', 'rm', filename)
16
+ end
17
+
18
+ # @see Nanoc::Extra::VCS#move
19
+ def move(src, dst)
20
+ system('git', 'mv', src, dst)
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ module Nanoc::Extra::VCSes
4
+
5
+ # @see Nanoc::Extra::VCS
6
+ class Mercurial < Nanoc::Extra::VCS
7
+
8
+ # @see Nanoc::Extra::VCS#add
9
+ def add(filename)
10
+ system('hg', 'add', filename)
11
+ end
12
+
13
+ # @see Nanoc::Extra::VCS#remove
14
+ def remove(filename)
15
+ system('hg', 'rm', filename)
16
+ end
17
+
18
+ # @see Nanoc::Extra::VCS#move
19
+ def move(src, dst)
20
+ system('hg', 'mv', src, dst)
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ module Nanoc::Extra::VCSes
4
+
5
+ # @see Nanoc::Extra::VCS
6
+ class Subversion < Nanoc::Extra::VCS
7
+
8
+ # @see Nanoc::Extra::VCS#add
9
+ def add(filename)
10
+ system('svn', 'add', filename)
11
+ end
12
+
13
+ # @see Nanoc::Extra::VCS#remove
14
+ def remove(filename)
15
+ system('svn', 'rm', filename)
16
+ end
17
+
18
+ # @see Nanoc::Extra::VCS#move
19
+ def move(src, dst)
20
+ system('svn', 'mv', src, dst)
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,59 @@
1
+ # encoding: utf-8
2
+
3
+ module Nanoc::Filters
4
+
5
+ autoload 'AsciiDoc', 'nanoc/filters/asciidoc'
6
+ autoload 'BlueCloth', 'nanoc/filters/bluecloth'
7
+ autoload 'CodeRay', 'nanoc/filters/coderay'
8
+ autoload 'ColorizeSyntax', 'nanoc/filters/colorize_syntax'
9
+ autoload 'CoffeeScript', 'nanoc/filters/coffeescript'
10
+ autoload 'ERB', 'nanoc/filters/erb'
11
+ autoload 'Erubis', 'nanoc/filters/erubis'
12
+ autoload 'Haml', 'nanoc/filters/haml'
13
+ autoload 'Kramdown', 'nanoc/filters/kramdown'
14
+ autoload 'Less', 'nanoc/filters/less'
15
+ autoload 'Markaby', 'nanoc/filters/markaby'
16
+ autoload 'Maruku', 'nanoc/filters/maruku'
17
+ autoload 'Mustache', 'nanoc/filters/mustache'
18
+ autoload 'Rainpress', 'nanoc/filters/rainpress'
19
+ autoload 'RDiscount', 'nanoc/filters/rdiscount'
20
+ autoload 'RDoc', 'nanoc/filters/rdoc'
21
+ autoload 'Redcarpet', 'nanoc/filters/redcarpet'
22
+ autoload 'RedCloth', 'nanoc/filters/redcloth'
23
+ autoload 'RelativizePaths', 'nanoc/filters/relativize_paths'
24
+ autoload 'RubyPants', 'nanoc/filters/rubypants'
25
+ autoload 'Sass', 'nanoc/filters/sass'
26
+ autoload 'Slim', 'nanoc/filters/slim'
27
+ autoload 'Typogruby', 'nanoc/filters/typogruby'
28
+ autoload 'UglifyJS', 'nanoc/filters/uglify_js'
29
+ autoload 'XSL', 'nanoc/filters/xsl'
30
+ autoload 'YUICompressor', 'nanoc/filters/yui_compressor'
31
+
32
+ Nanoc::Filter.register '::Nanoc::Filters::AsciiDoc', :asciidoc
33
+ Nanoc::Filter.register '::Nanoc::Filters::BlueCloth', :bluecloth
34
+ Nanoc::Filter.register '::Nanoc::Filters::CodeRay', :coderay
35
+ Nanoc::Filter.register '::Nanoc::Filters::ColorizeSyntax', :colorize_syntax
36
+ Nanoc::Filter.register '::Nanoc::Filters::CoffeeScript', :coffeescript
37
+ Nanoc::Filter.register '::Nanoc::Filters::ERB', :erb
38
+ Nanoc::Filter.register '::Nanoc::Filters::Erubis', :erubis
39
+ Nanoc::Filter.register '::Nanoc::Filters::Haml', :haml
40
+ Nanoc::Filter.register '::Nanoc::Filters::Kramdown', :kramdown
41
+ Nanoc::Filter.register '::Nanoc::Filters::Less', :less
42
+ Nanoc::Filter.register '::Nanoc::Filters::Markaby', :markaby
43
+ Nanoc::Filter.register '::Nanoc::Filters::Maruku', :maruku
44
+ Nanoc::Filter.register '::Nanoc::Filters::Mustache', :mustache
45
+ Nanoc::Filter.register '::Nanoc::Filters::Rainpress', :rainpress
46
+ Nanoc::Filter.register '::Nanoc::Filters::RDiscount', :rdiscount
47
+ Nanoc::Filter.register '::Nanoc::Filters::RDoc', :rdoc
48
+ Nanoc::Filter.register '::Nanoc::Filters::Redcarpet', :redcarpet
49
+ Nanoc::Filter.register '::Nanoc::Filters::RedCloth', :redcloth
50
+ Nanoc::Filter.register '::Nanoc::Filters::RelativizePaths', :relativize_paths
51
+ Nanoc::Filter.register '::Nanoc::Filters::RubyPants', :rubypants
52
+ Nanoc::Filter.register '::Nanoc::Filters::Sass', :sass
53
+ Nanoc::Filter.register '::Nanoc::Filters::Slim', :slim
54
+ Nanoc::Filter.register '::Nanoc::Filters::Typogruby', :typogruby
55
+ Nanoc::Filter.register '::Nanoc::Filters::UglifyJS', :uglify_js
56
+ Nanoc::Filter.register '::Nanoc::Filters::XSL', :xsl
57
+ Nanoc::Filter.register '::Nanoc::Filters::YUICompressor', :yui_compressor
58
+
59
+ end
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+
3
+ require 'systemu'
4
+
5
+ module Nanoc::Filters
6
+
7
+ # @since 3.2.0
8
+ class AsciiDoc < Nanoc::Filter
9
+
10
+ # Runs the content through [AsciiDoc](http://www.methods.co.nz/asciidoc/).
11
+ # This method takes no options.
12
+ #
13
+ # @param [String] content The content to filter
14
+ #
15
+ # @return [String] The filtered content
16
+ def run(content, params={})
17
+ # Run command
18
+ stdout = ''
19
+ stderr = ''
20
+ status = systemu(
21
+ [ 'asciidoc', '-o', '-', '-' ],
22
+ 'stdin' => content,
23
+ 'stdout' => stdout,
24
+ 'stderr' => stderr)
25
+
26
+ # Show errors
27
+ unless status.success?
28
+ $stderr.puts stderr
29
+ raise RuntimeError, "AsciiDoc filter failed with status #{status}"
30
+ end
31
+
32
+ # Get result
33
+ stdout
34
+ end
35
+
36
+ end
37
+
38
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ require 'bluecloth'
4
+
5
+ module Nanoc::Filters
6
+ class BlueCloth < Nanoc::Filter
7
+
8
+ # Runs the content through [BlueCloth](http://deveiate.org/projects/BlueCloth).
9
+ # This method takes no options.
10
+ #
11
+ # @param [String] content The content to filter
12
+ #
13
+ # @return [String] The filtered content
14
+ def run(content, params={})
15
+ ::BlueCloth.new(content).to_html
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+
3
+ require 'coderay'
4
+
5
+ module Nanoc::Filters
6
+ class CodeRay < Nanoc::Filter
7
+
8
+ # @deprecated Use the `:colorize_syntax` filter instead.
9
+ def run(content, params={})
10
+ # Warn
11
+ warn 'The :coderay filter is deprecated; consider using the :colorize_syntax filter instead.'
12
+
13
+ # Check params
14
+ raise ArgumentError, "CodeRay filter requires a :language argument which is missing" if params[:language].nil?
15
+
16
+ # Get result
17
+ ::CodeRay.scan(content, params[:language]).html
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,20 @@
1
+ require 'coffee-script'
2
+
3
+ module Nanoc::Filters
4
+
5
+ # @since 3.3.0
6
+ class CoffeeScript < Nanoc::Filter
7
+
8
+ # Runs the content through [CoffeeScript](http://coffeescript.org/).
9
+ # This method takes no options.
10
+ #
11
+ # @param [String] content The CoffeeScript content to turn into JavaScript
12
+ #
13
+ # @return [String] The resulting JavaScript
14
+ def run(content, params = {})
15
+ ::CoffeeScript.compile(content)
16
+ end
17
+
18
+ end
19
+
20
+ end
@@ -0,0 +1,298 @@
1
+ # encoding: utf-8
2
+
3
+ require 'nokogiri'
4
+ require 'stringio'
5
+ require 'open3'
6
+
7
+ module Nanoc::Filters
8
+ class ColorizeSyntax < Nanoc::Filter
9
+
10
+ # The default colorizer to use for a language if the colorizer for that
11
+ # language is not overridden.
12
+ DEFAULT_COLORIZER = :coderay
13
+
14
+ # Syntax-highlights code blocks in the given content. Code blocks should
15
+ # be enclosed in `pre` elements that contain a `code` element. The code
16
+ # element should have an indication of the language the code is in. There
17
+ # are two possible ways of adding such an indication:
18
+ #
19
+ # 1. A HTML class starting with `language-` and followed by the
20
+ # code language, as specified by HTML5. For example, `<code class="language-ruby">`.
21
+ #
22
+ # 2. A comment on the very first line of the code block in the format
23
+ # `#!language` where `language` is the language the code is in. For
24
+ # example, `#!ruby`.
25
+ #
26
+ # Options for individual colorizers will be taken from the {#run}
27
+ # options’ value for the given colorizer. For example, if the filter is
28
+ # invoked with a `:coderay => coderay_options_hash` option, the
29
+ # `coderay_options_hash` hash will be passed to the CodeRay colorizer.
30
+ #
31
+ # Currently, the following colorizers are supported:
32
+ #
33
+ # * `:coderay` for [Coderay](http://coderay.rubychan.de/)
34
+ # * `:pygmentize` for [pygmentize](http://pygments.org/docs/cmdline/), the
35
+ # commandline frontend for [Pygments](http://pygments.org/)
36
+ # * `:pygmentsrb` for [pygments.rb](https://github.com/tmm1/pygments.rb),
37
+ # a Ruby interface for [Pygments](http://pygments.org/)
38
+ # * `:simon_highlight` for [Highlight](http://www.andre-simon.de/doku/highlight/en/highlight.html)
39
+ #
40
+ # Additional colorizer implementations are welcome!
41
+ #
42
+ # @example Using a class to indicate type of code be highlighted
43
+ #
44
+ # <pre><code class="language-ruby">
45
+ # def foo
46
+ # "asdf"
47
+ # end
48
+ # </code></pre>
49
+ #
50
+ # @example Using a comment to indicate type of code be highlighted
51
+ #
52
+ # <pre><code>
53
+ # #!ruby
54
+ # def foo
55
+ # "asdf"
56
+ # end
57
+ # </code></pre>
58
+ #
59
+ # @example Invoking the filter with custom parameters
60
+ #
61
+ # filter :colorize_syntax,
62
+ # :colorizers => { :ruby => :coderay },
63
+ # :coderay => { :line_numbers => :list }
64
+ #
65
+ # @param [String] content The content to filter
66
+ #
67
+ # @option params [Symbol] :default_colorizer (DEFAULT_COLORIZER) The
68
+ # default colorizer, i.e. the colorizer that will be used when the
69
+ # colorizer is not overriden for a specific language.
70
+ #
71
+ # @option params [Symbol] :syntax (:html) The syntax to use, which can be
72
+ # `:html`, `:xml` or `:xhtml`, the latter two being the same.
73
+ #
74
+ # @option params [Hash] :colorizers ({}) A hash containing
75
+ # a mapping of programming languages (symbols, not strings) onto
76
+ # colorizers (symbols).
77
+ #
78
+ # @option params [Boolean] :outside_pre (false) `true` if the colorizer
79
+ # should be applied on `code` elements outside `pre` elements, false
80
+ # if only `code` elements inside` pre` elements should be colorized.
81
+ #
82
+ # @option params [Symbol] :is_fullpage (false) Whether to treat the input
83
+ # as a full HTML page or a page fragment. When true, HTML boilerplate
84
+ # such as the doctype, `html`, `head` and `body` elements will be added.
85
+ #
86
+ # @return [String] The filtered content
87
+ def run(content, params={})
88
+ # Take colorizers from parameters
89
+ @colorizers = Hash.new(params[:default_colorizer] || DEFAULT_COLORIZER)
90
+ (params[:colorizers] || {}).each_pair do |language, colorizer|
91
+ @colorizers[language] = colorizer
92
+ end
93
+
94
+ # Determine syntax (HTML or XML)
95
+ syntax = params[:syntax] || :html
96
+ case syntax
97
+ when :html
98
+ klass = Nokogiri::HTML
99
+ when :xml, :xhtml
100
+ klass = Nokogiri::XML
101
+ else
102
+ raise RuntimeError, "unknown syntax: #{syntax.inspect} (expected :html or :xml)"
103
+ end
104
+
105
+ # Colorize
106
+ is_fullpage = params.fetch(:is_fullpage) { false }
107
+ doc = is_fullpage ? klass.parse(content, nil, 'UTF-8') : klass.fragment(content)
108
+ selector = params[:outside_pre] ? 'code' : 'pre > code'
109
+ doc.css(selector).each do |element|
110
+ # Get language
111
+ has_class = false
112
+ language = nil
113
+ if element['class']
114
+ # Get language from class
115
+ match = element['class'].match(/(^| )language-([^ ]+)/)
116
+ language = match[2] if match
117
+ has_class = true if language
118
+ else
119
+ # Get language from comment line
120
+ match = element.inner_text.match(/^#!([^\/][^\n]*)$/)
121
+ language = match[1] if match
122
+ element.content = element.content.sub(/^#!([^\/][^\n]*)$\n/, '') if language
123
+ end
124
+
125
+ # Give up if there is no hope left
126
+ next if language.nil?
127
+
128
+ # Highlight
129
+ raw = strip(element.inner_text)
130
+ highlighted_code = highlight(raw, language, params)
131
+ element.children = Nokogiri::HTML.fragment(strip(highlighted_code), 'utf-8')
132
+
133
+ # Add class
134
+ unless has_class
135
+ klass = element['class'] || ''
136
+ klass << ' ' unless [' ', nil].include?(klass[-1,1])
137
+ klass << "language-#{language}"
138
+ element['class'] = klass
139
+ end
140
+ end
141
+
142
+ method = "to_#{syntax}".to_sym
143
+ doc.send(method, :encoding => 'UTF-8')
144
+ end
145
+
146
+ private
147
+
148
+ KNOWN_COLORIZERS = [ :coderay, :dummy, :pygmentize, :pygmentsrb, :simon_highlight ]
149
+
150
+ # Removes the first blank lines and any whitespace at the end.
151
+ def strip(s)
152
+ s.lines.drop_while { |line| line.strip.empty? }.join.rstrip
153
+ end
154
+
155
+ def highlight(code, language, params={})
156
+ colorizer = @colorizers[language.to_sym]
157
+ if KNOWN_COLORIZERS.include?(colorizer)
158
+ send(colorizer, code, language, params[colorizer] || {})
159
+ else
160
+ raise RuntimeError, "I don’t know how to highlight code using the “#{colorizer}” colorizer"
161
+ end
162
+ end
163
+
164
+ # Runs the code through [CodeRay](http://coderay.rubychan.de/).
165
+ #
166
+ # @api private
167
+ #
168
+ # @param [String] code The code to colorize
169
+ #
170
+ # @param [String] language The language the code is written in
171
+ #
172
+ # @param [Hash] params Parameters to pass on to CodeRay
173
+ #
174
+ # @return [String] The colorized output
175
+ def coderay(code, language, params={})
176
+ require 'coderay'
177
+
178
+ ::CodeRay.scan(code, language).html(params)
179
+ end
180
+
181
+ # Returns the input itself, not performing any code highlighting.
182
+ #
183
+ # @param [String] code The code to colorize
184
+ #
185
+ # @param [String] language The language the code is written in (unused)
186
+ #
187
+ # @return [String] The colorized output, which is identical to the input
188
+ # in this case
189
+ def dummy(code, language, params={})
190
+ code
191
+ end
192
+
193
+ # Runs the content through [pygmentize](http://pygments.org/docs/cmdline/),
194
+ # the commandline frontend for [Pygments](http://pygments.org/).
195
+ #
196
+ # @api private
197
+ #
198
+ # @param [String] code The code to colorize
199
+ #
200
+ # @param [String] language The language the code is written in
201
+ #
202
+ # @option params [String, Symbol] :encoding The encoding of the code block
203
+ #
204
+ # @return [String] The colorized output
205
+ def pygmentize(code, language, params={})
206
+ require 'systemu'
207
+ check_availability('pygmentize', '-V')
208
+
209
+ params[:encoding] ||= 'utf-8'
210
+ params[:nowrap] ||= 'True'
211
+
212
+ # Build command
213
+ cmd = [ 'pygmentize', '-l', language, '-f', 'html' ]
214
+ cmd << '-O' << params.map { |k,v| "#{k}=#{v}" }.join(',') unless params.empty?
215
+
216
+ # Run command
217
+ stdout = StringIO.new
218
+ systemu cmd, 'stdin' => code, 'stdout' => stdout
219
+
220
+ # Get result
221
+ stdout.rewind
222
+ stdout.read
223
+ end
224
+
225
+ # Runs the content through [Pygments](http://pygments.org/) via
226
+ # [pygments.rb](https://github.com/tmm1/pygments.rb).
227
+ #
228
+ # @api private
229
+ #
230
+ # @param [String] code The code to colorize
231
+ #
232
+ # @param [String] language The language the code is written in
233
+ #
234
+ # @return [String] The colorized output
235
+ def pygmentsrb(code, language, params={})
236
+ require 'pygments'
237
+
238
+ args = params.dup
239
+ args[:lexer] ||= language
240
+ args[:options] ||= {}
241
+ args[:options][:encoding] ||= 'utf-8'
242
+ args[:options][:nowrap] ||= 'True'
243
+
244
+ Pygments.highlight(code, args)
245
+ end
246
+
247
+ SIMON_HIGHLIGHT_OPT_MAP = {
248
+ :wrap => '-W',
249
+ :include_style => '-I',
250
+ :line_numbers => '-l',
251
+ }
252
+
253
+ # Runs the content through [Highlight](http://www.andre-simon.de/doku/highlight/en/highlight.html).
254
+ #
255
+ # @api private
256
+ #
257
+ # @param [String] code The code to colorize
258
+ #
259
+ # @param [String] language The language the code is written in
260
+ #
261
+ # @option params [String] :style The style to use
262
+ #
263
+ # @since 3.2.0
264
+ def simon_highlight(code, language, params={})
265
+ require 'systemu'
266
+
267
+ check_availability('highlight', '--version')
268
+
269
+ # Build command
270
+ cmd = [ 'highlight', '--syntax', language, '--fragment' ]
271
+ params.each do |key, value|
272
+ if SIMON_HIGHLIGHT_OPT_MAP[key]
273
+ cmd << SIMON_HIGHLIGHT_OPT_MAP[key]
274
+ else
275
+ # TODO allow passing other options
276
+ case key
277
+ when :style
278
+ cmd << '--style' << params[:style]
279
+ end
280
+ end
281
+ end
282
+
283
+ # Run command
284
+ stdout = StringIO.new
285
+ systemu cmd, 'stdin' => code, 'stdout' => stdout
286
+
287
+ # Get result
288
+ stdout.rewind
289
+ stdout.read
290
+ end
291
+
292
+ def check_availability(*cmd)
293
+ systemu cmd
294
+ raise "Could not spawn #{cmd.join(' ')}" if $?.exitstatus != 0
295
+ end
296
+
297
+ end
298
+ end