Skip to content

Commit 3a97b80

Browse files
committed
Latex encoder from Redmine
1 parent 3effca8 commit 3a97b80

File tree

2 files changed

+123
-0
lines changed

2 files changed

+123
-0
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
module CodeRay
2+
module Encoders
3+
4+
# = LaTeX Encoder
5+
#
6+
# Encoder producing LaTeX.
7+
class Latex < Encoder
8+
9+
include Streamable
10+
register_for :latex
11+
12+
FILE_EXTENSION = 'tex'
13+
14+
DEFAULT_OPTIONS = {
15+
:wrap => true,
16+
}
17+
18+
protected
19+
def text_token text, kind
20+
@out <<
21+
if kind == :space
22+
text
23+
else
24+
text = escape_latex(text)
25+
"\\syn#{kind_to_command(kind)}{#{text}}"
26+
end
27+
end
28+
29+
def block_token action, kind
30+
@out << super
31+
end
32+
33+
def open_token kind
34+
"\\syn#{kind_to_command(kind)}{"
35+
end
36+
37+
def close_token kind
38+
"}"
39+
end
40+
41+
def kind_to_command kind
42+
kind.to_s.gsub(/[^a-z0-9]/i, '').to_sym
43+
end
44+
45+
def finish options
46+
case options[:wrap]
47+
when true, 1, :semiverbatim
48+
@out = "\\begin{semiverbatim}\n#{@out}\n\\end{semiverbatim}\n"
49+
when false, 0
50+
# Nothing to do
51+
else
52+
raise ArgumentError, "Unknown :wrap option: '#{options[:wrap]}'"
53+
end
54+
55+
super
56+
end
57+
58+
# Escape text so it's interpreted literally by LaTeX compilers
59+
def escape_latex string
60+
string.to_s.gsub(/[$\\{}_%#&~^"]/) do |s|
61+
case s
62+
when '$'
63+
'\$'
64+
when '\\'
65+
'\synbs{}'
66+
when /[{}_%#&]/
67+
"\\#{s}"
68+
when /[~^]/
69+
"\\#{s}{}"
70+
when '"'
71+
'"{}'
72+
end
73+
end
74+
end
75+
76+
end
77+
78+
end
79+
end

lib/coderay/encoders/latex.rb

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
module CodeRay
2+
module Encoders
3+
4+
class Latex < Encoder
5+
6+
include Streamable
7+
register_for :latex
8+
9+
FILE_EXTENSION = 'tex'
10+
11+
ALLTT_ESCAPE = { #:nodoc:
12+
'{' => '\lb',
13+
'}' => '\rb',
14+
'\\' => '\bs',
15+
}
16+
17+
HTML_ESCAPE_PATTERN = /[\\{}]/
18+
19+
protected
20+
21+
def text_token text, kind
22+
if text =~ /#{HTML_ESCAPE_PATTERN}/o
23+
text = text.gsub(/#{HTML_ESCAPE_PATTERN}/o) { |m| @HTML_ESCAPE[m] }
24+
end
25+
k = Tokens::ClassOfKind[kind]
26+
if k == :NO_HIGHLIGHT
27+
text
28+
else
29+
"\\CR#{k}{#{text}}"
30+
end
31+
end
32+
33+
def open_token kind
34+
"\\CR#{Tokens::ClassOfKind[kind]}{"
35+
end
36+
37+
def close_token kind
38+
"}"
39+
end
40+
41+
end
42+
43+
end
44+
end

0 commit comments

Comments
 (0)