maiku 0.6.1.maiku

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 (44) hide show
  1. data/lib/maruku.rb +141 -0
  2. data/lib/maruku/attributes.rb +175 -0
  3. data/lib/maruku/defaults.rb +71 -0
  4. data/lib/maruku/errors_management.rb +92 -0
  5. data/lib/maruku/ext/div.rb +133 -0
  6. data/lib/maruku/ext/math.rb +41 -0
  7. data/lib/maruku/ext/math/elements.rb +27 -0
  8. data/lib/maruku/ext/math/latex_fix.rb +12 -0
  9. data/lib/maruku/ext/math/mathml_engines/blahtex.rb +107 -0
  10. data/lib/maruku/ext/math/mathml_engines/itex2mml.rb +29 -0
  11. data/lib/maruku/ext/math/mathml_engines/none.rb +20 -0
  12. data/lib/maruku/ext/math/mathml_engines/ritex.rb +24 -0
  13. data/lib/maruku/ext/math/parsing.rb +119 -0
  14. data/lib/maruku/ext/math/to_html.rb +187 -0
  15. data/lib/maruku/ext/math/to_latex.rb +26 -0
  16. data/lib/maruku/helpers.rb +260 -0
  17. data/lib/maruku/input/charsource.rb +326 -0
  18. data/lib/maruku/input/extensions.rb +69 -0
  19. data/lib/maruku/input/html_helper.rb +189 -0
  20. data/lib/maruku/input/linesource.rb +111 -0
  21. data/lib/maruku/input/parse_block.rb +616 -0
  22. data/lib/maruku/input/parse_doc.rb +232 -0
  23. data/lib/maruku/input/parse_span_better.rb +746 -0
  24. data/lib/maruku/input/rubypants.rb +225 -0
  25. data/lib/maruku/input/type_detection.rb +147 -0
  26. data/lib/maruku/input_textile2/t2_parser.rb +163 -0
  27. data/lib/maruku/maruku.rb +33 -0
  28. data/lib/maruku/output/s5/fancy.rb +756 -0
  29. data/lib/maruku/output/s5/to_s5.rb +138 -0
  30. data/lib/maruku/output/to_html.rb +991 -0
  31. data/lib/maruku/output/to_latex.rb +590 -0
  32. data/lib/maruku/output/to_latex_entities.rb +367 -0
  33. data/lib/maruku/output/to_latex_strings.rb +64 -0
  34. data/lib/maruku/output/to_markdown.rb +164 -0
  35. data/lib/maruku/output/to_s.rb +56 -0
  36. data/lib/maruku/string_utils.rb +201 -0
  37. data/lib/maruku/structures.rb +167 -0
  38. data/lib/maruku/structures_inspect.rb +87 -0
  39. data/lib/maruku/structures_iterators.rb +61 -0
  40. data/lib/maruku/textile2.rb +1 -0
  41. data/lib/maruku/toc.rb +199 -0
  42. data/lib/maruku/usage/example1.rb +33 -0
  43. data/lib/maruku/version.rb +39 -0
  44. metadata +167 -0
@@ -0,0 +1,590 @@
1
+ #--
2
+ # Copyright (C) 2006 Andrea Censi <andrea (at) rubyforge.org>
3
+ #
4
+ # This file is part of Maruku.
5
+ #
6
+ # Maruku is free software; you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation; either version 2 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # Maruku is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with Maruku; if not, write to the Free Software
18
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
+ #++
20
+
21
+ module MaRuKu
22
+
23
+ class MDDocument
24
+
25
+ Latex_preamble_enc_cjk =
26
+ "\\usepackage[C40]{fontenc}
27
+ \\usepackage[cjkjis]{ucs}
28
+ \\usepackage[utf8x]{inputenc}"
29
+
30
+ Latex_preamble_enc_utf8 =
31
+ "\\usepackage{ucs}
32
+ \\usepackage[utf8x]{inputenc}"
33
+
34
+ def latex_require_package(p)
35
+ if not self.latex_required_packages.include? p
36
+ self.latex_required_packages.push p
37
+ end
38
+ end
39
+
40
+ # Render as a LaTeX fragment
41
+ def to_latex
42
+ children_to_latex
43
+ end
44
+
45
+ =begin maruku_doc
46
+ Attribute: maruku_signature
47
+ Scope: document
48
+ Output: html, latex
49
+ Summary: Enables Maruku's signature.
50
+ Default: true
51
+
52
+ If false, Maruku does not append a signature to the
53
+ generated file.
54
+ =end
55
+
56
+ # Render as a complete LaTeX document
57
+ def to_latex_document
58
+ body = to_latex
59
+
60
+ if get_setting(:maruku_signature)
61
+ body += render_latex_signature
62
+ end
63
+
64
+ required =
65
+ self.latex_required_packages.map {|p|
66
+ "\\usepackage{#{p}}\n"
67
+ }.join
68
+
69
+ =begin maruku_doc
70
+ Attribute: latex_cjk
71
+ Scope: document
72
+ Output: latex
73
+ Summary: Support for CJK characters.
74
+
75
+ If the `latex_cjk` attribute is specified, then appropriate headers
76
+ are added to the LaTeX preamble to support Japanese fonts.
77
+ You have to have these fonts installed -- and this can be a pain.
78
+
79
+ If `latex_cjk` is specified, this is added to the preamble:
80
+
81
+ <?mrk puts "ciao" ?>
82
+
83
+ <?mrk md_codeblock(Maruku::MDDocument::Latex_preamble_enc_cjk) ?>
84
+
85
+
86
+ while the default is to add this:
87
+
88
+ <?mrk md_codeblock(Maruku::MDDocument::Latex_preamble_enc_utf8) ?>
89
+
90
+ =end
91
+ encoding = get_setting(:latex_cjk) ?
92
+ Latex_preamble_enc_cjk : Latex_preamble_enc_utf8
93
+
94
+ =begin maruku_doc
95
+ Attribute: latex_preamble
96
+ Scope: document
97
+ Output: latex
98
+ Summary: User-defined preamble.
99
+
100
+ If the `latex_preamble` attribute is specified, then its value
101
+ will be used as a custom preamble.
102
+
103
+ For example:
104
+
105
+ Title: My document
106
+ Latex preamble: preamble.tex
107
+
108
+ will produce:
109
+
110
+ ...
111
+ \input{preamble.tex}
112
+ ...
113
+
114
+ =end
115
+ user_preamble = (file = @doc.attributes[:latex_preamble]) ?
116
+ "\\input{#{file}}\n" : ""
117
+
118
+ "\\documentclass{article}
119
+
120
+ % Packages required to support encoding
121
+ #{encoding}
122
+
123
+ % Packages required by code
124
+ #{required}
125
+
126
+ % Packages always used
127
+ \\usepackage{hyperref}
128
+ \\usepackage{xspace}
129
+ \\usepackage[usenames,dvipsnames]{color}
130
+ \\hypersetup{colorlinks=true,urlcolor=blue}
131
+
132
+ #{user_preamble}
133
+
134
+ \\begin{document}
135
+ #{body}
136
+ \\end{document}
137
+ "
138
+ end
139
+
140
+
141
+ def render_latex_signature
142
+ "\\vfill
143
+ \\hrule
144
+ \\vspace{1.2mm}
145
+ \\begin{tiny}
146
+ Created by \\href{http://maruku.rubyforge.org}{Maruku} #{self.nice_date}.
147
+ \\end{tiny}"
148
+ end
149
+
150
+ end end
151
+
152
+ module MaRuKu; module Out; module Latex
153
+
154
+ def to_latex_hrule; "\n\\vspace{.5em} \\hrule \\vspace{.5em}\n" end
155
+ def to_latex_linebreak; "\\newline " end
156
+
157
+ def to_latex_paragraph
158
+ children_to_latex+"\n\n"
159
+ end
160
+
161
+
162
+ =begin maruku_doc
163
+ Title: Input format for colors
164
+ Output: latex, html
165
+ Related: code_background_color
166
+
167
+ Admissible formats:
168
+
169
+ green
170
+ #abc
171
+ #aabbcc
172
+ =end
173
+
174
+ # \color[named]{name}
175
+ # \color[rgb]{1,0.2,0.3}
176
+ def latex_color(s, command='color')
177
+ if s =~ /^\#(\w\w)(\w\w)(\w\w)$/
178
+ r = $1.hex; g = $2.hex; b=$3.hex
179
+ # convert from 0-255 to 0.0-1.0
180
+ r = r / 255.0; g = g / 255.0; b = b / 255.0;
181
+ "\\#{command}[rgb]{%0.2f,%0.2f,%0.2f}" % [r,g,b]
182
+ elsif s =~ /^\#(\w)(\w)(\w)$/
183
+ r = $1.hex; g = $2.hex; b=$3.hex
184
+ # convert from 0-15 to 0.0-1.0
185
+ r = r / 15.0; g = g / 15.0; b = b / 15.0;
186
+ "\\#{command}[rgb]{%0.2f,%0.2f,%0.2f}" % [r,g,b]
187
+ else
188
+ "\\#{command}{#{s}}"
189
+ end
190
+ end
191
+
192
+ =begin maruku_doc
193
+ Attribute: code_show_spaces
194
+ Scope: global, document, element
195
+
196
+ If `true`, shows spaces and tabs in code blocks.
197
+
198
+ Example:
199
+
200
+ One space
201
+ Two spaces
202
+ Tab, space, tab
203
+ Tab, tab, tab and all is green!
204
+ {:code_show_spaces code_background_color=#ffeedd}
205
+ {:markdown}
206
+
207
+ That will produce:
208
+
209
+ One space
210
+ Two spaces
211
+ Tab, space, tab
212
+ Tab, tab, tab and all is green!
213
+ {:code_show_spaces code_background_color=#ffeedd}
214
+
215
+ =end
216
+
217
+ =begin maruku_doc
218
+ Attribute: latex_use_listings
219
+ Scope: document
220
+ Output: latex
221
+ Summary: Support for `listings` package.
222
+ Related: code_show_spaces, code_background_color, lang, code_lang
223
+
224
+ If the `latex_use_listings` attribute is specified, then
225
+ code block are rendered using the `listings` package.
226
+ Otherwise, a standard `verbatim` environment is used.
227
+
228
+ * If the `lang` attribute for the code block has been specified,
229
+ it gets passed to the `listings` package using the `lstset` macro.
230
+ The default lang for code blocks is specified through
231
+ the `code_lang` attribute.
232
+
233
+ \lstset{language=ruby}
234
+
235
+ Please refer to the documentation of the `listings` package for
236
+ supported languages.
237
+
238
+ If a language is not supported, the `listings` package will emit
239
+ a warning during the compilation. Just press enter and nothing
240
+ wrong will happen.
241
+
242
+ * If the `code_show_spaces` is specified, than spaces and tabs will
243
+ be shown using the macro:
244
+
245
+ \lstset{showspaces=true,showtabs=true}
246
+
247
+ * The background color is given by `code_background_color`.
248
+
249
+ =end
250
+
251
+ def to_latex_code;
252
+ raw_code = self.raw_code
253
+
254
+ if get_setting(:latex_use_listings)
255
+ @doc.latex_require_package('listings')
256
+
257
+ s = "\\lstset{columns=fixed,frame=shadowbox}"
258
+
259
+ if get_setting(:code_show_spaces)
260
+ s+= "\\lstset{showspaces=true,showtabs=true}\n"
261
+ else
262
+ s+= "\\lstset{showspaces=false,showtabs=false}\n"
263
+ end
264
+
265
+ color = latex_color get_setting(:code_background_color)
266
+
267
+ s+= "\\lstset{backgroundcolor=#{color}}\n"
268
+
269
+ s+= "\\lstset{basicstyle=\\ttfamily\\footnotesize}\n"
270
+
271
+
272
+ lang = self.attributes[:lang] || @doc.attributes[:code_lang] || '{}'
273
+ if lang
274
+ s += "\\lstset{language=#{lang}}\n"
275
+ end
276
+
277
+ "#{s}\n\\begin{lstlisting}\n#{raw_code}\n\\end{lstlisting}"
278
+ else
279
+ "\\begin{verbatim}#{raw_code}\\end{verbatim}\n"
280
+ end
281
+ end
282
+
283
+ TexHeaders = {
284
+ 1=>'section',
285
+ 2=>'subsection',
286
+ 3=>'subsubsection',
287
+ 4=>'paragraph'}
288
+
289
+ def to_latex_header
290
+ h = TexHeaders[self.level] || 'paragraph'
291
+
292
+ title = children_to_latex
293
+ if number = section_number
294
+ title = number + title
295
+ end
296
+
297
+ if id = self.attributes[:id]
298
+ # drop '#' at the beginning
299
+ if id[0,1] == '#' then id = [1,id.size] end
300
+ %{\\hypertarget{%s}{}\\%s*{{%s}}\\label{%s}\n\n} % [ id, h, title, id ]
301
+ else
302
+ %{\\%s*{%s}\n\n} % [ h, title]
303
+ end
304
+ end
305
+
306
+
307
+ def to_latex_ul;
308
+ if self.attributes[:toc]
309
+ @doc.toc.to_latex
310
+ else
311
+ wrap_as_environment('itemize')
312
+ end
313
+ end
314
+
315
+ def to_latex_quote; wrap_as_environment('quote') end
316
+ def to_latex_ol; wrap_as_environment('enumerate') end
317
+ def to_latex_li;
318
+ "\\item #{children_to_latex}\n"
319
+ end
320
+ def to_latex_li_span;
321
+ "\\item #{children_to_latex}\n"
322
+ end
323
+
324
+ def to_latex_strong
325
+ "\\textbf{#{children_to_latex}}"
326
+ end
327
+ def to_latex_emphasis
328
+ "\\emph{#{children_to_latex}}"
329
+ end
330
+
331
+ def wrap_as_span(c)
332
+ "{#{c} #{children_to_latex}}"
333
+ end
334
+
335
+ def wrap_as_environment(name)
336
+ "\\begin{#{name}}%
337
+ #{children_to_latex}
338
+ \\end{#{name}}\n"
339
+ end
340
+
341
+ SAFE_CHARS = Set.new((?a..?z).to_a + (?A..?Z).to_a)
342
+ # the ultimate escaping
343
+ # (is much better than using \verb)
344
+ def latex_escape(source)
345
+ s="";
346
+
347
+ source.each_byte do |b|
348
+ if b == ?\
349
+ s << '~'
350
+ elsif SAFE_CHARS.include? b
351
+ s << b
352
+ else
353
+ s += "\\char%d" % b
354
+ end
355
+ end
356
+ s
357
+ end
358
+
359
+ def to_latex_inline_code;
360
+ source = self.raw_code
361
+
362
+ # Convert to printable latex chars
363
+ s = latex_escape(source)
364
+
365
+ color = get_setting(:code_background_color)
366
+ colorspec = latex_color(color, 'colorbox')
367
+
368
+ "{#{colorspec}{\\tt #{s}}}"
369
+ end
370
+
371
+ def to_latex_immediate_link
372
+ url = self.url
373
+ text = url.gsub(/^mailto:/,'') # don't show mailto
374
+ # gsub('~','$\sim$')
375
+ text = latex_escape(text)
376
+ if url[0,1] == '#'
377
+ url = url[1,url.size]
378
+ return "\\hyperlink{#{url}}{#{text}}"
379
+ else
380
+
381
+ return "\\href{#{url}}{#{text}}"
382
+ end
383
+ end
384
+
385
+ def to_latex_im_link
386
+ url = self.url
387
+
388
+ if url[0,1] == '#'
389
+ url = url[1,url.size]
390
+ return "\\hyperlink{#{url}}{#{children_to_latex}}"
391
+ else
392
+ return "\\href{#{url}}{#{children_to_latex}}"
393
+ end
394
+ end
395
+
396
+ def to_latex_link
397
+ id = self.ref_id
398
+ ref = @doc.refs[id]
399
+ if not ref
400
+ $stderr.puts "Could not find id = '#{id}'"
401
+ return children_to_latex
402
+ else
403
+ url = ref[:url]
404
+ #title = ref[:title] || 'no title'
405
+
406
+ if url[0,1] == '#'
407
+ url = url[1,url.size]
408
+ return "\\hyperlink{#{url}}{#{children_to_latex}}"
409
+ else
410
+ return "\\href{#{url}}{#{children_to_latex}}"
411
+ end
412
+ end
413
+
414
+ end
415
+
416
+ def to_latex_email_address
417
+ email = self.email
418
+ "\\href{mailto:#{email}}{#{latex_escape(email)}}"
419
+ end
420
+
421
+
422
+ def to_latex_table
423
+ align = self.align
424
+ num_columns = align.size
425
+
426
+ head = @children.slice(0, num_columns)
427
+ rows = []
428
+ i = num_columns
429
+ while i<@children.size
430
+ rows << @children.slice(i, num_columns)
431
+ i+=num_columns
432
+ end
433
+
434
+ h = {:center=>'c',:left=>'l',:right=>'r'}
435
+ align_string = align.map{|a| h[a]}.join('|')
436
+
437
+ s = "\\begin{tabular}{#{align_string}}\n"
438
+
439
+ s += array_to_latex(head, '&') + "\\\\" +"\n"
440
+
441
+ s += "\\hline \n"
442
+
443
+ rows.each do |row|
444
+ s += array_to_latex(row, '&') + "\\\\" +"\n"
445
+ end
446
+
447
+ s += "\\end{tabular}"
448
+
449
+ # puts table in its own paragraph
450
+ s += "\n\n"
451
+
452
+ s
453
+ end
454
+
455
+
456
+ def to_latex_head_cell; children_to_latex end
457
+ def to_latex_cell; children_to_latex end
458
+
459
+
460
+ def to_latex_footnote_reference
461
+ id = self.footnote_id
462
+ f = @doc.footnotes[id]
463
+ if f
464
+ "\\footnote{#{f.children_to_latex.strip}} "
465
+ else
466
+ $stderr.puts "Could not find footnote '#{fid}'"
467
+ end
468
+ end
469
+
470
+ def to_latex_raw_html
471
+ #'{\bf Raw HTML removed in latex version }'
472
+ ""
473
+ end
474
+
475
+ ## Definition lists ###
476
+ def to_latex_definition_list
477
+ s = "\\begin{description}\n"
478
+ s += children_to_latex
479
+ s += "\\end{description}\n"
480
+ s
481
+ end
482
+
483
+ def to_latex_definition
484
+ terms = self.terms
485
+ definitions = self.definitions
486
+
487
+ s = ""
488
+ terms.each do |t|
489
+ s +="\n\\item[#{t.children_to_latex}] "
490
+ end
491
+
492
+ definitions.each do |d|
493
+ s += "#{d.children_to_latex} \n"
494
+ end
495
+
496
+ s
497
+ end
498
+
499
+
500
+ def to_latex_abbr
501
+ children_to_latex
502
+ end
503
+
504
+ def to_latex_image
505
+ id = self.ref_id
506
+ ref = @doc.refs[id]
507
+ if not ref
508
+ maruku_error "Could not find ref #{id.inspect} for image.\n"+
509
+ "Available are: #{@docs.refs.keys.inspect}"
510
+ # $stderr.puts "Could not find id = '#{id}'"
511
+ ""
512
+ else
513
+ url = ref[:url]
514
+ $stderr.puts "Images not supported yet (#{url})"
515
+ # "{\\bf Images not supported yet (#{latex_escape(url)})}"
516
+ ""
517
+ end
518
+
519
+ end
520
+
521
+ def to_latex_div
522
+ type = self.attributes[:class]
523
+ id = self.attributes[:id]
524
+ case type
525
+ when /^un_(\w*)/
526
+ s = "\\begin{u#{$1}}"
527
+ # s += "[#{@children[0].send('children_to_latex')}]"
528
+ @children.delete_at(0)
529
+ s += "\n" + children_to_latex
530
+ s += "\\end{u#{$1}}\n"
531
+ when /^num_(\w*)/
532
+ s = "\\begin{#{$1}}"
533
+ # s += "[#{@children[0].send('children_to_latex')}]"
534
+ @children.delete_at(0)
535
+ s += "\n\\label{#{id}}\\hypertarget{#{id}}{}\n"
536
+ s += children_to_latex
537
+ s += "\\end{#{$1}}\n"
538
+ when /^proof/
539
+ s = "\\begin{proof}"
540
+ @children.delete_at(0)
541
+ s += "\n" + children_to_latex
542
+ s += "\\end{proof}\n"
543
+ else
544
+ s = children_to_latex
545
+ end
546
+ s
547
+ end
548
+
549
+ # Convert each child to html
550
+ def children_to_latex
551
+ array_to_latex(@children)
552
+ end
553
+
554
+ def array_to_latex(array, join_char='')
555
+ e = []
556
+ array.each do |c|
557
+ method = c.kind_of?(MDElement) ?
558
+ "to_latex_#{c.node_type}" : "to_latex"
559
+
560
+ if not c.respond_to?(method)
561
+ # raise "Object does not answer to #{method}: #{c.class} #{c.inspect[0,100]}"
562
+ next
563
+ end
564
+
565
+ h = c.send(method)
566
+
567
+ if h.nil?
568
+ raise "Nil html for #{c.inspect} created with method #{method}"
569
+ end
570
+
571
+ if h.kind_of?Array
572
+ e = e + h
573
+ else
574
+ e << h
575
+ end
576
+ end
577
+
578
+ # puts a space after commands if needed
579
+ # e.each_index do |i|
580
+ # if e[i] =~ /\\\w+\s*$/ # command
581
+ # if (s=e[i+1]) && s[0] == ?\ # space
582
+ # e[i] = e[i] + "\\ "
583
+ # end
584
+ # end
585
+ # end
586
+
587
+ e.join(join_char)
588
+ end
589
+
590
+ end end end # MaRuKu::Out::Latex