Class: String

Inherits:
Object
  • Object
show all
Defined in:
lib/erbook/to_xhtml.rb

Constant Summary collapse

PROTECTED_TAGS =

The content of these XHTML tags will be preserved while they are being processed by Textile. By doing this, we avoid unwanted Textile transformations, such as quotation marks becoming curly ( ), in source code.

{
  :pre  => :block,    # tag => is it a block or inline element?
  :code => :inline,
  :tt   => :inline
}
VERBATIM_TAGS =

The content of these XHTML tags will be preserved verbatim throughout the text-to-XHTML conversion process.

{
  :noformat => :block # tag => is it a block or inline element?
}

Instance Method Summary collapse

Instance Method Details

#thru_coderayObject

Adds syntax coloring to <code> elements in this string.

Each <code> element is annotated with a class=“line” or a class=“para” attribute, according to whether it spans a single line or multiple lines of code.

In the latter case, the <code> element is replaced with a <pre> element so that its multi-line body appears correctly in text-mode web browsers.

If a <code> element has a lang=“…” attribute, then that attribute’s value is considered to be the programming language for which appropriate syntax coloring should be applied. Otherwise, the programming language is assumed to be ruby.



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/erbook/to_xhtml.rb', line 113

def thru_coderay #:nodoc:
  gsub %r{<(code)(.*?)>(.*?)</\1>}m do
    elem, atts, code = $1, $2, CGI.unescapeHTML($3).sub(/\A\r?\n/, '')

    lang_regexp = /\blang=('|")(.*?)\1/io
    lang = atts[lang_regexp, 2]
    lang = :ruby if lang !~ /\S/
    atts.sub! lang_regexp, %{lang="#{lang}"}

    body = CodeRay.scan(code, lang).html(:css => :style)

    if code =~ /\n/
      span = :para
      head = "<ins><pre"
      tail = "</pre></ins>"

    else
      span = :line
      head = "<#{elem}"
      tail = "</#{elem}>"
    end

    unless atts.sub!(/\b(class=('|"))(.*?\2)/){ $1 + span + ' ' + $3 }
      atts << %{ class="#{span}"}
    end

    %{#{head}#{atts}>#{body}#{tail}}
  end
end

#thru_marukuObject

Returns the result of running this string through Maruku.



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/erbook/to_xhtml.rb', line 80

def thru_maruku #:nodoc:
  #
  # XXX: add a newline at the beginning of the text to
  #      prevent Maruku from interpreting the first line
  #      of text as a parameter definition, which is the
  #      case if that first line matches /\S{2}: /
  #
  #      see this bug report for details:
  #      http://rubyforge.org/tracker/?func=detail&atid=10735&aid=25697&group_id=2795
  #
  Maruku.new("\n#{self}").to_html.

  # omit the <p> added by Maruku
  sub(%r{\A<p>(.*)</p>\Z}, '\1')
end

#to_xhtmlObject

Transforms this string into XHTML.



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/erbook/to_xhtml.rb', line 49

def to_xhtml
  with_protected_tags(self, VERBATIM_TAGS, true) do |text|
    html = with_protected_tags(text, PROTECTED_TAGS, false) do
      |s| s.thru_maruku
    end

    # Markdown's "code spans" should really be "pre spans"
    while html.gsub! %r{(<pre>)<code>(.*?)</code>(</pre>)}m, '\1\2\3'
    end

    # allow "code spans" annotated with Maruku's IAL (Inline
    # Attribute List) Markdown extension to be syntax colored
    while html.gsub! %r{<pre[^>]+>(<code[^>]+>.*?</code>)</pre>}m, '\1'
    end

    # allow user to type <pre> blocks on single lines
    # without affecting the display of their content
    html.gsub! %r{(<pre>)[ \t]*\r?\n|\r?\n[ \t]*(</pre>)}, '\1\2'

    # ensure tables have a border: this *greatly* improves
    # readability in text-based web browsers like w3m and lynx
    html.gsub! %r/<table\b/, '\& border="1"'

    # add syntax coloring
    html.thru_coderay
  end
end