|
9 | 9 | # “content/about.html”). To select all children, grandchildren, … of an |
10 | 10 | # item, use the pattern “/about/*/”; “/about/*” will also select the parent, |
11 | 11 | # because “*” matches zero or more characters. |
12 | | -# |
13 | | -# routes define what file should be served for a certain request |
14 | | -# |
15 | | -# compiles define how the content for a given route should be prepared |
16 | | - |
17 | | -route '/assets/*/' do |
18 | | - # when the request is for /assets/* |
19 | | - # (e.g. '/assets/css/style.css') ... |
20 | | - # this is the file to return, so we |
21 | | - # return the item's identifier (e.g. '/assets/css/style/') |
22 | | - # but chop off its last character ('/assets/css/style') |
23 | | - # and then append the item's extension ('css') |
24 | | - item.identifier.chop + '.' + item[:extension] |
| 12 | + |
| 13 | +require "cgi" |
| 14 | + |
| 15 | +class Nanoc3::Filter |
| 16 | + class CodeBlocks < Nanoc3::Filter |
| 17 | + LANGUAGES = { "ruby" => "ruby", "sql" => "sql", "javascript" => "javascript", |
| 18 | + "css" => "css", "plain" => "plain", "erb" => "ruby; html-script: true", |
| 19 | + "html" => "xml", "xml" => "xml", "shell" => "plain", "yaml" => "yaml" } |
| 20 | + |
| 21 | + def run(content, params={}) |
| 22 | + @string = content.dup |
| 23 | + |
| 24 | + @output = "" |
| 25 | + @pending = "" |
| 26 | + |
| 27 | + languages = LANGUAGES.keys.join("|") |
| 28 | + |
| 29 | + until @string.empty? |
| 30 | + match = scan_until /(\+(\S.*?\S?)\+|<(#{languages})(?: filename=["']([^"']*)["'])?>|\z)/m |
| 31 | + |
| 32 | + @pending << match.pre_match |
| 33 | + |
| 34 | + if match[2] # +foo+ |
| 35 | + @pending << "<notextile><tt>#{CGI.escapeHTML(match[2])}</tt></notextile>" if match[2] |
| 36 | + elsif match[3] # <language> |
| 37 | + flush |
| 38 | + generate_brushes match[3], LANGUAGES[match[3]], match[4] |
| 39 | + end |
| 40 | + end |
| 41 | + |
| 42 | + flush |
| 43 | + |
| 44 | + @output |
| 45 | + end |
| 46 | + |
| 47 | + def scan_until(regex) |
| 48 | + match = @string.match(regex) |
| 49 | + return unless match |
| 50 | + @string = match.post_match |
| 51 | + match |
| 52 | + end |
| 53 | + |
| 54 | + def generate_brushes(tag, replace, filename) |
| 55 | + match = scan_until %r{</#{tag}>} |
| 56 | + @output << %{<div class="code_container">\n} |
| 57 | + @output << %{<div class="filename">#{filename}</div>\n} if filename |
| 58 | + @output << %{<pre class="brush: #{replace}; gutter: false; toolbar: false">\n} << |
| 59 | + CGI.escapeHTML(match.pre_match) << %{</pre></div>} |
| 60 | + end |
| 61 | + |
| 62 | + def flush |
| 63 | + @output << @pending |
| 64 | + @pending = "" |
| 65 | + end |
| 66 | + end |
| 67 | +end |
| 68 | + |
| 69 | +Nanoc3::Filter.register 'CodeBlocks', :code_blocks |
| 70 | + |
| 71 | + |
| 72 | + |
| 73 | +compile '/assets/*' do |
| 74 | + # don’t filter or layout |
25 | 75 | end |
26 | 76 |
|
27 | | -compile '/assets/*/' do |
28 | | - # for assets, we don't want to do anything |
29 | | - nil |
| 77 | +compile '/images/*' do |
30 | 78 | end |
31 | 79 |
|
32 | | -# these rules only apply if none of the rules above apply |
| 80 | +filters = { |
| 81 | + :markdown => :kramdown, |
| 82 | + :md => :kramdown, |
| 83 | + :html => :erb |
| 84 | +} |
33 | 85 |
|
34 | 86 | compile '*' do |
35 | | - # for most things, we want to run them through kramdown |
36 | | - filter :kramdown |
| 87 | + filter :code_blocks |
| 88 | + filter filters[item[:extension].to_sym] || item[:extension].to_sym |
37 | 89 | layout 'default' |
38 | 90 | end |
39 | 91 |
|
40 | 92 | route '*' do |
41 | | - # for most things, we want to return the index.html |
42 | | - # that corresponds with the identifier |
43 | | - item.identifier + 'index.html' |
| 93 | + p [item.identifier, item[:extension], item.binary?] |
| 94 | + if item.binary? || item[:extension] == 'css' || item[:extension] =~ /\.js$/ |
| 95 | + # /foo/ -> /foo.ext |
| 96 | + p item.identifier.chop + '.' + item[:extension] |
| 97 | + item.identifier.chop + '.' + item[:extension] |
| 98 | + else |
| 99 | + # /foo/ -> /foo/index.html |
| 100 | + item.identifier + 'index.html' |
| 101 | + end |
44 | 102 | end |
45 | 103 |
|
46 | 104 | layout '*', :erb |
| 105 | + |
0 commit comments