nanoc3 3.2.0a3 → 3.2.0a4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. data/.gemtest +0 -0
  2. data/LICENSE +1 -1
  3. data/NEWS.md +23 -4
  4. data/README.md +7 -0
  5. data/lib/nanoc3/base/compilation/checksum_store.rb +17 -90
  6. data/lib/nanoc3/base/compilation/compiled_content_cache.rb +5 -0
  7. data/lib/nanoc3/base/compilation/compiler.rb +112 -175
  8. data/lib/nanoc3/base/compilation/compiler_dsl.rb +54 -11
  9. data/lib/nanoc3/base/compilation/dependency_tracker.rb +32 -65
  10. data/lib/nanoc3/base/compilation/filter.rb +4 -3
  11. data/lib/nanoc3/base/compilation/item_rep_proxy.rb +19 -4
  12. data/lib/nanoc3/base/compilation/item_rep_recorder_proxy.rb +90 -0
  13. data/lib/nanoc3/base/compilation/outdatedness_checker.rb +152 -15
  14. data/lib/nanoc3/base/compilation/outdatedness_reasons.rb +12 -9
  15. data/lib/nanoc3/base/compilation/rule.rb +3 -1
  16. data/lib/nanoc3/base/compilation/rule_memory_calculator.rb +42 -0
  17. data/lib/nanoc3/base/compilation/rule_memory_store.rb +53 -0
  18. data/lib/nanoc3/base/compilation/rules_collection.rb +205 -0
  19. data/lib/nanoc3/base/core_ext/array.rb +20 -0
  20. data/lib/nanoc3/base/core_ext/hash.rb +30 -0
  21. data/lib/nanoc3/base/core_ext/pathname.rb +26 -0
  22. data/lib/nanoc3/base/core_ext/string.rb +12 -0
  23. data/lib/nanoc3/base/core_ext.rb +1 -0
  24. data/lib/nanoc3/base/directed_graph.rb +11 -3
  25. data/lib/nanoc3/base/errors.rb +0 -4
  26. data/lib/nanoc3/base/memoization.rb +72 -0
  27. data/lib/nanoc3/base/result_data/item_rep.rb +64 -25
  28. data/lib/nanoc3/base/source_data/code_snippet.rb +9 -0
  29. data/lib/nanoc3/base/source_data/configuration.rb +20 -0
  30. data/lib/nanoc3/base/source_data/item.rb +29 -4
  31. data/lib/nanoc3/base/source_data/layout.rb +20 -1
  32. data/lib/nanoc3/base/source_data/site.rb +49 -26
  33. data/lib/nanoc3/base/store.rb +10 -1
  34. data/lib/nanoc3/base.rb +6 -1
  35. data/lib/nanoc3/cli/base.rb +20 -7
  36. data/lib/nanoc3/cli/commands/compile.rb +0 -2
  37. data/lib/nanoc3/cli/commands/create_site.rb +16 -7
  38. data/lib/nanoc3/cli/commands/debug.rb +3 -3
  39. data/lib/nanoc3/cli/commands/view.rb +1 -0
  40. data/lib/nanoc3/cli/commands/watch.rb +2 -1
  41. data/lib/nanoc3/data_sources/deprecated/delicious.rb +0 -2
  42. data/lib/nanoc3/data_sources/deprecated/last_fm.rb +0 -2
  43. data/lib/nanoc3/data_sources/deprecated/twitter.rb +0 -2
  44. data/lib/nanoc3/data_sources/filesystem.rb +17 -3
  45. data/lib/nanoc3/data_sources/filesystem_unified.rb +17 -17
  46. data/lib/nanoc3/extra/auto_compiler.rb +5 -1
  47. data/lib/nanoc3/extra/core_ext/time.rb +1 -1
  48. data/lib/nanoc3/extra/file_proxy.rb +11 -1
  49. data/lib/nanoc3/extra/validators/links.rb +1 -1
  50. data/lib/nanoc3/filters/asciidoc.rb +3 -3
  51. data/lib/nanoc3/filters/colorize_syntax.rb +106 -27
  52. data/lib/nanoc3/filters/erb.rb +16 -6
  53. data/lib/nanoc3/filters/erubis.rb +5 -1
  54. data/lib/nanoc3/filters/haml.rb +2 -1
  55. data/lib/nanoc3/filters/less.rb +3 -6
  56. data/lib/nanoc3/filters/mustache.rb +3 -0
  57. data/lib/nanoc3/filters/redcarpet.rb +27 -0
  58. data/lib/nanoc3/filters/sass.rb +1 -5
  59. data/lib/nanoc3/filters/slim.rb +25 -0
  60. data/lib/nanoc3/filters/typogruby.rb +23 -0
  61. data/lib/nanoc3/filters.rb +6 -0
  62. data/lib/nanoc3/helpers/blogging.rb +22 -26
  63. data/lib/nanoc3/helpers/rendering.rb +1 -1
  64. data/lib/nanoc3/helpers/xml_sitemap.rb +11 -2
  65. data/lib/nanoc3.rb +24 -3
  66. data/nanoc3.gemspec +4 -3
  67. data/tasks/clean.rake +11 -0
  68. data/tasks/doc.rake +14 -0
  69. data/tasks/test.rake +38 -0
  70. data/test/base/core_ext/array_spec.rb +55 -0
  71. data/test/base/core_ext/hash_spec.rb +82 -0
  72. data/test/base/core_ext/pathname_spec.rb +29 -0
  73. data/test/base/core_ext/string_spec.rb +39 -0
  74. data/test/base/test_checksum_store.rb +37 -0
  75. data/test/base/test_code_snippet.rb +33 -0
  76. data/test/base/test_compiler.rb +303 -0
  77. data/test/base/test_compiler_dsl.rb +156 -0
  78. data/test/base/test_context.rb +33 -0
  79. data/test/base/test_data_source.rb +48 -0
  80. data/test/base/test_dependency_tracker.rb +264 -0
  81. data/test/base/test_directed_graph.rb +285 -0
  82. data/test/base/test_filter.rb +85 -0
  83. data/test/base/test_item.rb +164 -0
  84. data/test/base/test_item_rep.rb +555 -0
  85. data/test/base/test_layout.rb +44 -0
  86. data/test/base/test_memoization.rb +53 -0
  87. data/test/base/test_notification_center.rb +36 -0
  88. data/test/base/test_outdatedness_checker.rb +365 -0
  89. data/test/base/test_plugin.rb +32 -0
  90. data/test/base/test_rule.rb +21 -0
  91. data/test/base/test_rule_context.rb +67 -0
  92. data/test/base/test_site.rb +144 -0
  93. data/test/cli/commands/test_compile.rb +12 -0
  94. data/test/cli/commands/test_create_item.rb +12 -0
  95. data/test/cli/commands/test_create_layout.rb +28 -0
  96. data/test/cli/commands/test_create_site.rb +24 -0
  97. data/test/cli/commands/test_help.rb +12 -0
  98. data/test/cli/commands/test_info.rb +12 -0
  99. data/test/cli/commands/test_update.rb +12 -0
  100. data/test/cli/test_logger.rb +12 -0
  101. data/test/data_sources/test_filesystem.rb +420 -0
  102. data/test/data_sources/test_filesystem_unified.rb +562 -0
  103. data/test/data_sources/test_filesystem_verbose.rb +359 -0
  104. data/test/extra/core_ext/test_enumerable.rb +32 -0
  105. data/test/extra/core_ext/test_time.rb +17 -0
  106. data/test/extra/deployers/test_rsync.rb +234 -0
  107. data/test/extra/test_auto_compiler.rb +417 -0
  108. data/test/extra/test_file_proxy.rb +21 -0
  109. data/test/extra/test_vcs.rb +24 -0
  110. data/test/extra/validators/test_links.rb +53 -0
  111. data/test/extra/validators/test_w3c.rb +49 -0
  112. data/test/filters/test_asciidoc.rb +22 -0
  113. data/test/filters/test_bluecloth.rb +20 -0
  114. data/test/filters/test_coderay.rb +46 -0
  115. data/test/filters/test_colorize_syntax.rb +149 -0
  116. data/test/filters/test_erb.rb +101 -0
  117. data/test/filters/test_erubis.rb +72 -0
  118. data/test/filters/test_haml.rb +98 -0
  119. data/test/filters/test_kramdown.rb +20 -0
  120. data/test/filters/test_less.rb +59 -0
  121. data/test/filters/test_markaby.rb +26 -0
  122. data/test/filters/test_maruku.rb +20 -0
  123. data/test/filters/test_mustache.rb +27 -0
  124. data/test/filters/test_rainpress.rb +31 -0
  125. data/test/filters/test_rdiscount.rb +33 -0
  126. data/test/filters/test_rdoc.rb +18 -0
  127. data/test/filters/test_redcarpet.rb +63 -0
  128. data/test/filters/test_redcloth.rb +35 -0
  129. data/test/filters/test_relativize_paths.rb +231 -0
  130. data/test/filters/test_rubypants.rb +20 -0
  131. data/test/filters/test_sass.rb +103 -0
  132. data/test/filters/test_slim.rb +37 -0
  133. data/test/filters/test_typogruby.rb +23 -0
  134. data/test/helper.rb +161 -0
  135. data/test/helpers/test_blogging.rb +756 -0
  136. data/test/helpers/test_breadcrumbs.rb +83 -0
  137. data/test/helpers/test_capturing.rb +43 -0
  138. data/test/helpers/test_filtering.rb +108 -0
  139. data/test/helpers/test_html_escape.rb +34 -0
  140. data/test/helpers/test_link_to.rb +251 -0
  141. data/test/helpers/test_rendering.rb +90 -0
  142. data/test/helpers/test_tagging.rb +89 -0
  143. data/test/helpers/test_text.rb +26 -0
  144. data/test/helpers/test_xml_sitemap.rb +105 -0
  145. data/test/tasks/test_clean.rb +69 -0
  146. metadata +96 -27
  147. data/lib/nanoc3/base/compilation/checksummer.rb +0 -68
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Nanoc3::CLI::Commands
4
4
 
5
+ # @since 3.2.0
5
6
  class Watch < Cri::Command
6
7
 
7
8
  def name
@@ -92,7 +93,7 @@ module Nanoc3::CLI::Commands
92
93
 
93
94
  # Watch
94
95
  puts "Watching for changes…".make_compatible_with_env
95
- watcher = lambda do
96
+ watcher = lambda do |*args|
96
97
  update(&rebuilder)
97
98
  delete(&rebuilder)
98
99
  create(&rebuilder)
@@ -8,8 +8,6 @@ module Nanoc3::DataSources
8
8
  def items
9
9
  @items ||= begin
10
10
  require 'json'
11
- require 'time'
12
- require 'enumerator'
13
11
 
14
12
  # Get data
15
13
  @http_client ||= Nanoc3::Extra::CHiCk::Client.new
@@ -8,9 +8,7 @@ module Nanoc3::DataSources
8
8
  def items
9
9
  @items ||= begin
10
10
  require 'json'
11
- require 'time'
12
11
  require 'uri'
13
- require 'enumerator'
14
12
 
15
13
  # Check configuration
16
14
  if self.config[:username].nil?
@@ -8,8 +8,6 @@ module Nanoc3::DataSources
8
8
  def items
9
9
  @item ||= begin
10
10
  require 'json'
11
- require 'time'
12
- require 'enumerator'
13
11
 
14
12
  # Get data
15
13
  @http_client ||= Nanoc3::Extra::CHiCk::Client.new
@@ -228,14 +228,14 @@ module Nanoc3::DataSources
228
228
  def parse(content_filename, meta_filename, kind)
229
229
  # Read content and metadata from separate files
230
230
  if meta_filename
231
- content = content_filename ? File.read(content_filename) : ''
232
- meta = YAML.load_file(meta_filename) || {}
231
+ content = content_filename ? read(content_filename) : ''
232
+ meta = YAML.load(read(meta_filename)) || {}
233
233
 
234
234
  return [ meta, content ]
235
235
  end
236
236
 
237
237
  # Read data
238
- data = File.read(content_filename)
238
+ data = read(content_filename)
239
239
 
240
240
  # Check presence of metadata section
241
241
  if data !~ /\A-{3,5}\s*$/
@@ -258,6 +258,20 @@ module Nanoc3::DataSources
258
258
  [ meta, content ]
259
259
  end
260
260
 
261
+ # Reads the content of the file with the given name and returns a string
262
+ # in UTF-8 encoding. The original encoding of the string is derived from
263
+ # the default external encoding, but this can be overridden by the
264
+ # “encoding” configuration attribute in the data source configuration.
265
+ def read(filename)
266
+ data = File.read(filename)
267
+ if data.respond_to?(:encode)
268
+ data.force_encoding(@config[:encoding]) if @config && @config[:encoding]
269
+ data.encode('UTF-8')
270
+ else
271
+ data
272
+ end
273
+ end
274
+
261
275
  end
262
276
 
263
277
  end
@@ -14,10 +14,10 @@ module Nanoc3::DataSources
14
14
  # itself can start with a metadata section: it can be stored at the top of
15
15
  # the file, between `---` (three dashes) separators. For example:
16
16
  #
17
- # ---
18
- # title: "Moo!"
19
- # ---
20
- # h1. Hello!
17
+ # ---
18
+ # title: "Moo!"
19
+ # ---
20
+ # h1. Hello!
21
21
  #
22
22
  # The metadata section can be omitted. If the file does not start with
23
23
  # three or five dashes, the entire file will be considered as content.
@@ -26,7 +26,7 @@ module Nanoc3::DataSources
26
26
  # an `index.*` filename, such as `index.txt`, will have the filesystem path
27
27
  # with the `index.*` part stripped as a identifier. For example:
28
28
  #
29
- # foo/bar/index.html → /foo/bar/
29
+ # foo/bar/index.html → /foo/bar/
30
30
  #
31
31
  # In other cases, the identifier is calculated by stripping the extension.
32
32
  # If the `allow_periods_in_identifiers` attribute in the configuration is
@@ -34,24 +34,24 @@ module Nanoc3::DataSources
34
34
  # extensions; if it is false or unset, all extensions will be stripped.
35
35
  # For example:
36
36
  #
37
- # (`allow_periods_in_identifiers` set to true)
38
- # foo.entry.html → /foo.entry/
39
- #
40
- # (`allow_periods_in_identifiers` set to false)
41
- # foo.html.erb → /foo/
37
+ # (`allow_periods_in_identifiers` set to true)
38
+ # foo.entry.html → /foo.entry/
39
+ #
40
+ # (`allow_periods_in_identifiers` set to false)
41
+ # foo.html.erb → /foo/
42
42
  #
43
43
  # Note that it is possible for two different, separate files to have the
44
44
  # same identifier. It is recommended to avoid such situations.
45
45
  #
46
46
  # Some more examples:
47
47
  #
48
- # content/index.html → /
49
- # content/foo.html → /foo/
50
- # content/foo/index.html → /foo/
51
- # content/foo/bar.html → /foo/bar/
52
- # content/foo/bar.baz.html → /foo/bar/ OR /foo/bar.baz/
53
- # content/foo/bar/index.html → /foo/bar/
54
- # content/foo.bar/index.html → /foo.bar/
48
+ # content/index.html → /
49
+ # content/foo.html → /foo/
50
+ # content/foo/index.html → /foo/
51
+ # content/foo/bar.html → /foo/bar/
52
+ # content/foo/bar.baz.html → /foo/bar/ OR /foo/bar.baz/
53
+ # content/foo/bar/index.html → /foo/bar/
54
+ # content/foo.bar/index.html → /foo.bar/
55
55
  #
56
56
  # The file extension does not determine the filters to run on items; the
57
57
  # Rules file is used to specify processing instructors for each item.
@@ -66,7 +66,7 @@ module Nanoc3::Extra
66
66
  rescue StandardError, ScriptError => e
67
67
  # Add compilation stack to env
68
68
  env['nanoc.stack'] = []
69
- site.compiler.stack.reverse.each do |obj|
69
+ stack.reverse.each do |obj|
70
70
  if obj.is_a?(Nanoc3::ItemRep) # item rep
71
71
  env['nanoc.stack'] << "[item] #{obj.item.identifier} (rep #{obj.name})"
72
72
  else # layout
@@ -93,6 +93,10 @@ module Nanoc3::Extra
93
93
  @file_server ||= ::Rack::File.new(site.config[:output_dir])
94
94
  end
95
95
 
96
+ def stack
97
+ site.compiler.stack
98
+ end
99
+
96
100
  end
97
101
 
98
102
  end
@@ -9,7 +9,7 @@ module Nanoc3::Extra::TimeExtensions
9
9
 
10
10
  # @return [String] The time in an ISO-8601 time format.
11
11
  def to_iso8601_time
12
- self.gmtime.strftime("%Y-%m-%dT%H:%M:%SZ")
12
+ self.getutc.strftime("%Y-%m-%dT%H:%M:%SZ")
13
13
  end
14
14
 
15
15
  end
@@ -13,8 +13,12 @@ module Nanoc3::Extra
13
13
  @path = path
14
14
  end
15
15
 
16
+ def freeze
17
+ super
18
+ end
19
+
16
20
  def respond_to?(meth)
17
- File.instance_methods.any? { |m| m == meth.to_s || m == meth.to_sym }
21
+ file_instance_methods.include?(meth.to_sym)
18
22
  end
19
23
 
20
24
  def method_missing(sym, *args, &block)
@@ -26,6 +30,12 @@ module Nanoc3::Extra
26
30
  File.open(@path, 'r') { |io| io.__send__(sym, *args, &block) }
27
31
  end
28
32
 
33
+ private
34
+
35
+ def file_instance_methods
36
+ @@file_instance_methods ||= Set.new(File.instance_methods.map { |m| m.to_sym })
37
+ end
38
+
29
39
  end
30
40
 
31
41
  end
@@ -166,7 +166,7 @@ module Nanoc3::Extra::Validators
166
166
  end
167
167
 
168
168
  # Skip non-HTTP URLs
169
- return true if uri.scheme != 'http'
169
+ return true if uri.scheme !~ /^https?$/
170
170
 
171
171
  # Get status
172
172
  status = fetch_http_status_for(uri)
@@ -1,10 +1,9 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Nanoc3::Filters
4
- class AsciiDoc < Nanoc3::Filter
5
4
 
6
- type :text
7
- identifier :asciidoc
5
+ # @since 3.2.0
6
+ class AsciiDoc < Nanoc3::Filter
8
7
 
9
8
  # Runs the content through [AsciiDoc](http://www.methods.co.nz/asciidoc/).
10
9
  # This method takes no options.
@@ -55,4 +54,5 @@ module Nanoc3::Filters
55
54
  end
56
55
 
57
56
  end
57
+
58
58
  end
@@ -9,8 +9,15 @@ module Nanoc3::Filters
9
9
 
10
10
  # Syntax-highlights code blocks in the given content. Code blocks should
11
11
  # be enclosed in `pre` elements that contain a `code` element. The code
12
- # element should have a class starting with `language-` and followed by
13
- # the programming language, as specified by HTML5.
12
+ # element should have an indication of the language the code is in. There
13
+ # are two possible ways of adding such an indication:
14
+ #
15
+ # 1. A HTML class starting with `language-` and followed by the
16
+ # code language, as specified by HTML5. For example, `<code class="language-ruby">`.
17
+ #
18
+ # 2. A comment on the very first line of the code block in the format
19
+ # `#!language` where `language` is the language the code is in. For
20
+ # example, `#!ruby`.
14
21
  #
15
22
  # Options for individual colorizers will be taken from the {#run}
16
23
  # options’ value for the given colorizer. For example, if the filter is
@@ -23,7 +30,7 @@ module Nanoc3::Filters
23
30
  # (http://www.andre-simon.de/doku/highlight/en/highlight.html) colorizers
24
31
  # are implemented. Additional colorizer implementations are welcome!
25
32
  #
26
- # @example Content that will be highlighted
33
+ # @example Using a class to indicate type of code be highlighted
27
34
  #
28
35
  # <pre><code class="language-ruby">
29
36
  # def foo
@@ -31,6 +38,15 @@ module Nanoc3::Filters
31
38
  # end
32
39
  # </code></pre>
33
40
  #
41
+ # @example Using a comment to indicate type of code be highlighted
42
+ #
43
+ # <pre><code>
44
+ # #!ruby
45
+ # def foo
46
+ # "asdf"
47
+ # end
48
+ # </code></pre>
49
+ #
34
50
  # @example Invoking the filter with custom parameters
35
51
  #
36
52
  # filter :colorize_syntax,
@@ -62,7 +78,7 @@ module Nanoc3::Filters
62
78
  case syntax
63
79
  when :html
64
80
  klass = Nokogiri::HTML
65
- when :xml
81
+ when :xml, :xhtml
66
82
  klass = Nokogiri::XML
67
83
  else
68
84
  raise RuntimeError, "unknown syntax: #{syntax.inspect} (expected :html or :xml)"
@@ -70,18 +86,40 @@ module Nanoc3::Filters
70
86
 
71
87
  # Colorize
72
88
  doc = klass.fragment(content)
73
- doc.css('pre > code[class*="language-"]').each do |element|
89
+ doc.css('pre > code').each do |element|
74
90
  # Get language
75
- match = element['class'].match(/(^| )language-([^ ]+)/)
76
- next if match.nil?
77
- language = match[2]
91
+ has_class = false
92
+ language = nil
93
+ if element['class']
94
+ # Get language from class
95
+ match = element['class'].match(/(^| )language-([^ ]+)/)
96
+ language = match[2] if match
97
+ has_class = true if language
98
+ else
99
+ # Get language from comment line
100
+ match = element.inner_text.match(/^#!([^\n]+)$/)
101
+ language = match[1] if match
102
+ element.content = element.content.sub(/^#!([^\n]+)$\n/, '') if language
103
+ end
104
+
105
+ # Give up if there is no hope left
106
+ next if language.nil?
78
107
 
79
108
  # Highlight
80
109
  highlighted_code = highlight(element.inner_text.strip, language, params)
81
110
  element.inner_html = highlighted_code.strip
111
+
112
+ # Add class
113
+ unless has_class
114
+ klass = element['class'] || ''
115
+ klass << ' ' unless [' ', nil].include?(klass[-1,1])
116
+ klass << "language-#{language}"
117
+ element['class'] = klass
118
+ end
82
119
  end
83
120
 
84
- doc.to_s
121
+ method = "to_#{syntax}".to_sym
122
+ doc.send(method, :encoding => 'UTF-8')
85
123
  end
86
124
 
87
125
  private
@@ -97,12 +135,31 @@ module Nanoc3::Filters
97
135
  end
98
136
  end
99
137
 
138
+ # Runs the code through [CodeRay](http://coderay.rubychan.de/).
139
+ #
140
+ # @api private
141
+ #
142
+ # @param [String] code The code to colorize
143
+ #
144
+ # @param [String] language The language the code is written in
145
+ #
146
+ # @param [Hash] params Parameters to pass on to CodeRay
147
+ #
148
+ # @return [String] The colorized output
100
149
  def coderay(code, language, params={})
101
150
  require 'coderay'
102
151
 
103
152
  ::CodeRay.scan(code, language).html(params)
104
153
  end
105
154
 
155
+ # Returns the input itself, not performing any code highlighting.
156
+ #
157
+ # @param [String] code The code to colorize
158
+ #
159
+ # @param [String] language The language the code is written in (unused)
160
+ #
161
+ # @return [String] The colorized output, which is identical to the input
162
+ # in this case
106
163
  def dummy(code, language, params={})
107
164
  code
108
165
  end
@@ -120,17 +177,24 @@ module Nanoc3::Filters
120
177
  #
121
178
  # @return [String] The colorized output
122
179
  def pygmentize(code, language, params={})
123
- enc = ""
124
- enc = "-O encoding=" + params[:encoding] if params[:encoding]
180
+ require 'stringio'
181
+ require 'systemu'
125
182
 
126
- IO.popen("pygmentize -l #{language} -f html #{enc}", "r+") do |io|
127
- io.write(code)
128
- io.close_write
129
- highlighted_code = io.read
183
+ # Build command
184
+ cmd = [ 'pygmentize', '-l', language, '-f', 'html' ]
185
+ cmd << '-O' << params.map { |k,v| "#{k}=#{v}" }.join(',') unless params.empty?
130
186
 
131
- doc = Nokogiri::HTML.fragment(highlighted_code)
132
- return doc.xpath('./div[@class="highlight"]/pre').inner_html
133
- end
187
+ # Run command
188
+ stdout = StringIO.new
189
+ systemu cmd, 'stdin' => code, 'stdout' => stdout
190
+
191
+ # Get result
192
+ stdout.rewind
193
+ highlighted_code = stdout.read
194
+
195
+ # Clean result
196
+ doc = Nokogiri::HTML.fragment(highlighted_code)
197
+ doc.xpath('./div[@class="highlight"]/pre').inner_html
134
198
  end
135
199
 
136
200
  SIMON_HIGHLIGHT_OPT_MAP = {
@@ -139,27 +203,42 @@ module Nanoc3::Filters
139
203
  :line_numbers => '-l',
140
204
  }
141
205
 
206
+ # Runs the content through [Highlight](http://www.andre-simon.de/doku/highlight/en/highlight.html).
207
+ #
208
+ # @api private
209
+ #
210
+ # @param [String] code The code to colorize
211
+ #
212
+ # @param [String] language The language the code is written in
213
+ #
214
+ # @option params [String] :style The style to use
215
+ #
216
+ # @since 3.2.0
142
217
  def simon_highlight(code, language, params={})
143
- opts = []
218
+ require 'stringio'
219
+ require 'systemu'
144
220
 
221
+ # Build command
222
+ cmd = [ 'highlight', '--syntax', language, '--fragment' ]
145
223
  params.each do |key, value|
146
224
  if SIMON_HIGHLIGHT_OPT_MAP[key]
147
- opts << SIMON_HIGHLIGHT_OPT_MAP[key]
225
+ cmd << SIMON_HIGHLIGHT_OPT_MAP[key]
148
226
  else
149
227
  # TODO allow passing other options
150
228
  case key
151
229
  when :style
152
- opts << "--style #{params[:style]}"
230
+ cmd << '--style' << params[:style]
153
231
  end
154
232
  end
155
233
  end
156
234
 
157
- commandline = "highlight --syntax #{language} --fragment #{opts.join(" ")} /dev/stdin"
158
- IO.popen(commandline, "r+") do |io|
159
- io.write(code)
160
- io.close_write
161
- return io.read
162
- end
235
+ # Run command
236
+ stdout = StringIO.new
237
+ systemu cmd, 'stdin' => code, 'stdout' => stdout
238
+
239
+ # Get result
240
+ stdout.rewind
241
+ stdout.read
163
242
  end
164
243
  end
165
244
  end
@@ -1,13 +1,17 @@
1
- # encoding: utf-8
1
+ # encoding: utf-8
2
2
 
3
3
  module Nanoc3::Filters
4
4
  class ERB < Nanoc3::Filter
5
5
 
6
6
  # Runs the content through [ERB](http://ruby-doc.org/stdlib/libdoc/erb/rdoc/classes/ERB.html).
7
- # This method takes no options.
8
7
  #
9
8
  # @param [String] content The content to filter
10
9
  #
10
+ # @option params [Integer] safe_level (nil) The safe level (`$SAFE`) to
11
+ # use while running this filter
12
+ #
13
+ # @option params [String] trim_mode (nil) The trim mode to use
14
+ #
11
15
  # @return [String] The filtered content
12
16
  def run(content, params={})
13
17
  require 'erb'
@@ -15,11 +19,17 @@ module Nanoc3::Filters
15
19
  # Create context
16
20
  context = ::Nanoc3::Context.new(assigns)
17
21
 
22
+ # Get binding
23
+ proc = assigns[:content] ? lambda { assigns[:content] } : nil
24
+ assigns_binding = context.get_binding(&proc)
25
+
18
26
  # Get result
19
- erb = ::ERB.new(content)
27
+ safe_level = params[:safe_level]
28
+ trim_mode = params[:trim_mode]
29
+ erb = ::ERB.new(content, safe_level, trim_mode)
20
30
  erb.filename = filename
21
- erb.result(context.get_binding { assigns[:content] })
22
- end
31
+ erb.result(assigns_binding)
32
+ end
23
33
 
24
- end
34
+ end
25
35
  end
@@ -15,8 +15,12 @@ module Nanoc3::Filters
15
15
  # Create context
16
16
  context = ::Nanoc3::Context.new(assigns)
17
17
 
18
+ # Get binding
19
+ proc = assigns[:content] ? lambda { assigns[:content] } : nil
20
+ assigns_binding = context.get_binding(&proc)
21
+
18
22
  # Get result
19
- ::Erubis::Eruby.new(content, :filename => filename).result(context.get_binding { assigns[:content] })
23
+ ::Erubis::Eruby.new(content, :filename => filename).result(assigns_binding)
20
24
  end
21
25
 
22
26
  end
@@ -19,7 +19,8 @@ module Nanoc3::Filters
19
19
  context = ::Nanoc3::Context.new(assigns)
20
20
 
21
21
  # Get result
22
- ::Haml::Engine.new(content, options).render(context, assigns) { assigns[:content] }
22
+ proc = assigns[:content] ? lambda { assigns[:content] } : nil
23
+ ::Haml::Engine.new(content, options).render(context, assigns, &proc)
23
24
  end
24
25
 
25
26
  end
@@ -13,12 +13,9 @@ module Nanoc3::Filters
13
13
  require 'less'
14
14
 
15
15
  # Add filename to load path
16
- $LESS_LOAD_PATH << File.dirname(@item[:content_filename])
17
-
18
- ::Less::Engine.new(content).to_css
19
- ensure
20
- # Restore load path
21
- $LESS_LOAD_PATH.delete_at(-1)
16
+ paths = [ File.dirname(@item[:content_filename]) ]
17
+ parser = ::Less::Parser.new(:paths => paths)
18
+ parser.parse(content).to_css
22
19
  end
23
20
 
24
21
  end
@@ -1,6 +1,8 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Nanoc3::Filters
4
+
5
+ # @since 3.2.0
4
6
  class Mustache < Nanoc3::Filter
5
7
 
6
8
  # Runs the content through
@@ -18,4 +20,5 @@ module Nanoc3::Filters
18
20
  end
19
21
 
20
22
  end
23
+
21
24
  end
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+
3
+ module Nanoc3::Filters
4
+
5
+ # @since 3.2.0
6
+ class Redcarpet < Nanoc3::Filter
7
+
8
+ # Runs the content through [Redcarpet](https://github.com/tanoku/redcarpet/).
9
+ # This method optionally takes processing options to pass on to Redcarpet.
10
+ #
11
+ # @param [String] content The content to filter
12
+ #
13
+ # @option params [Array] :options ([]) A list of options to pass on to
14
+ # Redcarpet
15
+ #
16
+ # @return [String] The filtered content
17
+ def run(content, params={})
18
+ require 'redcarpet'
19
+
20
+ options = params[:options] || []
21
+
22
+ ::Redcarpet.new(content, *options).to_html
23
+ end
24
+
25
+ end
26
+
27
+ end
@@ -28,7 +28,6 @@ module Nanoc3::Filters
28
28
  engine = ::Sass::Engine.new(content, options)
29
29
 
30
30
  # Get import nodes
31
- require 'set'
32
31
  imported_nodes = []
33
32
  unprocessed_nodes = Set.new([ engine.to_tree ])
34
33
  until unprocessed_nodes.empty?
@@ -46,10 +45,7 @@ module Nanoc3::Filters
46
45
  # Get import paths
47
46
  import_paths = (options[:load_paths] || []).dup
48
47
  import_paths.unshift(File.dirname(sass_filename)) if sass_filename
49
- # Get imported filenames
50
- imported_filenames = imported_nodes.map do |node|
51
- ::Sass::Files.find_file_to_import(node.imported_filename, import_paths)
52
- end
48
+ imported_filenames = imported_nodes.map { |node| node.imported_filename }
53
49
 
54
50
  # Convert to items
55
51
  imported_items = imported_filenames.map do |filename|
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ module Nanoc3::Filters
4
+
5
+ # @since 3.2.0
6
+ class Slim < Nanoc3::Filter
7
+
8
+ # Runs the content through [Slim](http://slim-lang.com/)
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
+ require 'slim'
16
+
17
+ # Create context
18
+ context = ::Nanoc3::Context.new(assigns)
19
+
20
+ ::Slim::Template.new { content }.render(context) { assigns[:content] }
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+
3
+ module Nanoc3::Filters
4
+
5
+ # @since 3.2.0
6
+ class Typogruby < Nanoc3::Filter
7
+
8
+ # Runs the content through [Typogruby](http://avdgaag.github.com/typogruby/).
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
+ require 'typogruby'
16
+
17
+ # Get result
18
+ ::Typogruby.improve(content)
19
+ end
20
+
21
+ end
22
+
23
+ end