livetext 0.9.14 → 0.9.20

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 +4 -4
  2. data/README.lt3 +2 -2
  3. data/imports/bookish.rb +288 -0
  4. data/imports/calibre.rb +28 -0
  5. data/imports/livemagick.rb +133 -0
  6. data/imports/markdown.rb +44 -0
  7. data/imports/markdown_importable.rb +46 -0
  8. data/imports/pyggish.rb +204 -0
  9. data/imports/tutorial.rb +95 -0
  10. data/lib/cmdargs.rb +93 -0
  11. data/lib/formatline.rb +56 -83
  12. data/lib/handler/icanhaz.rb +35 -0
  13. data/lib/handler.rb +1 -0
  14. data/lib/helpers.rb +173 -4
  15. data/lib/livetext.rb +16 -141
  16. data/lib/parser/file.rb +8 -0
  17. data/lib/parser/import.rb +1 -3
  18. data/lib/parser/mixin.rb +22 -24
  19. data/lib/parser/set.rb +35 -26
  20. data/lib/parser/string.rb +19 -4
  21. data/lib/processor.rb +1 -4
  22. data/lib/standard.rb +68 -97
  23. data/lib/userapi.rb +1 -0
  24. data/livetext.gemspec +2 -1
  25. data/plugin/bookish.rb +26 -22
  26. data/plugin/calibre.rb +1 -1
  27. data/plugin/livemagick.rb +10 -10
  28. data/plugin/markdown.rb +13 -11
  29. data/plugin/pyggish.rb +94 -84
  30. data/plugin/tutorial.rb +10 -5
  31. data/test/all.rb +0 -1
  32. data/test/snapshots/OMIT.txt +9 -8
  33. data/test/snapshots/clusion.txt +84 -0
  34. data/test/snapshots/error_inc_line_num/match-error.txt +1 -1
  35. data/test/snapshots/error_invalid_name/match-error.txt +1 -1
  36. data/test/snapshots/error_line_num/match-error.txt +1 -1
  37. data/test/snapshots/error_mismatched_end/match-error.txt +1 -1
  38. data/test/snapshots/error_missing_end/match-error.txt +1 -1
  39. data/test/snapshots/error_no_such_copy/match-error.txt +1 -1
  40. data/test/snapshots/error_no_such_copy/source.lt3 +0 -1
  41. data/test/snapshots/error_no_such_inc/match-error.txt +1 -1
  42. data/test/snapshots/icanhaz/expected-output.txt +5 -0
  43. data/test/snapshots/icanhaz/match-error.txt +1 -0
  44. data/test/snapshots/icanhaz/simple_import.rb +5 -0
  45. data/test/snapshots/icanhaz/source.lt3 +10 -0
  46. data/test/snapshots/icanhaz2/expected-error.txt +0 -0
  47. data/test/snapshots/icanhaz2/expected-output.txt +6 -0
  48. data/test/snapshots/icanhaz2/simple_canhaz.rb +5 -0
  49. data/test/snapshots/icanhaz2/source.lt3 +6 -0
  50. data/test/snapshots/simple_import/expected-error.txt +0 -0
  51. data/test/snapshots/simple_import/expected-output.txt +7 -0
  52. data/test/snapshots/simple_import/simple_import.rb +5 -0
  53. data/test/snapshots/simple_import/source.lt3 +7 -0
  54. data/test/snapshots/simple_include/source.lt3 +0 -1
  55. data/test/snapshots.rb +85 -37
  56. data/test/unit/all.rb +1 -0
  57. data/test/unit/formatline.rb +650 -0
  58. data/test/unit/parser/importable.rb +1 -1
  59. data/test/unit/parser/mixin.rb +1 -1
  60. data/test/unit/parser/set.rb +19 -12
  61. data/test/unit/parser/string.rb +14 -14
  62. metadata +27 -5
  63. data/test/formatting-tests.rb +0 -35
  64. data/test/formatting.rb +0 -103
  65. data/test/snapshots/formatting-tests.txt +0 -124
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d9e6ad9c8d933b361da03fadc6cc4d28e0a8b699f8f50e434db9bf41f0b9d66b
4
- data.tar.gz: 49e59704162aea72ac92122d69f0006591856b9fe09f2b2fdbf6843b7253b80b
3
+ metadata.gz: e957f66d40d20b936f18712c96f1c73474f4b90a047ee94510bb384a687e3575
4
+ data.tar.gz: 11507a7db834b9e3ac5897b2867d1c9236d159b99c7b34685481ae588e97d84d
5
5
  SHA512:
6
- metadata.gz: 74b1b06e0bc91d976c0f60a2136ed8bb1c4d2d5ba33359620752b44a51918a89fbba2cec9c542ae12a6368de82bdc4db64b30a4d95146caab4e5a290f9c7fa8b
7
- data.tar.gz: ed0c0fa3b4da538ddbd31cd799a84f5647d45a369f0f45d729c223f74c7b0f2445bfc0812aa0c319b9a9f5992efa6af521d550eed38a8e2c551b183e28a16722
6
+ metadata.gz: a5614413ab2af9baf687293fa93a531210725b9875df5c3f4fd225074e0f78532cef0bf662f9897bb8b08723eebf6a36ed49bf595d7e00f24e5f369d596b1f9f
7
+ data.tar.gz: 20d135ef80c767d58489a3564cb33f6d1e73cd3baaa11bb83f1448f6fffe29b49f92e3449ecfd476aefc72e840b6920d78b3c8a7b617b53857631a7940efd791
data/README.lt3 CHANGED
@@ -1,5 +1,5 @@
1
- .mixin tutorial
2
- .mixin markdown
1
+ .icanhaz tutorial
2
+ .icanhaz markdown
3
3
 
4
4
  . copy basic.css
5
5
 
@@ -0,0 +1,288 @@
1
+ module Bookish
2
+ def hardbreaks(args = nil, body = nil)
3
+ @hard = false
4
+ @hard = true unless @_args.first == "off"
5
+ end
6
+
7
+ def hardbreaks?
8
+ @hard
9
+ end
10
+
11
+ def credit(args = nil, body = nil)
12
+ # really just a place marker in source
13
+ end
14
+
15
+ # These are duplicated. Remove safely
16
+
17
+ def h1; _out "<h1>#{@_data}</h1>"; end
18
+ def h2; _out "<h2>#{@_data}</h2>"; end
19
+ def h3; _out "<h3>#{@_data}</h3>"; end
20
+
21
+ def alpha_columns(args = nil, body = nil)
22
+ n = @_args.first.to_i # FIXME: what if missing?
23
+ words = []
24
+ _body do |line|
25
+ words << line.chomp
26
+ end
27
+ words.sort!
28
+ _out "<table cellpadding=2>"
29
+ words.each_slice(n) do |w|
30
+ items = w.map {|x| "<tt>#{x}</tt>" }
31
+ _out "<tr><td width=5% valign=top></td><td>" + items.join("</td><td>") + "</td></tr>"
32
+ end
33
+ _out "</table>"
34
+ end
35
+
36
+ # def comment
37
+ # _body { } # ignore body
38
+ # end
39
+
40
+ def _errout(*args)
41
+ ::STDERR.puts *args
42
+ end
43
+
44
+ def _nbsp(n)
45
+ "&nbsp;"*n
46
+ end
47
+
48
+ def _slug(str)
49
+ s2 = str.chomp.strip.gsub(/[?:,()'"\/]/,"").gsub(/ /, "-").downcase
50
+ # _errout "SLUG: #{str} => #{s2}"
51
+ s2
52
+ end
53
+
54
+
55
+ # FIXME duplicated?
56
+ def image(args = nil, body = nil)
57
+ name = @_args[0]
58
+ _out "<img src='#{name}'></img>"
59
+ end
60
+
61
+ def figure(args = nil, body = nil)
62
+ name = @_args[0]
63
+ num = @_args[1]
64
+ title = @_args[2..-1].join(" ")
65
+ title = _format(title)
66
+ _out "<img src='#{name}'></img>"
67
+ _out "<center><b>Figure #{num}</b> #{title}</center>"
68
+ end
69
+
70
+ def chapter(args = nil, body = nil)
71
+ # _errout("chapter")
72
+ @chapter = @_args.first.to_i
73
+ @sec = @sec2 = 0
74
+ title = @_data.split(" ",2)[1]
75
+ @toc << "<br><b>#@chapter</b> #{title}<br>"
76
+ @_data = _slug(title)
77
+ next_output
78
+ _out "<title>#{@chapter}. #{title}</title>"
79
+ _out <<-HTML
80
+ <h2>Chapter #{@chapter}</h2>
81
+ <h1>#{title}</h1>
82
+
83
+ HTML
84
+ end
85
+
86
+ def chapterN(args = nil, body = nil)
87
+ @chapter += 1
88
+ @sec = @sec2 = 0
89
+ title = @_data # .split(" ",2)[1]
90
+ _errout("Chapter #@chapter: #{title}")
91
+ @toc << "<br><b>#@chapter</b> #{title}<br>"
92
+ @_data = _slug(title)
93
+ next_output
94
+ _out "<title>#{@chapter}. #{title}</title>"
95
+ _out <<-HTML
96
+ <h2>Chapter #{@chapter}</h2>
97
+ <h1>#{title}</h1>
98
+
99
+ HTML
100
+ end
101
+
102
+ def sec(args = nil, body = nil)
103
+ @sec += 1
104
+ @sec2 = 0
105
+ @section = "#@chapter.#@sec"
106
+ title = @_data.dup
107
+ @toc << "#{_nbsp(3)}<b>#@section</b> #{title}<br>"
108
+ @_data = _slug(@_data)
109
+ next_output
110
+ _out "<h3>#@section #{title}</h3>\n"
111
+ rescue => err
112
+ STDERR.puts "#{err}\n#{err.backtrace}"
113
+ exit
114
+ end
115
+
116
+ def subsec(args = nil, body = nil)
117
+ @sec2 += 1
118
+ @subsec = "#@chapter.#@sec.#@sec2"
119
+ title = @_data.dup
120
+ @toc << "#{_nbsp(6)}<b>#@subsec</b> #{title}<br>"
121
+ @_data = _slug(@_data)
122
+ next_output
123
+ _out "<h3>#@subsec #{title}</h3>\n"
124
+ end
125
+
126
+ def definition_table(args = nil, body = nil)
127
+ title = @_data
128
+ wide = "95"
129
+ delim = " :: "
130
+ _out "<br><center><table width=#{wide}% cellpadding=5>"
131
+ lines = _body(true)
132
+ lines.map! {|line| _format(line) }
133
+
134
+ lines.each do |line|
135
+ cells = line.split(delim)
136
+ _out "<tr>"
137
+ cells.each.with_index do |cell, i|
138
+ width = (i == 0) ? "width=15%" : ""
139
+ _out " <td #{width} valign=top>#{cell}</td>"
140
+ end
141
+ _out "</tr>"
142
+ end
143
+ _out "</table></center><br><br>"
144
+
145
+ _optional_blank_line
146
+ end
147
+
148
+ def table2(args = nil, body = nil)
149
+ title = @_data
150
+ wide = "90"
151
+ extra = _args[2]
152
+ delim = " :: "
153
+ _out "<br><center><table width=#{wide}% cellpadding=5>"
154
+ lines = _body(true)
155
+ lines.map! {|line| _format(line) }
156
+
157
+ lines.each do |line|
158
+ cells = line.split(delim)
159
+ percent = (100/cells.size.to_f).round
160
+ _out "<tr>"
161
+ cells.each do |cell|
162
+ _out " <td width=#{percent}% valign=top " +
163
+ "#{extra}>#{cell}</td>"
164
+ end
165
+ _out "</tr>"
166
+ end
167
+ _out "</table></center><br><br>"
168
+
169
+ _optional_blank_line
170
+ end
171
+
172
+ def simple_table(args = nil, body = nil)
173
+ title = @_data
174
+ delim = " :: "
175
+ _out "<table cellpadding=2>"
176
+ lines = _body(true)
177
+ maxw = nil
178
+ lines.each do |line|
179
+ _format(line)
180
+ cells = line.split(delim)
181
+ wide = cells.map {|x| x.length }
182
+ maxw = [0] * cells.size
183
+ maxw = maxw.map.with_index {|x, i| [x, wide[i]].max }
184
+ end
185
+
186
+ sum = maxw.inject(0, :+)
187
+ maxw.map! {|x| (x/sum*100).floor }
188
+
189
+ lines.each do |line|
190
+ cells = line.split(delim)
191
+ _out "<tr>"
192
+ cells.each.with_index do |cell, i|
193
+ _out " <td width=#{maxw}% valign=top>" +
194
+ "#{cell}</td>"
195
+ end
196
+ _out "</tr>"
197
+ end
198
+ _out "</table>"
199
+ end
200
+
201
+ def table(args = nil, body = nil)
202
+ @table_num ||= 0
203
+ @table_num += 1
204
+ title = @_data
205
+ delim = " :: "
206
+ _out "<br><center><table width=90% cellpadding=5>"
207
+ lines = _body(true)
208
+ maxw = nil
209
+ lines.each do |line|
210
+ _format(line)
211
+ cells = line.split(delim)
212
+ wide = cells.map {|x| x.length }
213
+ maxw = [0] * cells.size
214
+ maxw = maxw.map.with_index {|x, i| [x, wide[i]+2].max }
215
+ end
216
+
217
+ sum = maxw.inject(0, :+)
218
+ maxw.map! {|x| (x/sum*100).floor }
219
+
220
+ lines.each do |line|
221
+ cells = line.split(delim)
222
+ _out "<tr>"
223
+ cells.each.with_index do |cell, i|
224
+ _out " <td width=#{maxw}% valign=top>" +
225
+ "#{cell}</td>"
226
+ end
227
+ _out "</tr>"
228
+ end
229
+ _out "</table>"
230
+ @toc << "#{_nbsp(8)}<b>Table #@chapter.#@table_num</b> #{title}<br>"
231
+ # _next_output(_slug("table_#{title}"))
232
+ _out "<b>Table #@chapter.#@table_num &nbsp;&nbsp; #{title}</b></center><br>"
233
+ end
234
+
235
+ def toc!(args = nil, body = nil)
236
+ _debug "Closing TOC"
237
+ @toc.close
238
+ rescue => err
239
+ puts @parent.body
240
+ @parent.body = ""
241
+ _errout "Exception: #{err.inspect}"
242
+ end
243
+
244
+ def toc2(args = nil, body = nil)
245
+ file = @_args[0]
246
+ @toc.close
247
+ ::File.write(file, <<-EOS)
248
+ <p style="page-break-after:always;"></p>
249
+ <meta charset='UTF-8'>
250
+
251
+ <center><h2>Fake (non-hyperlinked) Table of Contents</h2></center>
252
+
253
+ EOS
254
+ system("cat toc.tmp >>#{file}")
255
+ end
256
+
257
+ def missing(args = nil, body = nil)
258
+ @toc << "#{_nbsp(8)}<font color=red>TBD: #@_data</font><br>"
259
+ stuff = @_data.empty? ? "" : ": #@_data"
260
+ _out "<br><font color=red><i>[Material missing#{stuff}]</i></font><br>\n "
261
+ end
262
+
263
+ def TBC(args = nil, body = nil)
264
+ @toc << "#{_nbsp(8)}<font color=red>To be continued...</font><br>"
265
+ _out "<br><font color=red><i>To be continued...</i></font><br>"
266
+ end
267
+
268
+ def note(args = nil, body = nil)
269
+ _out "<br><font color=red><i>Note: "
270
+ _out @_data
271
+ _out "</i></font><br>\n "
272
+ end
273
+
274
+ def quote(args = nil, body = nil)
275
+ _out "<blockquote>"
276
+ _body {|line| _out line }
277
+ _out "</blockquote>"
278
+ rescue => err
279
+ STDERR.puts "#{err}\n#{err.backtrace}"
280
+ exit
281
+ end
282
+
283
+ def init_bookish
284
+ @toc_file = "toc.tmp"
285
+ @toc = ::File.new(@toc_file, "w")
286
+ @chapter = -1
287
+ end
288
+ end
@@ -0,0 +1,28 @@
1
+ require 'fileutils'
2
+
3
+ module Calibre
4
+ def epub!(args = nil, body = nil)
5
+ out = _format(@_args[0])
6
+ src = @_args[1]
7
+ @cover = @_args[2]
8
+ if ::File.directory?(src)
9
+ files = ::Dir["#{src}/*"].grep /\.html$/
10
+ files = files.sort # why is this necessary now?
11
+ cmd = "cat #{files.join(' ')} >TEMP.html"
12
+ system(cmd)
13
+ else
14
+ raise "Not supported yet"
15
+ end
16
+
17
+ cmd = "ebook-convert "
18
+ cmd << "TEMP.html #{out}.epub "
19
+ cmd << "--cover #@cover " if @cover
20
+ system(cmd)
21
+
22
+ system("links -dump TEMP.html >/tmp/links.out")
23
+ str = `wc -w /tmp/links.out`
24
+ nw = str.split[0]
25
+ puts "Approx words: #{nw}"
26
+ # ::FileUtils.rm("TEMP.html")
27
+ end
28
+ end
@@ -0,0 +1,133 @@
1
+ require 'rmagick'
2
+
3
+ module Livemagick # FIXME auto-mangle names
4
+ include ::Magick
5
+
6
+ def image(args = nil, body = nil)
7
+ xx, yy, bg = _args
8
+ xx, yy = xx.to_i, yy.to_i
9
+ @image = Image.new(xx,yy) { self.background_color = bg }
10
+ _optional_blank_line
11
+ end
12
+
13
+ def canvas(args = nil, body = nil)
14
+ color, width, opacity = _args
15
+ opacity, width = opacity.to_i, width.to_i
16
+ @canvas = Draw.new
17
+ @canvas.fill_opacity(0)
18
+ @canvas.stroke('black')
19
+ @canvas.stroke_width(1)
20
+ _optional_blank_line
21
+ end
22
+
23
+ def rectangle(args = nil, body = nil)
24
+ xy, wxh, stroke_color, stroke_width = _args
25
+ x, y = xy.split(",").map(&:to_i)
26
+ width, height = wxh.split("x").map(&:to_i)
27
+ stroke_width = stroke_width.to_i
28
+ _debug "rectangle: x=#{x} y=#{y} width=#{width} height=#{height} "
29
+ @canvas.stroke(stroke_color)
30
+ @canvas.stroke_width(stroke_width)
31
+ @canvas.rectangle(x, y, x+width, y+height)
32
+ end
33
+
34
+ def pen(args = nil, body = nil)
35
+ @fill, @stroke = _args
36
+ @stroke = "black" if @stroke.nil? || @stroke.empty?
37
+ _debug "pen: fill=#@fill stroke=#@stroke"
38
+ _optional_blank_line
39
+ end
40
+
41
+ def font(args = nil, body = nil)
42
+ size, font = _args
43
+ font = "Helvetica" if font.nil? || font.empty?
44
+ size = "32" if size.nil? || size.empty?
45
+ @size, @font = size.to_i, font
46
+ _debug "font: size=#@size font=#@font"
47
+ _optional_blank_line
48
+ end
49
+
50
+ def _text(xy, wxh, str, weight, gravity)
51
+ x, y = xy.split(",").map(&:to_i)
52
+ width, height = wxh.split("x").map(&:to_i)
53
+ font, fill, stroke, size = @font, @fill, @stroke, @size
54
+ @canvas.annotate(@image, width, height, x, y, str) do
55
+ self.font_family = font
56
+ self.fill = fill
57
+ self.stroke = stroke
58
+ self.pointsize = size
59
+ self.font_weight = weight
60
+ self.gravity = gravity
61
+ end
62
+ end
63
+
64
+ def text(args = nil, body = nil)
65
+ xy, wxh, str = _data.split
66
+ weight, gravity = BoldWeight, CenterGravity
67
+ _text(xy, wxh, str, weight, gravity)
68
+ _optional_blank_line
69
+ end
70
+
71
+ def text!(args = nil, body = nil)
72
+ xy, wxh = _data.split
73
+ str = _body_text # .join
74
+ weight, gravity = BoldWeight, CenterGravity
75
+ _text(xy, wxh, str, weight, gravity)
76
+ _optional_blank_line
77
+ end
78
+
79
+ def draw(args = nil, body = nil)
80
+ @canvas.draw(@image)
81
+ _optional_blank_line
82
+ end
83
+
84
+ def save(args = nil, body = nil)
85
+ @image.write(_args.first)
86
+ _optional_blank_line
87
+ end
88
+
89
+ def save!(args = nil, body = nil)
90
+ save
91
+ system("open #{_args.first}")
92
+ _optional_blank_line
93
+ end
94
+ end
95
+ =begin
96
+ draw.annotate(img, width, height, x, y, text) [ { additional parameters } ] -> draw
97
+ Description
98
+
99
+ Annotates a image with text. The text is positioned according to the gravity attribute around the rectangle described by the x, y, width, and height arguments. If either of the width or height arguments are 0, uses the image width-x and the image height-y to compute the rectangle width and height. The attributes described in annotate attributes, below, influence the appearance and position of the text. These attributes may be set in the Draw object before calling annotate, or within annotate's optional additional parameters block.
100
+
101
+ Note: all of the annotate attributes are set-only.
102
+ Arguments
103
+
104
+ img
105
+ the image or imagelist to be annotated
106
+ width
107
+ width of the rectangle within which the text is positioned
108
+ height
109
+ height of the rectangle within which the text is positioned
110
+ x
111
+ x offset of the rectangle
112
+ y
113
+ y offset of the rectangle
114
+ text
115
+ the text
116
+
117
+ Returns
118
+
119
+ self
120
+ Example
121
+
122
+ This example is an excerpt of colors.rb. Many other examples also use annotate.
123
+
124
+ title.annotate(montage, 0,0,0,40, 'Named Colors') {
125
+ self.font_family = 'Helvetica'
126
+ self.fill = 'white'
127
+ self.stroke = 'transparent'
128
+ self.pointsize = 32
129
+ self.font_weight = BoldWeight
130
+ self.gravity = NorthGravity
131
+ }
132
+
133
+ =end
@@ -0,0 +1,44 @@
1
+ # This file is intended to be used via a Livetext .mixin
2
+ # or the equivalent.
3
+
4
+ module Markdown
5
+ SimpleFormats = {}
6
+ SimpleFormats[:b] = %w[* *]
7
+ SimpleFormats[:i] = %w[_ _]
8
+ SimpleFormats[:t] = %w[` `]
9
+ SimpleFormats[:s] = %w[<strike> </strike>]
10
+
11
+
12
+ def h1(args = nil, body = nil); _out "# #{FormatLine.var_func_parse(@_data)}"; _optional_blank_line end # atx style for now
13
+ def h2(args = nil, body = nil); _out "## #{FormatLine.var_func_parse(@_data)}"; _optional_blank_line end
14
+ def h3(args = nil, body = nil); _out "### #{FormatLine.var_func_parse(@_data)}"; _optional_blank_line end
15
+ def h4(args = nil, body = nil); _out "#### #{FormatLine.var_func_parse(@_data)}"; _optional_blank_line end
16
+ def h5(args = nil, body = nil); _out "##### #{FormatLine.var_func_parse(@_data)}"; _optional_blank_line end
17
+ def h6(args = nil, body = nil); _out "###### #{FormatLine.var_func_parse(@_data)}"; _optional_blank_line end
18
+
19
+ def title(args = nil, body = nil)
20
+ h1
21
+ end
22
+
23
+ def section(args = nil, body = nil)
24
+ h3
25
+ end
26
+
27
+ def bq(args = nil, body = nil) # block quote
28
+ _body {|line| _out "> #{line}" }
29
+ end
30
+
31
+ def list(args = nil, body = nil)
32
+ _body {|line| _out " * #{line}" }
33
+ end
34
+
35
+ def olist(args = nil, body = nil) # Doesn't handle paragraphs yet
36
+ n = 0
37
+ _body do |line|
38
+ n += 1
39
+ _out "#{n}. #{_format(line)}"
40
+ end
41
+ end
42
+
43
+ alias nlist olist
44
+ end
@@ -0,0 +1,46 @@
1
+ # This file is intended to be used via a Livetext .mixin
2
+ # or the equivalent.
3
+
4
+ require_relative '../lib/livetext/importable'
5
+
6
+ class MarkdownImportable < LiveText::Importable
7
+
8
+ SimpleFormats[:b] = %w[* *]
9
+ SimpleFormats[:i] = %w[_ _]
10
+ SimpleFormats[:t] = %w[` `]
11
+ SimpleFormats[:s] = %w[<strike> </strike>]
12
+
13
+ def h1; _out "# #{FormatLine.var_func_parse(@_data)}"; _optional_blank_line end # atx style for now
14
+ def h2; _out "## #{FormatLine.var_func_parse(@_data)}"; _optional_blank_line end
15
+ def h3; _out "### #{FormatLine.var_func_parse(@_data)}"; _optional_blank_line end
16
+ def h4; _out "#### #{FormatLine.var_func_parse(@_data)}"; _optional_blank_line end
17
+ def h5; _out "##### #{FormatLine.var_func_parse(@_data)}"; _optional_blank_line end
18
+ def h6; _out "###### #{FormatLine.var_func_parse(@_data)}"; _optional_blank_line end
19
+
20
+ def title
21
+ h1
22
+ end
23
+
24
+ def section
25
+ h3
26
+ end
27
+
28
+ def bq # block quote
29
+ _body {|line| _out "> #{line}" }
30
+ end
31
+
32
+ def list
33
+ _body {|line| _out " * #{line}" }
34
+ end
35
+
36
+ def olist # Doesn't handle paragraphs yet
37
+ n = 0
38
+ _body do |line|
39
+ n += 1
40
+ _out "#{n}. #{_format(line)}"
41
+ end
42
+ end
43
+
44
+ alias nlist olist
45
+ end
46
+ end