nanoc 3.2.4 → 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
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