livetext 0.9.17 → 0.9.19

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d027612469e45b953a3e8589ebbedf1f746f87f50c4a90b502f4daac56d28605
4
- data.tar.gz: b811285f434d3b2760e201eb403f864ba31cb12e31f21105fc8c4fe5e3b743a2
3
+ metadata.gz: 27c2715e2e3ac638609f0ad19b2427d3da68be25f08bea8196d574b0efdbc115
4
+ data.tar.gz: 7edbc57a07ae50aa240561ad6f250da79a76248cc4c46941df7353cccb3b663c
5
5
  SHA512:
6
- metadata.gz: 1e1b08d7d900ae551d7777576a7284d776422d2039813a764c3d9d9b0495ac14eec4e53225e1e0f3b97a1a548377f14b861e72d4b24d2a52055cd0f75404d2bf
7
- data.tar.gz: 025055edd14e392750b482f4b0a9a973f213b24a5991bb9c7e9939c225a21bfe77398cc118983599a0fd1ccf1c1aa4c8bbf62874745a2cf5257410b747db72ee
6
+ metadata.gz: bbe056fd07c4198012ae2f0fc9f9af3e6eb45d2d3b68d9b8653c29b84081852ed40f05f63f59ccee7d6face5e68675f2293ca1ff3d9b92c12bbb2ca51cbc06df
7
+ data.tar.gz: 1b0f1b84ffd1cbbc41812f76516d39f7d805a53f89f4ef525962cf90128f6e738c81e671e8e98b6d83549b6959f03c844b312cac41a0445fd55472170c888d2c
@@ -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
@@ -0,0 +1,204 @@
1
+ require 'rouge'
2
+
3
+ module Pyggish
4
+ def self.pyg_change(code, klass, style)
5
+ color = style[0..6]
6
+ modifier = style[8]
7
+ mod_open = modifier ? "<#{modifier}>" : ""
8
+ mod_close = modifier ? "</#{modifier}>" : ""
9
+ rx = /<span class="#{klass}">(?<cname>[^<]+?)<\/span>/
10
+ loop do
11
+ md = rx.match(code)
12
+ break if md.nil?
13
+ str = md[:cname]
14
+ result = code.sub!(rx, "<font color=#{color}>#{mod_open}#{str}#{mod_close}</font>")
15
+ break if result.nil?
16
+ end
17
+ end
18
+
19
+ def self._codebar_color(lexer)
20
+ color = case lexer
21
+ when :elixir
22
+ "#fc88fc"
23
+ when :ruby
24
+ "#fc8888"
25
+ else
26
+ raise "Unknown lexer"
27
+ end
28
+ end
29
+
30
+ def self.pyg_finalize(code, lexer=:elixir)
31
+ Styles.each_pair {|klass, style| pyg_change(code, klass, style) }
32
+ File.open("debug-pf1", "w") {|f| f.puts code }
33
+ code.sub!(/<pre>/, "<pre>\n")
34
+ code.gsub!(/<span class="[np]">/, "")
35
+ code.gsub!(/<\/span>/, "")
36
+ color = _codebar_color(lexer)
37
+ code.sub!(/<td class="linenos"/, "<td width=2%></td><td width=5% bgcolor=#{color}")
38
+ code.gsub!(/<td/, "<td valign=top ")
39
+ code.gsub!(/ class="[^"]*?"/, "") # Get rid of remaining Pygments CSS
40
+ File.open("debug-pf2", "w") {|f| f.puts code }
41
+ lines = code.split("\n")
42
+ # lines.each {|line| line << "\n" }
43
+ n1 = lines.index {|x| x =~ /<pre>/ }
44
+ n2 = lines.index {|x| x =~ /<\/pre>/ }
45
+ # FIXME ?
46
+ n1 ||= 0
47
+ n2 ||= -1
48
+ lines[n1].sub!(/ 1$/, " 1 ")
49
+ (n1+1).upto(n2) {|n| lines[n].replace(" " + lines[n] + " ") }
50
+ code = lines.join("\n")
51
+ File.open("debug-pf3", "w") {|f| f.puts code }
52
+ code
53
+ end
54
+
55
+ def _process_code(text)
56
+ File.open("debug-pc1", "w") {|f| f.puts text }
57
+ lines = text.split("\n")
58
+ lines = lines.select {|x| x !~ /##~ omit/ }
59
+ @refs = {}
60
+ lines.each.with_index do |line, i|
61
+ if line =~ /##~ ref/
62
+ frag, name = line.split(/ *##~ ref/)
63
+ @refs[name.strip] = i
64
+ line.replace(frag)
65
+ end
66
+ end
67
+ lines.map! {|line| " " + line }
68
+ text2 = lines.join("\n")
69
+ File.open("debug-pc2", "w") {|f| f.puts text2 }
70
+ text.replace(text2)
71
+ end
72
+
73
+ def _colorize(code, lexer=:elixir)
74
+ text = ::Pygments.highlight(code, lexer: lexer, options: {linenos: "table"})
75
+ _debug "--- in _colorize: text = #{text.inspect}"
76
+ text2 = PygmentFix.pyg_finalize(text, lexer)
77
+ result = "<!-- colorized code -->\n" + text2
78
+ result
79
+ end
80
+
81
+ def _colorize!(code, lexer=:elixir)
82
+ text = ::Pygments.highlight(code, lexer: lexer, options: {})
83
+ _debug "--- in _colorize!: text = #{text.inspect}"
84
+ text2 = PygmentFix.pyg_finalize(text, lexer)
85
+ result = "<!-- colorized code -->\n" + text2
86
+ result
87
+ end
88
+
89
+ def OLD_ruby
90
+ file = @_args.first
91
+ if file.nil?
92
+ code = "# Ruby code\n"
93
+ _body {|line| code << line + "\n" }
94
+ else
95
+ code = "# Ruby code\n\n" + ::File.read(file)
96
+ end
97
+
98
+ _process_code(code)
99
+ html = _colorize(code, :ruby)
100
+ _out "\n#{html}\n "
101
+ end
102
+
103
+ def OLD_elixir
104
+ file = @_args.first
105
+ if file.nil?
106
+ code = ""
107
+ _body {|line| code << line + "\n" }
108
+ else
109
+ code = ::File.read(file)
110
+ end
111
+
112
+ _process_code(code)
113
+ html = _colorize(code, :elixir)
114
+ _out "\n#{html}\n "
115
+ end
116
+
117
+ def fragment
118
+ lang = @_args.empty? ? :elixir : @_args.first.to_sym # ruby or elixir
119
+ @_args = []
120
+ send(lang)
121
+ _out "\n"
122
+ end
123
+
124
+ def code # FIXME ?
125
+ text = ""
126
+ _body {|line| _out " " + line }
127
+ end
128
+
129
+ def mono
130
+ _out "<pre>"
131
+ _body {|line| _out " " + line }
132
+ _out "</pre>"
133
+ end
134
+
135
+ def create_code_styles
136
+ dir = @_outdir || "."
137
+ theme, back = "Github", "white"
138
+ css = Rouge::Themes.const_get(theme).render(scope: '.rb_highlight')
139
+ added = <<~CSS
140
+ .rb_highlight {
141
+ font-family: 'Monaco', 'Andale Mono', 'Lucida Grande', 'Courier', 'Lucida Console', 'Courier New', monospace;
142
+ white-space: pre;
143
+ background-color: #{back}
144
+ }
145
+ CSS
146
+
147
+ css.gsub!(/{\n/, "{\n font-family: courier;")
148
+ css = added + "\n" + css
149
+ # STDERR.puts "Writing #{theme} theme to ruby.css"
150
+ File.write("#{dir}/ruby.css", css)
151
+
152
+ css = Rouge::Themes.const_get(theme).render(scope: '.ex_highlight')
153
+ added = added.sub(/rb/, "ex")
154
+ css.gsub!(/{\n/, "{\n font-family: courier;")
155
+ css = added + "\n" + css
156
+ # STDERR.puts "Writing #{theme} theme to elixir.css"
157
+ File.write("#{dir}/elixir.css", css)
158
+ end
159
+
160
+
161
+ def format_ruby(source, theme = "Github", back = "black")
162
+ # theme/back not used now
163
+ formatter = Rouge::Formatters::HTML.new
164
+ lexer = Rouge::Lexers::Ruby.new
165
+ body = formatter.format(lexer.lex(source))
166
+ text = "<div class=rb_highlight>#{body}</div>"
167
+ text
168
+ end
169
+
170
+ def format_elixir(source, theme = "Github", back = "black")
171
+ # theme/back not used now
172
+ formatter = Rouge::Formatters::HTML.new
173
+ lexer = Rouge::Lexers::Elixir.new
174
+ body = formatter.format(lexer.lex(source))
175
+ text = "<div class=ex_highlight>#{body}</div>"
176
+ text
177
+ end
178
+
179
+ def ruby
180
+ file = @_args.first
181
+ if file.nil?
182
+ code = " # Ruby code\n\n"
183
+ _body {|line| code << " " + line + "\n" }
184
+ else
185
+ code = "# Ruby code\n\n" + ::File.read(file)
186
+ end
187
+
188
+ html = format_ruby(code)
189
+ _out html
190
+ end
191
+
192
+ def elixir
193
+ file = @_args.first
194
+ if file.nil?
195
+ code = ""
196
+ _body {|line| code << " " + line + "\n" }
197
+ else
198
+ code = ::File.read(file)
199
+ end
200
+
201
+ html = format_elixir(code)
202
+ _out html
203
+ end
204
+ end
@@ -0,0 +1,95 @@
1
+ # require 'cgi'
2
+
3
+ require 'helpers'
4
+
5
+ module Tutorial
6
+ include Helpers
7
+
8
+ def title(args = nil, body = nil)
9
+ h1
10
+ _optional_blank_line
11
+ end
12
+
13
+ def section(args = nil, body = nil)
14
+ h3
15
+ _optional_blank_line
16
+ end
17
+
18
+ def code(args = nil, body = nil)
19
+ first = true # dumb hack! fixes blank space
20
+ _body do |line|
21
+ tag, first = "<pre>", false if first
22
+ _out "#{tag} #{escape_html(line)}" # indentation
23
+ end
24
+ _out "</pre>"
25
+ _optional_blank_line
26
+ end
27
+
28
+ def rx(str)
29
+ ::Regexp.compile(::Regexp.escape(str))
30
+ end
31
+
32
+ def inout(args = nil, body = nil)
33
+ src, out = _args
34
+ t1 = ::File.readlines(src) rescue (abort "t1 = #{src}")
35
+ t2 = ::File.readlines(out) rescue (abort "t2 = #{out}")
36
+ # To pacify markdown for README (FIXME later)
37
+ t1 = t1.map {|x| " " + x.sub(/ +$/,"").gsub(/_/, "\\_") }.join
38
+ t2 = t2.map {|x| " " + x.sub(/ +$/,"").gsub(/_/, "\\_") }.join
39
+
40
+ _out <<-HTML
41
+ <table width=80% cellpadding=4>
42
+ <tr>
43
+ <td width=50%><b>Input</b></td>
44
+ <td width=50%><b>Output</b></td>
45
+ </tr>
46
+ <tr>
47
+ <td width=50% bgcolor=#fee0fe valign=top>
48
+ <pre>#{t1}</pre>
49
+ </td>
50
+ <td width=50% bgcolor=#eeeeee valign=top>
51
+ <pre>#{t2}</pre>
52
+ </td>
53
+ </tr>
54
+ </table>
55
+ HTML
56
+ _optional_blank_line
57
+ end
58
+
59
+ def put_table(src, exp)
60
+ t1 = ::File.readlines(src) rescue (abort "t1 = #{src}")
61
+ t2 = ::File.readlines(exp) rescue (abort "t2 = #{out}")
62
+ t1 = t1.map {|x| " " + x.sub(/ +$/,"").gsub(/_/, "\\_") }.join
63
+ t2 = t2.map {|x| " " + x.sub(/ +$/,"").gsub(/_/, "\\_") }.join
64
+
65
+ _out <<-HTML
66
+ <font size=+1>
67
+ <table width=80% cellpadding=4>
68
+ <tr>
69
+ <td width=50%><b>Input</b></td>
70
+ <td width=50%><b>Output</b></td>
71
+ </tr>
72
+ <tr>
73
+ <td width=50% bgcolor=#fee0fe valign=top>
74
+ <pre>#{t1}</pre>
75
+ </td>
76
+ <td width=50% bgcolor=#eeeeee valign=top>
77
+ <pre>#{t2}</pre>
78
+ </td>
79
+ </tr>
80
+ </table>
81
+ </font>
82
+ HTML
83
+ end
84
+
85
+ def testcase(args = nil, body = nil)
86
+ name = _args.first
87
+ _out "\n<font size=+1><b>Test: </font><font size=+2><tt>#{name}</tt></font></b></h3><br>"
88
+ src, exp = "test/data/#{name}/source.lt3", "test/data/#{name}/expected-output.txt"
89
+ @_args = [src, exp] # Better way to do this??
90
+ put_table(src, exp)
91
+ _out "<br>"
92
+ _optional_blank_line
93
+ end
94
+ end
95
+
data/lib/livetext.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # Class Livetext skeleton (top level).
2
2
 
3
3
  class Livetext
4
- VERSION = "0.9.17"
4
+ VERSION = "0.9.19"
5
5
  Path = File.expand_path(File.join(File.dirname(__FILE__)))
6
6
 
7
7
  module Handler
data/livetext.gemspec CHANGED
@@ -15,7 +15,8 @@ Gem::Specification.new do |s|
15
15
  s.executables << "livetext"
16
16
 
17
17
  # Files...
18
- main = Find.find("bin").to_a + Find.find("lib").to_a + Find.find("plugin").to_a
18
+ main = Find.find("bin").to_a + Find.find("lib").to_a +
19
+ Find.find("plugin").to_a + Find.find("imports").to_a
19
20
  misc = %w[./README.lt3 ./README.md livetext.gemspec]
20
21
  test = Find.find("test").to_a
21
22
 
@@ -3,7 +3,21 @@
3
3
  # Blank lines and comments are ignored.
4
4
  # Other lines: name_of_snapshot and any comments here are ignored (no # needed)
5
5
 
6
- # i to include, x to exclude
6
+ # You can start by uncommenting one of these:
7
+ # Default INCLUDE all
8
+ # Default EXCLUDE all
9
+ # If you use neither, INCLUDE is the default (but explicit is better)
10
+
11
+ # If you include all, you can specify exclusions with an x:
12
+ # x my_test_name # this is a comment
13
+
14
+ # Likewise if you EXCLUDE all, you can specify inclusions with an i:
15
+ # i some_other_test # this is a comment
16
+
17
+ # The i and x (to include/exclude) must be the first token on
18
+ # the line (preceding the test name)
19
+
20
+ # Note that QUIT (on a line by itself) will stop processing the file
7
21
 
8
22
  x error_no_such_inc # Output BEFORE error doesn't get passed through ("leading" output)
9
23
  x error_no_such_copy # ^ Same behavior as error_no_such_inc
data/test/snapshots.rb CHANGED
@@ -43,6 +43,69 @@ class TestingLivetext < MiniTest::Test
43
43
  EXP_OUT, EXP_ERR = "expected-output.txt", "expected-error.txt"
44
44
  MATCH_OUT, MATCH_ERR = "match-output.txt", "match-error.txt"
45
45
 
46
+ TTY = File.open("/dev/tty","w")
47
+
48
+ def self.get_dir # FIXME - uh what?
49
+ cmdline = ARGV.first == "cmdline" # FIXME remove??
50
+ if cmdline
51
+ dir = "../"
52
+ Dir.chdir `livetext --path`.chomp.chomp
53
+ else
54
+ dir = ""
55
+ end
56
+ end
57
+
58
+ args = ARGV - ["cmdline"]
59
+
60
+ dir = self.get_dir
61
+
62
+ Data = "#{dir}test/snapshots"
63
+ Dir.chdir(Data)
64
+
65
+ TestDirs = Dir.entries(".").reject {|fname| ! File.directory?(fname) } - %w[. ..]
66
+
67
+
68
+ def self.filter # TODO move subset/omit logic here??
69
+ all = Dir.entries(Data).reject {|fname| ! File.directory?(fname) } - %w[. ..]
70
+ included, excluded = [], []
71
+ @iflag, @eflag = true, false # defaults to INCLUDE
72
+ control = File.new("clusion.txt")
73
+ control.each_line do |line|
74
+ line.sub!(/#.*/, "")
75
+ line.strip!
76
+ lower = line.downcase
77
+ dejavu = false
78
+ case
79
+ when lower.empty?
80
+ # ignore
81
+ when lower == "default include all"
82
+ raise "Only one 'default' allowed" if dejavu
83
+ @iflag, @eflag = true, false # defaults to INCLUDE
84
+ dejavu = true
85
+ when lower == "default exclude all"
86
+ raise "Only one 'default' allowed" if dejavu
87
+ @iflag, @eflag = false, true
88
+ dejavu = true
89
+ when lower == "quit"
90
+ break
91
+ when lower[0] == "i"
92
+ TTY.puts "Warning: Can't include with 'i' when that is default" if @iflag
93
+ included << line.split(" ", 2)[1] # add to included
94
+ when lower[0] == "x"
95
+ TTY.puts "Warning: Can't exclude with 'x' when that is default" if @eflag
96
+ excluded << line.split(" ", 2)[1] # add to excluded
97
+ # add to excluded
98
+ end
99
+ [included, excluded]
100
+ end
101
+ end
102
+
103
+ i, e = self.filter
104
+ p i
105
+ p e
106
+
107
+ exit
108
+
46
109
  def initialize(base, assertion = nil)
47
110
  @assertion = assertion
48
111
  @base = base
@@ -109,9 +172,6 @@ class TestingLivetext < MiniTest::Test
109
172
  system("rm -f #{ACTUAL_OUT} #{ACTUAL_ERR} *sdiff.txt")
110
173
  end
111
174
 
112
- def filter # TODO move subset/omit logic here??
113
- end
114
-
115
175
  def run
116
176
  @errors = false # oops, need to reset
117
177
  Dir.chdir(@base) do
@@ -124,27 +184,6 @@ class TestingLivetext < MiniTest::Test
124
184
  end
125
185
  end
126
186
 
127
- def self.get_dir # FIXME - uh what?
128
- cmdline = ARGV.first == "cmdline" # FIXME remove??
129
- if cmdline
130
- dir = "../"
131
- Dir.chdir `livetext --path`.chomp.chomp
132
- else
133
- dir = ""
134
- end
135
- end
136
-
137
- TTY = File.open("/dev/tty","w")
138
-
139
- args = ARGV - ["cmdline"]
140
-
141
- dir = self.get_dir
142
-
143
- Data = "#{dir}test/snapshots"
144
- Dir.chdir(Data)
145
-
146
- TestDirs = Dir.entries(".").reject {|fname| ! File.directory?(fname) } - %w[. ..]
147
-
148
187
  if args.empty?
149
188
  selected = File.readlines("subset.txt").map(&:chomp)
150
189
  omitfile = "OMIT.txt"
@@ -166,7 +205,6 @@ class TestingLivetext < MiniTest::Test
166
205
  Subset = args
167
206
  end
168
207
 
169
-
170
208
  Subset.each do |tdir|
171
209
  define_method("test_#{tdir}") do
172
210
  myproc = Proc.new {|bool, info| assert bool, info }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: livetext
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.17
4
+ version: 0.9.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hal Fulton
@@ -20,6 +20,13 @@ files:
20
20
  - "./README.lt3"
21
21
  - "./README.md"
22
22
  - bin/livetext
23
+ - imports/bookish.rb
24
+ - imports/calibre.rb
25
+ - imports/livemagick.rb
26
+ - imports/markdown.rb
27
+ - imports/markdown_importable.rb
28
+ - imports/pyggish.rb
29
+ - imports/tutorial.rb
23
30
  - lib/cmdargs.rb
24
31
  - lib/errors.rb
25
32
  - lib/formatline.rb