RedCloth 4.1.1 → 4.1.9
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of RedCloth might be problematic. Click here for more details.
- data/CHANGELOG +36 -0
- data/COPYING +1 -1
- data/README +32 -17
- data/Rakefile +1 -0
- data/RedCloth.gemspec +4 -7
- data/ext/redcloth_scan/redcloth.h +53 -22
- data/ext/redcloth_scan/redcloth_attributes.c +176 -172
- data/ext/redcloth_scan/redcloth_attributes.c.rl +2 -3
- data/ext/redcloth_scan/redcloth_attributes.java.rl +5 -6
- data/ext/redcloth_scan/redcloth_attributes.rl +2 -2
- data/ext/redcloth_scan/redcloth_common.rl +5 -1
- data/ext/redcloth_scan/redcloth_inline.c +14485 -7298
- data/ext/redcloth_scan/redcloth_inline.c.rl +48 -14
- data/ext/redcloth_scan/redcloth_inline.java.rl +36 -4
- data/ext/redcloth_scan/redcloth_inline.rl +11 -12
- data/ext/redcloth_scan/redcloth_scan.c +6436 -6228
- data/ext/redcloth_scan/redcloth_scan.c.rl +12 -14
- data/ext/redcloth_scan/redcloth_scan.java.rl +25 -3
- data/ext/redcloth_scan/redcloth_scan.rl +7 -12
- data/lib/redcloth/formatters/base.rb +26 -20
- data/lib/redcloth/formatters/html.rb +22 -30
- data/lib/redcloth/formatters/latex.rb +45 -17
- data/lib/redcloth/textile_doc.rb +1 -3
- data/lib/redcloth/version.rb +1 -1
- data/test/basic.yml +16 -2
- data/test/code.yml +6 -7
- data/test/html.yml +15 -1
- data/test/images.yml +23 -0
- data/test/links.yml +27 -1
- data/test/lists.yml +19 -1
- data/test/table.yml +73 -4
- data/test/test_custom_tags.rb +13 -1
- data/test/test_erb.rb +1 -1
- data/test/test_extensions.rb +1 -1
- data/test/test_formatters.rb +1 -1
- data/test/test_parser.rb +1 -1
- data/test/test_restrictions.rb +1 -1
- data/test/textism.yml +1 -1
- data/test/threshold.yml +1 -3
- data/test/validate_fixtures.rb +2 -1
- metadata +6 -15
@@ -1,7 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* redcloth_scan.c.rl
|
3
3
|
*
|
4
|
-
* Copyright (C)
|
4
|
+
* Copyright (C) 2009 Jason Garber
|
5
5
|
*/
|
6
6
|
#define redcloth_scan_c
|
7
7
|
|
@@ -31,11 +31,11 @@ redcloth_transform(self, p, pe, refs)
|
|
31
31
|
VALUE refs;
|
32
32
|
{
|
33
33
|
char *orig_p = p, *orig_pe = pe;
|
34
|
-
int cs, act, nest;
|
34
|
+
int cs, act, nest = 0;
|
35
35
|
char *ts = NULL, *te = NULL, *reg = NULL, *bck = NULL, *eof = NULL;
|
36
|
-
VALUE html =
|
37
|
-
VALUE table =
|
38
|
-
VALUE block =
|
36
|
+
VALUE html = STR_NEW2("");
|
37
|
+
VALUE table = STR_NEW2("");
|
38
|
+
VALUE block = STR_NEW2("");
|
39
39
|
VALUE regs; CLEAR_REGS()
|
40
40
|
|
41
41
|
|
@@ -84,7 +84,7 @@ redcloth_html_esc(int argc, VALUE* argv, VALUE self) //(self, str, level)
|
|
84
84
|
|
85
85
|
rb_scan_args(argc, argv, "11", &str, &level);
|
86
86
|
|
87
|
-
VALUE new_str =
|
87
|
+
VALUE new_str = STR_NEW2("");
|
88
88
|
if (str == Qnil)
|
89
89
|
return new_str;
|
90
90
|
|
@@ -95,7 +95,7 @@ redcloth_html_esc(int argc, VALUE* argv, VALUE self) //(self, str, level)
|
|
95
95
|
|
96
96
|
char *ts = RSTRING_PTR(str), *te = RSTRING_PTR(str) + RSTRING_LEN(str);
|
97
97
|
char *t = ts, *t2 = ts, *ch = NULL;
|
98
|
-
if (te <= ts) return;
|
98
|
+
if (te <= ts) return Qnil;
|
99
99
|
|
100
100
|
while (t2 < te) {
|
101
101
|
ch = NULL;
|
@@ -142,7 +142,7 @@ redcloth_html_esc(int argc, VALUE* argv, VALUE self) //(self, str, level)
|
|
142
142
|
static VALUE
|
143
143
|
redcloth_latex_esc(VALUE self, VALUE str)
|
144
144
|
{
|
145
|
-
VALUE new_str =
|
145
|
+
VALUE new_str = STR_NEW2("");
|
146
146
|
|
147
147
|
if (str == Qnil)
|
148
148
|
return new_str;
|
@@ -154,7 +154,7 @@ redcloth_latex_esc(VALUE self, VALUE str)
|
|
154
154
|
|
155
155
|
char *ts = RSTRING_PTR(str), *te = RSTRING_PTR(str) + RSTRING_LEN(str);
|
156
156
|
char *t = ts, *t2 = ts, *ch = NULL;
|
157
|
-
if (te <= ts) return;
|
157
|
+
if (te <= ts) return Qnil;
|
158
158
|
|
159
159
|
while (t2 < te) {
|
160
160
|
ch = NULL;
|
@@ -181,7 +181,7 @@ redcloth_latex_esc(VALUE self, VALUE str)
|
|
181
181
|
if (t2 > t)
|
182
182
|
rb_str_cat(new_str, t, t2-t);
|
183
183
|
VALUE opts = rb_hash_new();
|
184
|
-
rb_hash_aset(opts, ID2SYM(rb_intern("text")),
|
184
|
+
rb_hash_aset(opts, ID2SYM(rb_intern("text")), STR_NEW2(ch));
|
185
185
|
rb_str_concat(new_str, rb_funcall(self, rb_intern("entity"), 1, opts));
|
186
186
|
t = t2 + 1;
|
187
187
|
}
|
@@ -201,12 +201,10 @@ static VALUE
|
|
201
201
|
redcloth_to(self, formatter)
|
202
202
|
VALUE self, formatter;
|
203
203
|
{
|
204
|
-
|
205
|
-
int len = 0;
|
206
|
-
|
207
|
-
rb_funcall(self, rb_intern("delete!"), 1, rb_str_new2("\r"));
|
204
|
+
rb_funcall(self, rb_intern("delete!"), 1, STR_NEW2("\r"));
|
208
205
|
VALUE working_copy = rb_obj_clone(self);
|
209
206
|
rb_extend_object(working_copy, formatter);
|
207
|
+
|
210
208
|
if (rb_funcall(working_copy, rb_intern("lite_mode"), 0) == Qtrue) {
|
211
209
|
return redcloth_inline2(working_copy, self, rb_hash_new());
|
212
210
|
} else {
|
@@ -1,7 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* redcloth_scan.java.rl
|
3
3
|
*
|
4
|
-
* Copyright (C)
|
4
|
+
* Copyright (C) 2009 Jason Garber
|
5
5
|
*/
|
6
6
|
import java.io.IOException;
|
7
7
|
|
@@ -108,8 +108,20 @@ public class RedclothScanService implements BasicLibraryService {
|
|
108
108
|
boolean punct = true;
|
109
109
|
while(p > reg && punct) {
|
110
110
|
switch(data[p - 1]) {
|
111
|
+
case ')':
|
112
|
+
int tempP = p - 1;
|
113
|
+
int level = -1;
|
114
|
+
while(tempP > reg) {
|
115
|
+
switch(data[tempP - 1]) {
|
116
|
+
case '(': ++level; break;
|
117
|
+
case ')': --level; break;
|
118
|
+
}
|
119
|
+
--tempP;
|
120
|
+
}
|
121
|
+
if (level == 0) { punct = false; } else { --p; }
|
122
|
+
break;
|
111
123
|
case '!': case '"': case '#': case '$': case '%': case ']': case '[': case '&': case '\'':
|
112
|
-
case '*': case '+': case ',': case '-': case '.': case '
|
124
|
+
case '*': case '+': case ',': case '-': case '.': case '(': case ':':
|
113
125
|
case ';': case '=': case '?': case '@': case '\\': case '^': case '_':
|
114
126
|
case '`': case '|': case '~': p--; break;
|
115
127
|
default: punct = false;
|
@@ -160,7 +172,8 @@ public class RedclothScanService implements BasicLibraryService {
|
|
160
172
|
((RubyHash)regs).aset(sym_text, inline2(self, block, refs));
|
161
173
|
}
|
162
174
|
|
163
|
-
|
175
|
+
IRubyObject formatterMethods = ((RubyObject)self).callMethod(runtime.getCurrentContext(), "formatter_methods");
|
176
|
+
if( ((RubyArray)formatterMethods).includes(runtime.getCurrentContext(), method) ) {
|
164
177
|
block = self.callMethod(runtime.getCurrentContext(), method.asJavaString(), regs);
|
165
178
|
} else {
|
166
179
|
IRubyObject fallback = ((RubyHash)regs).aref(runtime.newSymbol("fallback"));
|
@@ -229,6 +242,10 @@ public class RedclothScanService implements BasicLibraryService {
|
|
229
242
|
((RubyString)H).append(self.callMethod(runtime.getCurrentContext(), T, regs));
|
230
243
|
}
|
231
244
|
|
245
|
+
public void RSTRIP_BANG(IRubyObject H) {
|
246
|
+
((RubyString)H).callMethod(runtime.getCurrentContext(), "rstrip!");
|
247
|
+
}
|
248
|
+
|
232
249
|
public void DONE(IRubyObject H) {
|
233
250
|
((RubyString)html).append(H);
|
234
251
|
CLEAR(H);
|
@@ -403,6 +420,11 @@ public class RedclothScanService implements BasicLibraryService {
|
|
403
420
|
|
404
421
|
((RubyObject)workingCopy).extend(new IRubyObject[]{formatter});
|
405
422
|
|
423
|
+
IRubyObject workingCopyMethods = workingCopy.callMethod(runtime.getCurrentContext(), "methods");
|
424
|
+
IRubyObject classInstanceMethods = workingCopy.getType().callMethod(runtime.getCurrentContext(), "instance_methods");
|
425
|
+
IRubyObject customTags = workingCopyMethods.callMethod(runtime.getCurrentContext(), "-", classInstanceMethods);
|
426
|
+
((RubyObject)workingCopy).setInstanceVariable("@custom_tags", customTags);
|
427
|
+
|
406
428
|
if(workingCopy.callMethod(runtime.getCurrentContext(), "lite_mode").isTrue()) {
|
407
429
|
return inline2(workingCopy, self, RubyHash.newHash(runtime));
|
408
430
|
} else {
|
@@ -1,19 +1,18 @@
|
|
1
1
|
/*
|
2
2
|
* redcloth_scan.rl
|
3
3
|
*
|
4
|
-
* Copyright (C)
|
4
|
+
* Copyright (C) 2009 Jason Garber
|
5
5
|
*/
|
6
6
|
%%{
|
7
7
|
|
8
8
|
machine redcloth_scan;
|
9
9
|
|
10
10
|
# blocks
|
11
|
-
|
12
|
-
notextile_tag_end = "</notextile>" LF? ;
|
11
|
+
notextile_tag = notextile (LF | EOF) ;
|
13
12
|
noparagraph_line_start = " "+ ;
|
14
13
|
notextile_block_start = ( "notextile" >A %{ STORE("type"); } A C :> "." ( "." %extend | "" ) " "+ ) ;
|
15
|
-
pre_tag_start = "<pre" [^>]* ">" (space*
|
16
|
-
pre_tag_end = (
|
14
|
+
pre_tag_start = "<pre" [^>]* ">" (space* code_tag_start)? ;
|
15
|
+
pre_tag_end = (code_tag_end space*)? "</pre>" LF? ;
|
17
16
|
pre_block_start = ( "pre" >A %{ STORE("type"); } A C :> "." ( "." %extend | "" ) " "+ ) ;
|
18
17
|
bc_start = ( "bc" >A %{ STORE("type"); } A C :> "." ( "." %extend | "" ) " "+ ) ;
|
19
18
|
bq_start = ( "bq" >A %{ STORE("type"); } A C :> "." ( "." %extend | "" ) ( ":" %A uri %{ STORE("cite"); } )? " "+ ) ;
|
@@ -30,7 +29,7 @@
|
|
30
29
|
ol = "#" %{nest++; list_type = "ol";};
|
31
30
|
ul_start = ( ul | ol )* ul A C :> " "+ ;
|
32
31
|
ol_start = ( ul | ol )* ol N A C :> " "+ ;
|
33
|
-
list_start = ( ul_start | ol_start ) >{nest = 0;} ;
|
32
|
+
list_start = " "* ( ul_start | ol_start ) >{nest = 0;} ;
|
34
33
|
dt_start = "-" . " "+ ;
|
35
34
|
dd_start = ":=" ;
|
36
35
|
long_dd = dd_start " "* LF %{ ADD_BLOCK(); ASET("type", "dd"); } any+ >A %{ TRANSFORM("text"); } :>> "=:" ;
|
@@ -109,11 +108,6 @@
|
|
109
108
|
LF { ADD_BLOCK(); fgoto main; };
|
110
109
|
default => cat;
|
111
110
|
*|;
|
112
|
-
|
113
|
-
notextile_tag := |*
|
114
|
-
notextile_tag_end { ADD_BLOCK(); fgoto main; };
|
115
|
-
default => cat;
|
116
|
-
*|;
|
117
111
|
|
118
112
|
notextile_block := |*
|
119
113
|
EOF {
|
@@ -178,6 +172,7 @@
|
|
178
172
|
} else {
|
179
173
|
ADD_EXTENDED_BLOCKCODE();
|
180
174
|
CAT(html);
|
175
|
+
RSTRIP_BANG(html);
|
181
176
|
INLINE(html, "bc_close");
|
182
177
|
SET_PLAIN_BLOCK("p");
|
183
178
|
END_EXTENDED();
|
@@ -293,7 +288,7 @@
|
|
293
288
|
|
294
289
|
main := |*
|
295
290
|
noparagraph_line_start { ASET("type", "ignored_line"); fgoto noparagraph_line; };
|
296
|
-
|
291
|
+
notextile_tag { INLINE(block, "notextile"); };
|
297
292
|
notextile_block_start { ASET("type", "notextile"); fgoto notextile_block; };
|
298
293
|
script_tag_start { CAT(block); fgoto script_tag; };
|
299
294
|
pre_tag_start { ASET("type", "notextile"); CAT(block); fgoto pre_tag; };
|
@@ -1,26 +1,6 @@
|
|
1
1
|
module RedCloth::Formatters
|
2
2
|
module Base
|
3
3
|
|
4
|
-
def pba(opts)
|
5
|
-
opts.delete(:style) if filter_styles
|
6
|
-
opts.delete(:class) if filter_classes
|
7
|
-
opts.delete(:id) if filter_ids
|
8
|
-
|
9
|
-
atts = ''
|
10
|
-
opts[:"text-align"] = opts.delete(:align)
|
11
|
-
opts[:style] += ';' if opts[:style] && (opts[:style][-1..-1] != ';')
|
12
|
-
[:float, :"text-align", :"vertical-align"].each do |a|
|
13
|
-
opts[:style] = "#{a}:#{opts[a]};#{opts[:style]}" if opts[a]
|
14
|
-
end
|
15
|
-
[:"padding-right", :"padding-left"].each do |a|
|
16
|
-
opts[:style] = "#{a}:#{opts[a]}em;#{opts[:style]}" if opts[a]
|
17
|
-
end
|
18
|
-
[:style, :class, :lang, :id, :colspan, :rowspan, :title, :start, :align].each do |a|
|
19
|
-
atts << " #{a}=\"#{ html_esc(opts[a].to_s, :html_escape_attributes) }\"" if opts[a]
|
20
|
-
end
|
21
|
-
atts
|
22
|
-
end
|
23
|
-
|
24
4
|
def ignore(opts)
|
25
5
|
opts[:text]
|
26
6
|
end
|
@@ -41,6 +21,28 @@ module RedCloth::Formatters
|
|
41
21
|
end
|
42
22
|
end
|
43
23
|
|
24
|
+
private
|
25
|
+
|
26
|
+
def pba(opts)
|
27
|
+
opts.delete(:style) if filter_styles
|
28
|
+
opts.delete(:class) if filter_classes
|
29
|
+
opts.delete(:id) if filter_ids
|
30
|
+
|
31
|
+
atts = ''
|
32
|
+
opts[:"text-align"] = opts.delete(:align)
|
33
|
+
opts[:style] += ';' if opts[:style] && (opts[:style][-1..-1] != ';')
|
34
|
+
[:float, :"text-align", :"vertical-align"].each do |a|
|
35
|
+
opts[:style] = "#{a}:#{opts[a]};#{opts[:style]}" if opts[a]
|
36
|
+
end
|
37
|
+
[:"padding-right", :"padding-left"].each do |a|
|
38
|
+
opts[:style] = "#{a}:#{opts[a]}em;#{opts[:style]}" if opts[a]
|
39
|
+
end
|
40
|
+
[:style, :class, :lang, :id, :colspan, :rowspan, :title, :start, :align].each do |a|
|
41
|
+
atts << " #{a}=\"#{ html_esc(opts[a].to_s, :html_escape_attributes) }\"" if opts[a]
|
42
|
+
end
|
43
|
+
atts
|
44
|
+
end
|
45
|
+
|
44
46
|
def method_missing(method, opts)
|
45
47
|
opts[:text] || ""
|
46
48
|
end
|
@@ -52,6 +54,10 @@ module RedCloth::Formatters
|
|
52
54
|
def after_transform(text)
|
53
55
|
|
54
56
|
end
|
57
|
+
|
58
|
+
def formatter_methods
|
59
|
+
singleton_methods.map! {|method| method.to_sym }
|
60
|
+
end
|
55
61
|
|
56
62
|
end
|
57
63
|
end
|
@@ -1,25 +1,6 @@
|
|
1
1
|
module RedCloth::Formatters::HTML
|
2
2
|
include RedCloth::Formatters::Base
|
3
3
|
|
4
|
-
# escapement for regular HTML (not in PRE tag)
|
5
|
-
def escape(text)
|
6
|
-
html_esc(text)
|
7
|
-
end
|
8
|
-
|
9
|
-
# escapement for HTML in a PRE tag
|
10
|
-
def escape_pre(text)
|
11
|
-
html_esc(text, :html_escape_preformatted)
|
12
|
-
end
|
13
|
-
|
14
|
-
# escaping for HTML attributes
|
15
|
-
def escape_attribute(text)
|
16
|
-
html_esc(text, :html_escape_attributes)
|
17
|
-
end
|
18
|
-
|
19
|
-
def after_transform(text)
|
20
|
-
text.chomp!
|
21
|
-
end
|
22
|
-
|
23
4
|
[:h1, :h2, :h3, :h4, :h5, :h6, :p, :pre, :div].each do |m|
|
24
5
|
define_method(m) do |opts|
|
25
6
|
"<#{m}#{pba(opts)}>#{opts[:text]}</#{m}>\n"
|
@@ -129,18 +110,7 @@ module RedCloth::Formatters::HTML
|
|
129
110
|
"</blockquote>\n"
|
130
111
|
end
|
131
112
|
|
132
|
-
LINK_TEXT_WITH_TITLE_RE = /
|
133
|
-
([^"]+?) # $text
|
134
|
-
\s?
|
135
|
-
\(([^)]+?)\) # $title
|
136
|
-
$
|
137
|
-
/x
|
138
113
|
def link(opts)
|
139
|
-
if opts[:name] =~ LINK_TEXT_WITH_TITLE_RE
|
140
|
-
md = LINK_TEXT_WITH_TITLE_RE.match(opts[:name])
|
141
|
-
opts[:name] = md[1]
|
142
|
-
opts[:title] = md[2]
|
143
|
-
end
|
144
114
|
"<a href=\"#{escape_attribute opts[:href]}\"#{pba(opts)}>#{opts[:name]}</a>"
|
145
115
|
end
|
146
116
|
|
@@ -281,6 +251,28 @@ module RedCloth::Formatters::HTML
|
|
281
251
|
opts[:text] + "\n"
|
282
252
|
end
|
283
253
|
|
254
|
+
private
|
255
|
+
|
256
|
+
# escapement for regular HTML (not in PRE tag)
|
257
|
+
def escape(text)
|
258
|
+
html_esc(text)
|
259
|
+
end
|
260
|
+
|
261
|
+
# escapement for HTML in a PRE tag
|
262
|
+
def escape_pre(text)
|
263
|
+
html_esc(text, :html_escape_preformatted)
|
264
|
+
end
|
265
|
+
|
266
|
+
# escaping for HTML attributes
|
267
|
+
def escape_attribute(text)
|
268
|
+
html_esc(text, :html_escape_attributes)
|
269
|
+
end
|
270
|
+
|
271
|
+
def after_transform(text)
|
272
|
+
text.chomp!
|
273
|
+
end
|
274
|
+
|
275
|
+
|
284
276
|
def before_transform(text)
|
285
277
|
clean_html(text) if sanitize_html
|
286
278
|
end
|
@@ -14,14 +14,6 @@ module RedCloth::Formatters::LATEX
|
|
14
14
|
|
15
15
|
RedCloth::TextileDoc.send(:include, Settings)
|
16
16
|
|
17
|
-
def escape(text)
|
18
|
-
latex_esc(text)
|
19
|
-
end
|
20
|
-
|
21
|
-
def escape_pre(text)
|
22
|
-
text
|
23
|
-
end
|
24
|
-
|
25
17
|
# headers
|
26
18
|
{ :h1 => 'section*',
|
27
19
|
:h2 => 'subsection*',
|
@@ -38,7 +30,7 @@ module RedCloth::Formatters::LATEX
|
|
38
30
|
# commands
|
39
31
|
{ :strong => 'textbf',
|
40
32
|
:em => 'emph',
|
41
|
-
:i => '
|
33
|
+
:i => 'textit',
|
42
34
|
:b => 'textbf',
|
43
35
|
:ins => 'underline',
|
44
36
|
:del => 'sout',
|
@@ -102,24 +94,50 @@ module RedCloth::Formatters::LATEX
|
|
102
94
|
end
|
103
95
|
|
104
96
|
def td(opts)
|
105
|
-
|
97
|
+
column = @table_row.size
|
98
|
+
if opts[:colspan]
|
99
|
+
opts[:text] = "\\multicolumn{#{opts[:colspan]}}{ #{"l " * opts[:colspan].to_i}}{#{opts[:text]}}"
|
100
|
+
end
|
101
|
+
if opts[:rowspan]
|
102
|
+
@table_multirow_next[column] = opts[:rowspan].to_i - 1
|
103
|
+
opts[:text] = "\\multirow{#{opts[:rowspan]}}{*}{#{opts[:text]}}"
|
104
|
+
end
|
105
|
+
@table_row.push(opts[:text])
|
106
|
+
return ""
|
106
107
|
end
|
107
108
|
|
108
109
|
def tr_open(opts)
|
109
|
-
|
110
|
+
@table_row = []
|
111
|
+
return ""
|
110
112
|
end
|
111
113
|
|
112
114
|
def tr_close(opts)
|
113
|
-
|
115
|
+
multirow_columns = @table_multirow.find_all {|c,n| n > 0}
|
116
|
+
multirow_columns.each do |c,n|
|
117
|
+
@table_row.insert(c,"")
|
118
|
+
@table_multirow[c] -= 1
|
119
|
+
end
|
120
|
+
@table_multirow.merge!(@table_multirow_next)
|
121
|
+
@table_multirow_next = {}
|
122
|
+
@table.push(@table_row)
|
123
|
+
return ""
|
114
124
|
end
|
115
125
|
|
116
|
-
#
|
126
|
+
# We need to know the column count before opening tabular context.
|
117
127
|
def table_open(opts)
|
118
|
-
|
128
|
+
@table = []
|
129
|
+
@table_multirow = {}
|
130
|
+
@table_multirow_next = {}
|
131
|
+
return ""
|
119
132
|
end
|
120
133
|
|
121
134
|
def table_close(opts)
|
122
|
-
"
|
135
|
+
output = "\\begin{tabular}{ #{"l " * @table[0].size }}\n"
|
136
|
+
@table.each do |row|
|
137
|
+
output << " #{row.join(" & ")} \\\\\n"
|
138
|
+
end
|
139
|
+
output << "\\end{tabular}\n"
|
140
|
+
output
|
123
141
|
end
|
124
142
|
|
125
143
|
def bc_open(opts)
|
@@ -222,12 +240,22 @@ module RedCloth::Formatters::LATEX
|
|
222
240
|
end
|
223
241
|
|
224
242
|
def dim(opts)
|
225
|
-
|
226
|
-
|
243
|
+
opts[:text].gsub!('x', '\times')
|
244
|
+
opts[:text].gsub!('"', "''")
|
245
|
+
period = opts[:text].slice!(/\.$/)
|
246
|
+
"$#{opts[:text]}$#{period}"
|
227
247
|
end
|
228
248
|
|
229
249
|
private
|
230
250
|
|
251
|
+
def escape(text)
|
252
|
+
latex_esc(text)
|
253
|
+
end
|
254
|
+
|
255
|
+
def escape_pre(text)
|
256
|
+
text
|
257
|
+
end
|
258
|
+
|
231
259
|
# Use this for block level commands that use \begin
|
232
260
|
def begin_chunk(type)
|
233
261
|
chunk_counter[type] += 1
|