parity-RedCloth 4.2.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +7 -0
  2. data/.gemtest +0 -0
  3. data/.rspec +1 -0
  4. data/CHANGELOG +265 -0
  5. data/COPYING +18 -0
  6. data/Gemfile +7 -0
  7. data/README.rdoc +215 -0
  8. data/Rakefile +18 -0
  9. data/bin/redcloth +28 -0
  10. data/doc/textile_reference.html +631 -0
  11. data/ext/redcloth_scan/extconf.rb +6 -0
  12. data/ext/redcloth_scan/redcloth.h +220 -0
  13. data/ext/redcloth_scan/redcloth_attributes.c +650 -0
  14. data/ext/redcloth_scan/redcloth_inline.c +8153 -0
  15. data/ext/redcloth_scan/redcloth_scan.c +24407 -0
  16. data/lib/case_sensitive_require/RedCloth.rb +6 -0
  17. data/lib/redcloth/erb_extension.rb +27 -0
  18. data/lib/redcloth/formatters/base.rb +63 -0
  19. data/lib/redcloth/formatters/html.rb +352 -0
  20. data/lib/redcloth/formatters/latex.rb +331 -0
  21. data/lib/redcloth/formatters/latex_entities.yml +2414 -0
  22. data/lib/redcloth/textile_doc.rb +113 -0
  23. data/lib/redcloth/version.rb +34 -0
  24. data/lib/redcloth.rb +45 -0
  25. data/lib/tasks/pureruby.rake +17 -0
  26. data/redcloth.gemspec +54 -0
  27. data/spec/benchmark_spec.rb +15 -0
  28. data/spec/custom_tags_spec.rb +50 -0
  29. data/spec/erb_spec.rb +10 -0
  30. data/spec/extension_spec.rb +26 -0
  31. data/spec/fixtures/basic.yml +1028 -0
  32. data/spec/fixtures/code.yml +257 -0
  33. data/spec/fixtures/definitions.yml +82 -0
  34. data/spec/fixtures/extra_whitespace.yml +64 -0
  35. data/spec/fixtures/filter_html.yml +177 -0
  36. data/spec/fixtures/filter_pba.yml +20 -0
  37. data/spec/fixtures/html.yml +348 -0
  38. data/spec/fixtures/images.yml +279 -0
  39. data/spec/fixtures/instiki.yml +38 -0
  40. data/spec/fixtures/links.yml +291 -0
  41. data/spec/fixtures/lists.yml +462 -0
  42. data/spec/fixtures/poignant.yml +89 -0
  43. data/spec/fixtures/sanitize_html.yml +42 -0
  44. data/spec/fixtures/table.yml +434 -0
  45. data/spec/fixtures/textism.yml +509 -0
  46. data/spec/fixtures/threshold.yml +762 -0
  47. data/spec/formatters/class_filtered_html_spec.rb +7 -0
  48. data/spec/formatters/filtered_html_spec.rb +7 -0
  49. data/spec/formatters/html_no_breaks_spec.rb +9 -0
  50. data/spec/formatters/html_spec.rb +13 -0
  51. data/spec/formatters/id_filtered_html_spec.rb +7 -0
  52. data/spec/formatters/latex_spec.rb +13 -0
  53. data/spec/formatters/lite_mode_html_spec.rb +7 -0
  54. data/spec/formatters/no_span_caps_html_spec.rb +7 -0
  55. data/spec/formatters/sanitized_html_spec.rb +7 -0
  56. data/spec/formatters/style_filtered_html_spec.rb +7 -0
  57. data/spec/parser_spec.rb +102 -0
  58. data/spec/spec_helper.rb +36 -0
  59. data/tasks/compile.rake +47 -0
  60. data/tasks/gems.rake +37 -0
  61. data/tasks/ragel_extension_task.rb +127 -0
  62. data/tasks/release.rake +15 -0
  63. data/tasks/rspec.rake +13 -0
  64. data/tasks/rvm.rake +79 -0
  65. metadata +239 -0
@@ -0,0 +1,331 @@
1
+ require 'yaml'
2
+
3
+ module RedCloth::Formatters::LATEX
4
+ include RedCloth::Formatters::Base
5
+
6
+ def self.entities
7
+ @entities ||= YAML.load(File.read(File.dirname(__FILE__)+'/latex_entities.yml'))
8
+ end
9
+
10
+ module Settings
11
+ # Maps CSS style names to latex formatting options
12
+ def latex_image_styles
13
+ @latex_image_class_styles ||= {}
14
+ end
15
+ end
16
+
17
+ RedCloth::TextileDoc.send(:include, Settings)
18
+
19
+ # headers
20
+ { :h1 => 'section',
21
+ :h2 => 'subsection',
22
+ :h3 => 'subsubsection',
23
+ :h4 => 'paragraph',
24
+ :h5 => 'subparagraph',
25
+ :h6 => 'textbf',
26
+ }.each do |m,tag|
27
+ define_method(m) do |opts|
28
+ case opts[:align]
29
+ when 'left' then
30
+ "\\begin{flushleft}\\#{tag}{#{opts[:text]}}\\end{flushleft}\n\n"
31
+ when 'right' then
32
+ "\\begin{flushright}\\#{tag}{#{opts[:text]}}\\end{flushright}\n\n"
33
+ when 'center' then
34
+ "\\begin{center}\\#{tag}{#{opts[:text]}}\\end{center}\n\n"
35
+ else
36
+ "\\#{tag}{#{opts[:text]}}\n\n"
37
+ end
38
+ end
39
+ end
40
+
41
+ # commands
42
+ { :strong => 'textbf',
43
+ :em => 'emph',
44
+ :i => 'textit',
45
+ :b => 'textbf',
46
+ :ins => 'underline',
47
+ :del => 'sout',
48
+ }.each do |m,tag|
49
+ define_method(m) do |opts|
50
+ "\\#{tag}{#{opts[:text]}}"
51
+ end
52
+ end
53
+
54
+ # inline code
55
+ def code(opts)
56
+ opts[:block] ? opts[:text] : "\\verb@#{opts[:text]}@"
57
+ end
58
+
59
+ # acronyms
60
+ def acronym(opts)
61
+ "#{opts[:title]} (#{opts[:text]})"
62
+ end
63
+
64
+ # sub/superscripts
65
+ { :sup => '\textsuperscript{#1}',
66
+ :sub => '\textsubscript{#1}',
67
+ }.each do |m, expr|
68
+ define_method(m) do |opts|
69
+ expr.sub('#1', opts[:text])
70
+ end
71
+ end
72
+
73
+ # environments
74
+ { :pre => 'verbatim',
75
+ :cite => 'quote',
76
+ }.each do |m, env|
77
+ define_method(m) do |opts|
78
+ begin_chunk(env) + opts[:text] + end_chunk(env)
79
+ end
80
+ end
81
+
82
+ # ignore (or find a good solution later)
83
+ [ :span,
84
+ :div,
85
+ :caps
86
+ ].each do |m|
87
+ define_method(m) do |opts|
88
+ opts[:text].to_s
89
+ end
90
+ end
91
+
92
+ # lists
93
+ { :ol => 'enumerate',
94
+ :ul => 'itemize',
95
+ }.each do |m, env|
96
+ define_method("#{m}_open") do |opts|
97
+ opts[:block] = true
98
+ "\\begin{#{env}}\n"
99
+ end
100
+ define_method("#{m}_close") do |opts|
101
+ "\\end{#{env}}\n\n"
102
+ end
103
+ end
104
+
105
+ def li_open(opts)
106
+ " \\item #{opts[:text]}"
107
+ end
108
+
109
+ def li_close(opts=nil)
110
+ "\n"
111
+ end
112
+
113
+ # paragraphs
114
+ def p(opts)
115
+ case opts[:align]
116
+ when 'left' then
117
+ "\\begin{flushleft}#{opts[:text]}\\end{flushleft}\n\n"
118
+ when 'right' then
119
+ "\\begin{flushright}#{opts[:text]}\\end{flushright}\n\n"
120
+ when 'center' then
121
+ "\\begin{center}#{opts[:text]}\\end{center}\n\n"
122
+ else
123
+ "#{opts[:text]}\n\n"
124
+ end
125
+ end
126
+
127
+ # tables
128
+ def td(opts)
129
+ column = @table_row.size
130
+ if opts[:colspan]
131
+ opts[:text] = "\\multicolumn{#{opts[:colspan]}}{ #{"l " * opts[:colspan].to_i}}{#{opts[:text]}}"
132
+ end
133
+ if opts[:rowspan]
134
+ @table_multirow_next[column] = opts[:rowspan].to_i - 1
135
+ opts[:text] = "\\multirow{#{opts[:rowspan]}}{*}{#{opts[:text]}}"
136
+ end
137
+ @table_row.push(opts[:text])
138
+ return ""
139
+ end
140
+
141
+ def tr_open(opts)
142
+ @table_row = []
143
+ return ""
144
+ end
145
+
146
+ def tr_close(opts)
147
+ multirow_columns = @table_multirow.find_all {|c,n| n > 0}
148
+ multirow_columns.each do |c,n|
149
+ @table_row.insert(c,"")
150
+ @table_multirow[c] -= 1
151
+ end
152
+ @table_multirow.merge!(@table_multirow_next)
153
+ @table_multirow_next = {}
154
+ @table.push(@table_row)
155
+ return ""
156
+ end
157
+
158
+ # We need to know the column count before opening tabular context.
159
+ def table_open(opts)
160
+ @table = []
161
+ @table_multirow = {}
162
+ @table_multirow_next = {}
163
+ return ""
164
+ end
165
+
166
+ # FIXME: need caption and label elements similar to image -> figure
167
+ def table_close(opts)
168
+ output = "\\begin{table}\n"
169
+ output << " \\centering\n"
170
+ output << " \\begin{tabular}{ #{"l " * @table[0].size }}\n"
171
+ @table.each do |row|
172
+ output << " #{row.join(" & ")} \\\\\n"
173
+ end
174
+ output << " \\end{tabular}\n"
175
+ output << "\\end{table}\n"
176
+ output
177
+ end
178
+
179
+ # code blocks
180
+ def bc_open(opts)
181
+ opts[:block] = true
182
+ begin_chunk("verbatim") + "\n"
183
+ end
184
+
185
+ def bc_close(opts)
186
+ end_chunk("verbatim") + "\n"
187
+ end
188
+
189
+ # block quotations
190
+ def bq_open(opts)
191
+ opts[:block] = true
192
+ "\\begin{quotation}\n"
193
+ end
194
+
195
+ def bq_close(opts)
196
+ "\\end{quotation}\n\n"
197
+ end
198
+
199
+ # links
200
+ def link(opts)
201
+ "\\href{#{opts[:href]}}{#{opts[:name]}}"
202
+ end
203
+
204
+ def auto_link(opts)
205
+ return opts[:href] unless auto_link_urls
206
+ href_with_proto = opts[:href]
207
+ href_with_proto = 'http://' + href_with_proto unless href_with_proto.index('http') == 0
208
+ "\\href{#{href_with_proto}}{#{opts[:href]}}"
209
+ end
210
+
211
+ # FIXME: use includegraphics with security verification
212
+ #
213
+ # Remember to use '\RequirePackage{graphicx}' in your LaTeX header
214
+ #
215
+ # FIXME: Look at dealing with width / height gracefully as this should be
216
+ # specified in a unit like cm rather than px.
217
+ def image(opts)
218
+ # Don't know how to use remote links, plus can we trust them?
219
+ return "" if opts[:src] =~ /^\w+\:\/\//
220
+ # Resolve CSS styles if any have been set
221
+ styling = opts[:class].to_s.split(/\s+/).collect { |style| latex_image_styles[style] }.compact.join ','
222
+ # Build latex code
223
+ [ "\\begin{figure}",
224
+ " \\centering",
225
+ " \\includegraphics[#{styling}]{#{opts[:src]}}",
226
+ (" \\caption{#{escape opts[:title]}}" if opts[:title]),
227
+ (" \\label{#{escape opts[:alt]}}" if opts[:alt]),
228
+ "\\end{figure}",
229
+ ].compact.join "\n"
230
+ end
231
+
232
+ # footnotes
233
+ def footno(opts)
234
+ # TODO: insert a placeholder until we know the footnote content.
235
+ # For this to work, we need some kind of post-processing...
236
+ "\\footnotemark[#{opts[:text]}]"
237
+ end
238
+
239
+ def fn(opts)
240
+ "\\footnotetext[#{opts[:id]}]{#{opts[:text]}}"
241
+ end
242
+
243
+ # inline verbatim
244
+ def snip(opts)
245
+ "\\verb`#{opts[:text]}`"
246
+ end
247
+
248
+ def quote1(opts)
249
+ "`#{opts[:text]}'"
250
+ end
251
+
252
+ def quote2(opts)
253
+ "``#{opts[:text]}''"
254
+ end
255
+
256
+ def ellipsis(opts)
257
+ "#{opts[:text]}\\ldots{}"
258
+ end
259
+
260
+ def emdash(opts)
261
+ "---"
262
+ end
263
+
264
+ def endash(opts)
265
+ " -- "
266
+ end
267
+
268
+ def arrow(opts)
269
+ "\\rightarrow{}"
270
+ end
271
+
272
+ def trademark(opts)
273
+ "\\texttrademark{}"
274
+ end
275
+
276
+ def registered(opts)
277
+ "\\textregistered{}"
278
+ end
279
+
280
+ def copyright(opts)
281
+ "\\copyright{}"
282
+ end
283
+
284
+ # TODO: what do we do with (unknown) unicode entities ?
285
+ #
286
+ def entity(opts)
287
+ text = opts[:text][0..0] == '#' ? opts[:text][1..-1] : opts[:text]
288
+ RedCloth::Formatters::LATEX.entities[text]
289
+ end
290
+
291
+ def dim(opts)
292
+ opts[:text].gsub!('x', '\times')
293
+ opts[:text].gsub!('"', "''")
294
+ period = opts[:text].slice!(/\.$/)
295
+ "$#{opts[:text]}$#{period}"
296
+ end
297
+
298
+ # TODO: what do we do with HTML?
299
+ def inline_html(opts)
300
+ opts[:text] || ""
301
+ end
302
+
303
+ private
304
+
305
+ def escape(text)
306
+ latex_esc(text)
307
+ end
308
+
309
+ def escape_pre(text)
310
+ text
311
+ end
312
+
313
+ # Use this for block level commands that use \begin
314
+ def begin_chunk(type)
315
+ chunk_counter[type] += 1
316
+ return "\\begin{#{type}}" if 1 == chunk_counter[type]
317
+ ''
318
+ end
319
+
320
+ # Use this for block level commands that use \end
321
+ def end_chunk(type)
322
+ chunk_counter[type] -= 1
323
+ raise RuntimeError, "Bad latex #{type} nesting detected" if chunk_counter[type] < 0 # This should never need to happen
324
+ return "\\end{#{type}}" if 0 == chunk_counter[type]
325
+ ''
326
+ end
327
+
328
+ def chunk_counter
329
+ @chunk_counter ||= Hash.new 0
330
+ end
331
+ end