YSRedCloth 4.2.9

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