martile 1.4.6 → 1.6.1
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/martile.rb +358 -297
- data.tar.gz.sig +0 -0
- metadata +56 -36
- metadata.gz.sig +0 -0
data/lib/martile.rb
CHANGED
@@ -13,11 +13,17 @@ require 'mindmapdoc'
|
|
13
13
|
require 'flowchartviz'
|
14
14
|
require 'jsmenubuilder'
|
15
15
|
require 'htmlcom'
|
16
|
+
require 'rxfhelper'
|
17
|
+
require 'mindwords'
|
16
18
|
|
17
19
|
|
20
|
+
# feature: 08-Apr-2022 A <mindwords> tag an now be embedded
|
21
|
+
# bug fix: 01-Feb-2022 When a Martile document has nomarkdown2 tags applied,
|
22
|
+
# they will no longer be applied from a
|
23
|
+
# nested Martile statement
|
18
24
|
# feature: 01-Sep-2020 Introduced the nomarkdown tag and nomarkdown2 tag.
|
19
|
-
# The nomarkdown2 tag has the advantage of being used
|
20
|
-
# inside tags which other Markdown parse don't read.
|
25
|
+
# The nomarkdown2 tag has the advantage of being used
|
26
|
+
# inside tags which other Markdown parse don't read.
|
21
27
|
# The tag will remove itself before completion to_s.
|
22
28
|
# feature: 08-Aug-2020 Implemented #to_Webpage
|
23
29
|
# improvement: 23-Apr-2020 A self-closing sidenav tag is now valid
|
@@ -25,61 +31,61 @@ require 'htmlcom'
|
|
25
31
|
# feature: 29-Feb-2020 The sidenav tag can now contain a raw hierachical list
|
26
32
|
# feature: 22-Jan-2020 An HtmlCom::Accordion component can now be generated
|
27
33
|
# using the tag <accordion>
|
28
|
-
# feature: 16-Sep-2019 An HTML Tree component can now be generated when
|
34
|
+
# feature: 16-Sep-2019 An HTML Tree component can now be generated when
|
29
35
|
# the tag <sidebar/> is used
|
30
36
|
# feature: 16-Jul-2019 An HTML Tabs component can now be created from XML
|
31
37
|
# XML can now be created using !tag notation e.g. !tabs
|
32
38
|
# feature: 05-May-2019 Dimensions can now be supplied for an iframe
|
33
39
|
# improvment: 06-Mar-2019 Checks for mindmap tags outside of other tags
|
34
|
-
# feature: 03-Mar-2019 A high level mindmap with associated doc can now be
|
40
|
+
# feature: 03-Mar-2019 A high level mindmap with associated doc can now be
|
35
41
|
# easily created using the -mm---identifier
|
36
|
-
# bug fix: 25-Feb-2019 The section content is now rendered using to_s
|
42
|
+
# bug fix: 25-Feb-2019 The section content is now rendered using to_s
|
37
43
|
# instead of to_html
|
38
|
-
# feature: 16-Feb-2019 A hidden field cam now be rendered using
|
39
|
-
# the syntax [? name: value]
|
40
|
-
# feature: 11-Feb-2019 An apostrophe used between words is now preserved
|
44
|
+
# feature: 16-Feb-2019 A hidden field cam now be rendered using
|
45
|
+
# the syntax [? name: value]
|
46
|
+
# feature: 11-Feb-2019 An apostrophe used between words is now preserved
|
41
47
|
# from Kramdown HTML rendering
|
42
|
-
# feature: 23-Dec-2018 A SectionX or KVX object can now be referenced
|
48
|
+
# feature: 23-Dec-2018 A SectionX or KVX object can now be referenced
|
43
49
|
# from interpolated variables
|
44
|
-
# feature: 17-Dec-2018 Now automatically generates a toc when there are 3
|
50
|
+
# feature: 17-Dec-2018 Now automatically generates a toc when there are 3
|
45
51
|
# sections or more
|
46
52
|
# feature: 3-Oct-2018 An embed tag can now be used to dynamically load content
|
47
|
-
# bug fix: 26-Sep-2018 An extra new line is added after a code block to
|
48
|
-
# ensure the line directly below it is transformed to
|
53
|
+
# bug fix: 26-Sep-2018 An extra new line is added after a code block to
|
54
|
+
# ensure the line directly below it is transformed to
|
49
55
|
# HTML correctly.
|
50
|
-
# bug fix: 23-Sep-2018 mindmap tag is now properly
|
56
|
+
# bug fix: 23-Sep-2018 mindmap tag is now properly
|
51
57
|
# transformed before parse__data__
|
52
58
|
# feature: 23-Jul-2018 An HTML form can now be generated
|
53
|
-
# feature: 12-Feb-2018 Transforms <mindmap> tags into a
|
59
|
+
# feature: 12-Feb-2018 Transforms <mindmap> tags into a
|
54
60
|
# mindmap + related headings
|
55
61
|
# feature: 8-Feb-2018 A section attribute id can now include a dash (-).
|
56
|
-
# Markdown inside a section element is no longer
|
62
|
+
# Markdown inside a section element is no longer
|
57
63
|
# rendered by RDiscount
|
58
|
-
# minor improvement: 29-Sep-2017 A Markdownviz or Flowchartviz embedded
|
64
|
+
# minor improvement: 29-Sep-2017 A Markdownviz or Flowchartviz embedded
|
59
65
|
# document can now be declared without the word viz at the end.
|
60
|
-
# feature: 21-Sep-2017 A qrcode can now be rendered
|
66
|
+
# feature: 21-Sep-2017 A qrcode can now be rendered
|
61
67
|
# e.g. !q[](http://github.com)
|
62
68
|
# feature: 16-Sep-2017 A Flowchartviz raw document can now be embedded
|
63
69
|
# feature: 9-Sep-2017 A Mindmapviz raw document can now be embedded
|
64
70
|
# feature: 8-Sep-2017 An SVG doc can now be embedded from !s[]()
|
65
|
-
# feature: 6-Sep-2017 The preparation of a Dynarex table in Markdown is now
|
71
|
+
# feature: 6-Sep-2017 The preparation of a Dynarex table in Markdown is now
|
66
72
|
# done from the Dynarex object
|
67
|
-
# bug fix: 13-Aug-2017 bug fixes: A markdown table is no longer interpreted
|
68
|
-
# as <code> and a string containig a caret is no longer
|
69
|
-
# interpreted as <nark> if it contains non
|
73
|
+
# bug fix: 13-Aug-2017 bug fixes: A markdown table is no longer interpreted
|
74
|
+
# as <code> and a string containig a caret is no longer
|
75
|
+
# interpreted as <nark> if it contains non
|
70
76
|
# alphanumerical characters.
|
71
|
-
# feature: 28-May-2017 Within the context of an embedded Dynarex table,
|
77
|
+
# feature: 28-May-2017 Within the context of an embedded Dynarex table,
|
72
78
|
# the nomarkdown extension was wrapped around the inner HTML for each column
|
73
|
-
#
|
79
|
+
#
|
74
80
|
# Return characters are now stripped out.
|
75
81
|
#
|
76
|
-
# An embeded Dynarex table contents are now rendered to
|
82
|
+
# An embeded Dynarex table contents are now rendered to
|
77
83
|
# Markdown by default
|
78
|
-
# feature: 11-Mar-2017 A details and summary tag can now be generated from +>
|
84
|
+
# feature: 11-Mar-2017 A details and summary tag can now be generated from +>
|
79
85
|
# e.g.
|
80
86
|
# !+
|
81
87
|
# This a paragraph
|
82
|
-
#
|
88
|
+
#
|
83
89
|
# ----------------
|
84
90
|
#
|
85
91
|
# * something
|
@@ -94,52 +100,64 @@ class Martile
|
|
94
100
|
|
95
101
|
attr_reader :to_s, :to_html, :data_source
|
96
102
|
|
97
|
-
|
98
|
-
|
103
|
+
# embedded: Is the Martile object being run inside another Martile object?
|
104
|
+
#
|
105
|
+
def initialize(raw_s='', ignore_domainlabel: nil, toc: true,
|
106
|
+
embedded: false, debug: false, log: nil)
|
99
107
|
|
100
108
|
|
101
109
|
@debug = debug
|
102
110
|
@data_source = {}
|
103
|
-
|
111
|
+
|
104
112
|
@ignore_domainlabel, @log = ignore_domainlabel, log
|
105
|
-
|
113
|
+
|
106
114
|
@css, @js = [], []
|
107
115
|
|
108
116
|
raw_s.gsub!("\r",'')
|
109
|
-
|
117
|
+
|
110
118
|
mmd = MindmapDoc.new(debug: debug)
|
111
119
|
s5 = apply_filter(raw_s) {|x| mmd.to_mmd(x) }
|
112
120
|
s10 = apply_filter(s5) {|x| mmd.transform(s5) }
|
113
121
|
#puts 's10: ' + s10.inspect if debug
|
114
122
|
#s10 = raw_s
|
115
123
|
s20 = s10 =~ /^__DATA__$/ ? parse__data__(s10) : s10
|
116
|
-
puts ('s20: ' + s20.inspect).debug if debug
|
117
|
-
|
124
|
+
puts ('s20: ' + s20.inspect).debug if debug
|
125
|
+
|
118
126
|
s30 = apply_filter(s20) {|x| slashpre x }
|
127
|
+
puts ('s30: ' + s30.inspect).debug if @debug
|
128
|
+
|
119
129
|
#puts 's1 : ' + s1.inspect
|
120
130
|
s40 = apply_filter(s30) {|x| code_block_to_html(x.strip + "\n") }
|
131
|
+
puts ('s40: ' + s40.inspect).debug if @debug
|
132
|
+
|
133
|
+
s45 = if !embedded then
|
134
|
+
s40.gsub(/<pre[^>]*>/,'\0{::nomarkdown2}').gsub(/<\/pre>/,'{:2/}\0')
|
135
|
+
else
|
136
|
+
s40
|
137
|
+
end
|
138
|
+
puts ('s45: ' + s45.inspect).debug if @debug
|
121
139
|
|
122
|
-
s45 = s40.gsub(/<pre[^>]*>/,'\0{::nomarkdown2}').gsub(/<\/pre>/,'{:2/}\0')
|
123
140
|
#puts 's2 : ' + s2.inspect
|
124
141
|
#s3 = apply_filter(s2, %w(ol ul)) {|x| explicit_list_to_html x }
|
125
142
|
#puts 's3 : ' + s3.inspect
|
126
143
|
s50 = apply_filter(s45) {|x| ordered_list_to_html x }
|
127
|
-
|
144
|
+
puts ('s50: ' + s50.inspect).debug if @debug
|
128
145
|
|
129
146
|
s60 = apply_filter(s50) {|x| unordered_list_to_html x }
|
130
|
-
|
147
|
+
puts ('s60: ' + s60.inspect).debug if @debug
|
131
148
|
|
132
149
|
s70 = apply_filter(s60) {|x| dynarex_to_markdown x }
|
133
|
-
|
150
|
+
puts ('s70: ' + s70.inspect).debug if @debug
|
134
151
|
|
135
152
|
s80 = apply_filter(s70) {|x| table_to_html x }
|
136
|
-
|
153
|
+
puts ('s80: ' + s80.inspect).debug if @debug
|
137
154
|
|
138
155
|
s90 = apply_filter(s80) {|x| underline x}
|
139
156
|
puts ('s90: ' + s90.inspect).debug if @debug
|
157
|
+
|
140
158
|
s100 = apply_filter(s90) {|x| section x }
|
141
159
|
puts ('s100: ' + s100.inspect).debug if @debug
|
142
|
-
|
160
|
+
|
143
161
|
s110 = apply_filter(s100) {|x| smartlink x }
|
144
162
|
|
145
163
|
puts 's110: ' + s110.inspect if @debug
|
@@ -147,69 +165,83 @@ class Martile
|
|
147
165
|
#s11 = section s9
|
148
166
|
#puts 's11 : ' + s11.inspect
|
149
167
|
s120 = apply_filter(s110) {|x| audiotag x }
|
150
|
-
|
168
|
+
puts 's120 : ' + s120.inspect if @debug
|
151
169
|
s130 = apply_filter(s120) {|x| videotag x }
|
152
|
-
|
170
|
+
puts 's130 : ' + s130.inspect if @debug
|
153
171
|
s140 = apply_filter(s130) {|x| iframetag x }
|
154
|
-
|
172
|
+
puts 's140 : ' + s140.inspect if @debug
|
155
173
|
s150 = apply_filter(s140) {|x| kvx_to_dl x }
|
156
|
-
|
174
|
+
puts 's150 : ' + s150.inspect if @debug
|
157
175
|
s160 = apply_filter(s150) {|x| list_item_to_hyperlink x }
|
176
|
+
puts 's160 : ' + s160.inspect if @debug
|
158
177
|
s165 = apply_filter(s160) {|x| formify x }
|
159
|
-
|
178
|
+
puts 's165 : ' + s165.inspect if @debug
|
160
179
|
s170 = apply_filter(s165) {|x| mtlite_utils x }
|
180
|
+
puts 's170 : ' + s170.inspect if @debug
|
161
181
|
s180 = apply_filter(s170) {|x| hyperlinkify x }
|
182
|
+
puts 's180 : ' + s180.inspect if @debug
|
162
183
|
s190 = apply_filter(s180) {|x| highlight x }
|
184
|
+
puts 's190 : ' + s190.inspect if @debug
|
163
185
|
s200 = apply_filter(s190) {|x| details x }
|
186
|
+
puts 's200 : ' + s200.inspect if @debug
|
164
187
|
s210 = apply_filter(s200) {|x| qrcodetag x }
|
188
|
+
puts 's210 : ' + s210.inspect if @debug
|
165
189
|
s220 = apply_filter(s210) {|x| svgtag x }
|
190
|
+
puts 's220 : ' + s220.inspect if @debug
|
166
191
|
s230 = apply_filter(s220) {|x| embedtag x }
|
192
|
+
puts 's230 : ' + s230.inspect if @debug
|
167
193
|
s240 = apply_filter(s230) {|x| script_out x }
|
194
|
+
puts 's240 : ' + s240.inspect if @debug
|
168
195
|
s245 = s240.gsub(/\{::nomarkdown2\}/,'').gsub(/\{:2\/\}/,'')
|
169
|
-
|
170
|
-
|
196
|
+
puts 's245 : ' + s245.inspect if @debug
|
197
|
+
s246 = mindwords(s245)
|
198
|
+
@to_s = s246.to_s
|
199
|
+
|
171
200
|
s250 = apply_filter(s245) {|x| nomarkdown x }
|
201
|
+
puts 's250 : ' + s250.inspect if @debug
|
172
202
|
s252 = sidenav(s250)
|
203
|
+
puts 's252 : ' + s252.inspect if @debug
|
173
204
|
s253 = bang_xml(s252)
|
174
|
-
puts ('
|
205
|
+
puts ('s253 after bang_xml: ' + s253.inspect).debug if @debug
|
175
206
|
|
176
207
|
s255 = tabs(s253)
|
177
208
|
puts ('s255 after tabs: ' + s255.inspect).debug if @debug
|
178
|
-
|
209
|
+
|
179
210
|
s257 = accordion(s255)
|
180
|
-
|
181
|
-
|
182
|
-
|
211
|
+
puts 's257 : ' + s257.inspect if @debug
|
212
|
+
|
213
|
+
toc = false if s257 =~ /class=['"]sidenav['"]>/
|
214
|
+
|
183
215
|
s260 = if toc then
|
184
216
|
Yatoc.new(Kramdown::Document.new(s257).to_html, debug: debug).to_html
|
185
217
|
else
|
186
218
|
s257
|
187
219
|
end
|
188
|
-
|
189
|
-
puts ('s260: ' + s260.inspect).debug if debug
|
220
|
+
|
221
|
+
puts ('s260: ' + s260.inspect).debug if debug
|
190
222
|
#puts 's17 : ' + s17.inspect
|
191
223
|
|
192
224
|
@to_html = s260
|
193
|
-
|
225
|
+
|
194
226
|
end
|
195
|
-
|
227
|
+
|
196
228
|
def create_form(s)
|
197
229
|
|
198
230
|
a = LineTree.new(s, ignore_blank_lines: true).to_a
|
199
|
-
|
231
|
+
|
200
232
|
def create_form_input(raw_name)
|
201
233
|
|
202
234
|
name = raw_name.downcase[/\w+/]
|
203
235
|
type = name =~ /password/ ? :password : :text
|
204
236
|
|
205
|
-
['div', {},
|
206
|
-
['label', {for: name}, raw_name],
|
237
|
+
['div', {},
|
238
|
+
['label', {for: name}, raw_name],
|
207
239
|
['input', {type: type, id: name, name: name}]
|
208
240
|
]
|
209
241
|
end
|
210
|
-
|
242
|
+
|
211
243
|
a2 = a[0][1..-1].select {|x| x[0] =~ /[^:]+\:/}.map do |items|
|
212
|
-
|
244
|
+
|
213
245
|
line = items[0]
|
214
246
|
case line
|
215
247
|
when /^\w/
|
@@ -228,21 +260,21 @@ class Martile
|
|
228
260
|
doc = Rexle.new(a2)
|
229
261
|
doc.root.element('div/input').attributes['autofocus'] = 'true'
|
230
262
|
doc.xml pretty: true, declaration: false
|
231
|
-
|
263
|
+
|
232
264
|
end
|
233
|
-
|
265
|
+
|
234
266
|
def to_css()
|
235
267
|
@css.join("\n")
|
236
268
|
end
|
237
|
-
|
269
|
+
|
238
270
|
def to_js()
|
239
271
|
@js.join("\n")
|
240
272
|
end
|
241
|
-
|
273
|
+
|
242
274
|
def to_webpage()
|
243
275
|
|
244
276
|
a = RexleBuilder.build do |xml|
|
245
|
-
xml.html do
|
277
|
+
xml.html do
|
246
278
|
xml.head do
|
247
279
|
xml.meta name: "viewport", content: \
|
248
280
|
"width=device-width, initial-scale=1"
|
@@ -252,58 +284,58 @@ class Martile
|
|
252
284
|
end
|
253
285
|
end
|
254
286
|
|
255
|
-
doc = Rexle.new(a)
|
256
|
-
|
287
|
+
doc = Rexle.new(a)
|
288
|
+
|
257
289
|
doc.root.element('body').add \
|
258
|
-
Rexle::Element.new('script').add_text "\n" +
|
290
|
+
Rexle::Element.new('script').add_text "\n" +
|
259
291
|
@js.join("\n").gsub(/^ +\/\/[^\n]+\n/,'')
|
260
|
-
|
292
|
+
|
261
293
|
"<!DOCTYPE html>\n" + doc.xml(pretty: true, declaration: false)\
|
262
294
|
.gsub(/<\/div>/,'\0' + "\n").gsub(/\n *<!--[^>]+>/,'')
|
263
|
-
|
295
|
+
|
264
296
|
end
|
265
|
-
|
297
|
+
|
266
298
|
private
|
267
|
-
|
299
|
+
|
268
300
|
def accordion(s1)
|
269
|
-
|
301
|
+
|
270
302
|
s = s1.clone
|
271
|
-
|
303
|
+
|
272
304
|
doc = Rexle.new("<root>#{s}</root>")
|
273
305
|
puts 'doc.root.xml: ' + doc.root.xml.inspect if @debug
|
274
306
|
a = doc.root.xpath('accordion').map.with_index do |e, i |
|
275
|
-
|
307
|
+
|
276
308
|
build = HtmlCom::Accordion.new(e.xml, debug: false)
|
277
|
-
|
309
|
+
|
278
310
|
if i < 1 then
|
279
|
-
@css << build.to_css
|
311
|
+
@css << build.to_css
|
280
312
|
@js << build.to_js
|
281
313
|
end
|
282
|
-
|
314
|
+
|
283
315
|
build.to_html
|
284
|
-
|
285
|
-
|
316
|
+
|
317
|
+
|
286
318
|
end
|
287
319
|
puts 'accordion a:' + a.inspect if @debug
|
288
320
|
|
289
321
|
# replaces the <accordion> XML with HTML
|
290
322
|
a.each do |html|
|
291
|
-
|
323
|
+
|
292
324
|
istart = s =~ /^<accordion[^>]*>/
|
293
325
|
iend = s =~ /<\/accordion>/
|
294
326
|
s.slice!(istart, (iend - istart) + '</accordion>'.length + 1)
|
295
327
|
s.insert(istart, html)
|
296
|
-
|
328
|
+
|
297
329
|
end
|
298
|
-
|
330
|
+
|
299
331
|
return s
|
300
|
-
|
301
|
-
end
|
302
|
-
|
332
|
+
|
333
|
+
end
|
334
|
+
|
303
335
|
def audiotag(s)
|
304
|
-
|
336
|
+
|
305
337
|
s.gsub(/\B!a\[\]\((https?:\/\/[^\)]+)\)\B/) do |x|
|
306
|
-
|
338
|
+
|
307
339
|
files = ($1).split
|
308
340
|
|
309
341
|
h = {/\.ogg$/ => 'ogg', /\.wav$/ => 'wav', /\.mp3$/ => 'mp3' }
|
@@ -314,17 +346,17 @@ class Martile
|
|
314
346
|
end
|
315
347
|
|
316
348
|
"<audio controls='controls'>\n%s\n</audio>" % [sources.join("\n")]
|
317
|
-
end
|
349
|
+
end
|
318
350
|
|
319
351
|
end
|
320
|
-
|
352
|
+
|
321
353
|
def bang_xml(s)
|
322
354
|
|
323
|
-
indent = -> (line) { ' ' + line }
|
324
|
-
a = s.split(/(
|
325
|
-
|
355
|
+
indent = -> (line) { ' ' + line }
|
356
|
+
a = s.split(/(?=^\![a-zA-Z]+)/)
|
357
|
+
|
326
358
|
a.map do |s|
|
327
|
-
|
359
|
+
|
328
360
|
if s =~ /^!!/ then
|
329
361
|
|
330
362
|
parent, children = s.split(/^!!/,2)
|
@@ -337,18 +369,18 @@ class Martile
|
|
337
369
|
else
|
338
370
|
s
|
339
371
|
end
|
340
|
-
|
372
|
+
|
341
373
|
end.join
|
342
374
|
end
|
343
375
|
|
344
376
|
def code_block_to_html(s)
|
345
377
|
|
346
|
-
|
347
|
-
s.split(/(?=<pre>)/).map do |s2|
|
348
|
-
|
378
|
+
|
379
|
+
s.split(/(?=<pre>)/).map do |s2|
|
380
|
+
|
349
381
|
if s2[0] != '<' then
|
350
|
-
|
351
|
-
|
382
|
+
|
383
|
+
s2.lines.chunk {|x| x =~ /^\n|^ |\n/ }.map do |_, x|
|
352
384
|
|
353
385
|
if x.join.lstrip[/^ /] then
|
354
386
|
"\n<pre><code>%s</code></pre>\n\n" % escape(x.join.gsub(/^ {4}/,''))
|
@@ -361,18 +393,18 @@ class Martile
|
|
361
393
|
else
|
362
394
|
s2
|
363
395
|
end
|
364
|
-
|
396
|
+
|
365
397
|
end.join
|
366
|
-
|
398
|
+
|
367
399
|
|
368
400
|
end
|
369
401
|
|
370
402
|
def details(s)
|
371
|
-
|
403
|
+
|
372
404
|
puts ('inside details: ' + s.inspect).debug if @debug
|
373
|
-
|
405
|
+
|
374
406
|
s.split(/(?=\!\+)/).map do |x|
|
375
|
-
|
407
|
+
|
376
408
|
if x =~ /\!\+/ then
|
377
409
|
|
378
410
|
x[2..-1].sub(/(.*)[^\+]+\n\+/m) do |x2|
|
@@ -382,23 +414,23 @@ class Martile
|
|
382
414
|
[summary, Martile.new(detail.chop).to_html]
|
383
415
|
|
384
416
|
end
|
385
|
-
|
417
|
+
|
386
418
|
else
|
387
419
|
x
|
388
420
|
end
|
389
421
|
end.join
|
390
422
|
|
391
423
|
end
|
392
|
-
|
424
|
+
|
393
425
|
def dynarex_to_markdown(s)
|
394
|
-
|
426
|
+
|
395
427
|
s.gsub(/!d\[\]\(((#\w+|https?:\/\/)?[\w\/\.\-]+)\)(\{[^\}]+\})?/) do |match|
|
396
428
|
|
397
429
|
source = ($1)
|
398
430
|
raw_select = ($3)
|
399
431
|
|
400
432
|
dx = if source =~ /^http/ then
|
401
|
-
Dynarex.new(source)
|
433
|
+
Dynarex.new(source)
|
402
434
|
else
|
403
435
|
@data_source[source[/\w+/]]
|
404
436
|
end
|
@@ -426,43 +458,43 @@ class Martile
|
|
426
458
|
end
|
427
459
|
|
428
460
|
end
|
429
|
-
|
461
|
+
|
430
462
|
def embedtag(s)
|
431
|
-
|
432
|
-
s.gsub(/\B!\(((?:https?|rse|dfs):\/\/[^\)]+)\)/) do
|
433
|
-
|
463
|
+
|
464
|
+
s.gsub(/\B!\(((?:https?|rse|dfs):\/\/[^\)]+)\)/) do
|
465
|
+
RXFReader.read(source=($1) ).first
|
434
466
|
end
|
435
467
|
|
436
468
|
end
|
437
|
-
|
438
|
-
|
469
|
+
|
470
|
+
|
439
471
|
def escape(s)
|
440
472
|
s.gsub('<','<').gsub('>','>')
|
441
473
|
end
|
442
|
-
|
474
|
+
|
443
475
|
def formify(s)
|
444
|
-
|
476
|
+
|
445
477
|
s.split(/(?=\n\w+)/).map do |s|
|
446
|
-
|
478
|
+
|
447
479
|
if s =~ /(?=\w+\n\n* \w+: +\[ +\])/ then
|
448
480
|
create_form(s)
|
449
481
|
else
|
450
482
|
s
|
451
483
|
end
|
452
|
-
|
484
|
+
|
453
485
|
end.join
|
454
|
-
|
486
|
+
|
455
487
|
end
|
456
|
-
|
488
|
+
|
457
489
|
def iframetag(s)
|
458
|
-
|
490
|
+
|
459
491
|
s.gsub(/\B!i\[\]\((https?:\/\/[^\)]+)\)(\{[^\}]+\})?/) do |x|
|
460
|
-
|
492
|
+
|
461
493
|
url = ($1)
|
462
494
|
attr = ($2)
|
463
495
|
|
464
496
|
h = attr ? attr.scan(/(\w+):\s+['"]?(\w+)?/).to_h : {}
|
465
|
-
attributes = h.any? ? (' ' +
|
497
|
+
attributes = h.any? ? (' ' +
|
466
498
|
h.map {|k,v| "%s='%s'" % [k,v]}.join(' ')) : ''
|
467
499
|
|
468
500
|
"<iframe src='%s'%s></iframe>" % [url, attributes]
|
@@ -470,8 +502,8 @@ class Martile
|
|
470
502
|
|
471
503
|
|
472
504
|
end
|
473
|
-
|
474
|
-
|
505
|
+
|
506
|
+
|
475
507
|
|
476
508
|
def list_to_html(s,symbol='#')
|
477
509
|
|
@@ -479,11 +511,11 @@ class Martile
|
|
479
511
|
tag = {'#' => 'ol', '\*' => 'ul'}[symbol]
|
480
512
|
|
481
513
|
s.split(/(?=\[#{symbol}|^#{symbol*2})/).map do |x|
|
482
|
-
|
514
|
+
|
483
515
|
if x.strip.length > 0 then
|
484
516
|
s2, remainder = [x[/\[#{symbol}.*#{symbol}[^\]]+\]/m], ($').to_s]
|
485
517
|
end
|
486
|
-
|
518
|
+
|
487
519
|
if s2 then
|
488
520
|
|
489
521
|
raw_list = s2[1..-2].split(/^#{symbol}/).reject(&:empty?).map(&:strip)
|
@@ -492,23 +524,23 @@ class Martile
|
|
492
524
|
ignore_domainlabel: @ignore_domainlabel).to_html)\
|
493
525
|
.to_html[/<p>(.*)<\/p>/,1]}.join
|
494
526
|
list + remainder.to_s
|
495
|
-
|
527
|
+
|
496
528
|
else
|
497
|
-
|
529
|
+
|
498
530
|
x
|
499
|
-
|
531
|
+
|
500
532
|
end
|
501
|
-
|
533
|
+
|
502
534
|
end.join
|
503
535
|
|
504
536
|
end
|
505
|
-
|
537
|
+
|
506
538
|
def filter_on(s)
|
507
539
|
|
508
540
|
@filter = []
|
509
541
|
|
510
542
|
a = s.split(/(?=\{::nomarkdown2?\})/).map.with_index do |row, i|
|
511
|
-
|
543
|
+
|
512
544
|
row.sub(/\{::nomarkdown2?\}.*{:2?\/}/m) do |pattern|
|
513
545
|
placeholder = '!' + Time.now.to_i.to_s + i.to_s
|
514
546
|
@filter << [placeholder, pattern]
|
@@ -518,11 +550,11 @@ class Martile
|
|
518
550
|
end
|
519
551
|
|
520
552
|
a.join
|
521
|
-
|
522
|
-
end
|
523
|
-
|
553
|
+
|
554
|
+
end
|
555
|
+
|
524
556
|
def filter_off(raw_s)
|
525
|
-
|
557
|
+
|
526
558
|
s = raw_s.clone
|
527
559
|
@filter.each {|id, x| s.sub!(id, x) }
|
528
560
|
return s
|
@@ -530,14 +562,14 @@ class Martile
|
|
530
562
|
end
|
531
563
|
|
532
564
|
def apply_filter(s)
|
533
|
-
|
565
|
+
|
534
566
|
s1 = filter_on(s)
|
535
567
|
s2 = yield s1
|
536
568
|
s3 = filter_off s2
|
537
|
-
|
569
|
+
|
538
570
|
return s3
|
539
571
|
end
|
540
|
-
|
572
|
+
|
541
573
|
|
542
574
|
def explicit_list_to_html(s)
|
543
575
|
|
@@ -562,25 +594,25 @@ class Martile
|
|
562
594
|
else
|
563
595
|
s
|
564
596
|
end
|
565
|
-
|
597
|
+
|
566
598
|
end
|
567
|
-
|
599
|
+
|
568
600
|
def hyperlinkify(s)
|
569
|
-
|
601
|
+
|
570
602
|
s.gsub(/\[([^\[]+)\]\(([^\)]+\)\)?\))/) do |x|
|
571
603
|
"<a href='#{$2.chop}'>#{$1}</a>"
|
572
604
|
end
|
573
605
|
|
574
606
|
end
|
575
|
-
|
576
|
-
|
607
|
+
|
608
|
+
|
577
609
|
def mtlite_utils(s)
|
578
|
-
|
610
|
+
|
579
611
|
# convert square brackets to unicode check boxes
|
580
|
-
# replaces a [] with a unicode checkbox,
|
612
|
+
# replaces a [] with a unicode checkbox,
|
581
613
|
# and [x] with a unicode checked checkbox
|
582
614
|
s2 = s.gsub(/\s\[ {0,1}\]\s/,' ☐ ').gsub(/\s\[x\]\s/,' ☑ ')
|
583
|
-
|
615
|
+
|
584
616
|
# create domain labels for hyperlinks
|
585
617
|
#
|
586
618
|
s3 = s2.gsub(/(?:^\[|\s\[)[^\]]+\]\((https?:\/\/[^\s]+)/) do |x|
|
@@ -596,60 +628,60 @@ class Martile
|
|
596
628
|
# e.g. -milk cow- becomes <del>milk cow</del>
|
597
629
|
s3.gsub(/\s-[^-]+-?[^-]+-[\s\]]/) do |x|
|
598
630
|
x.sub(/-([&\w]+.*\w+)-/,'<del>\1</del>')
|
599
|
-
end
|
631
|
+
end
|
600
632
|
|
601
633
|
end
|
602
|
-
|
634
|
+
|
603
635
|
def nomarkdown(s)
|
604
636
|
s.gsub(/\b'\b/,"{::nomarkdown}'{:/}")
|
605
637
|
end
|
606
|
-
|
638
|
+
|
607
639
|
def qrcodetag(s)
|
608
|
-
|
609
|
-
s.gsub(/\B!q\[\]\((https?:\/\/[^\)]+)\)/) do
|
610
|
-
|
611
|
-
svg = RQRCode::QRCode.new($1).as_svg
|
640
|
+
|
641
|
+
s.gsub(/\B!q\[\]\((https?:\/\/[^\)]+)\)/) do
|
642
|
+
|
643
|
+
svg = RQRCode::QRCode.new($1).as_svg
|
612
644
|
svg.slice!(/.*(?=<svg)/m)
|
613
|
-
|
645
|
+
|
614
646
|
svg
|
615
647
|
end
|
616
648
|
|
617
|
-
end
|
618
|
-
|
649
|
+
end
|
650
|
+
|
619
651
|
def ordered_list_to_html(s)
|
620
652
|
list_to_html s, '#'
|
621
653
|
end
|
622
|
-
|
654
|
+
|
623
655
|
def dx_render_table(dx, raw_select)
|
624
|
-
|
656
|
+
|
625
657
|
fields, markdown, heading, inner = nil, true, true, true
|
626
|
-
|
658
|
+
|
627
659
|
if raw_select then
|
628
660
|
|
629
661
|
raw_fields = raw_select[/select:\s*["']([^"']+)/,1]
|
630
|
-
|
662
|
+
|
631
663
|
fields = raw_fields.split(/\s*,\s*/) if raw_fields
|
632
664
|
inner = false if raw_select[/\bmarkdown:\s*false\b/]
|
633
665
|
heading = false if raw_select[/\bheading:\s*false\b/]
|
634
666
|
|
635
667
|
end
|
636
|
-
|
637
668
|
|
638
|
-
|
669
|
+
|
670
|
+
dx.to_table(markdown: true, fields: fields, innermarkdown: inner,
|
639
671
|
heading: heading)
|
640
|
-
end
|
641
|
-
|
672
|
+
end
|
673
|
+
|
642
674
|
def dx_render_table2(dx, raw_select)
|
643
|
-
|
675
|
+
|
644
676
|
markdown, heading = true, true
|
645
|
-
|
677
|
+
|
646
678
|
if raw_select then
|
647
679
|
raw_fields = raw_select[/select:\s*["']([^"']+)/,1]
|
648
680
|
fields = raw_fields.split(/\s*,\s*/) if raw_fields
|
649
681
|
markdown = false if raw_select[/\bmarkdown:\s*false\b/]
|
650
682
|
heading = false if raw_select[/\bheading:\s*false\b/]
|
651
683
|
end
|
652
|
-
|
684
|
+
|
653
685
|
print_row = -> (row, widths) do
|
654
686
|
'| ' + row.map\
|
655
687
|
.with_index {|y,i| y.to_s.ljust(widths[i])}.join(' | ') + " |\n"
|
@@ -667,12 +699,12 @@ class Martile
|
|
667
699
|
|
668
700
|
|
669
701
|
flat_records = raw_select ? dx.to_a(select: fields) : dx.to_a
|
670
|
-
|
702
|
+
|
671
703
|
keys = flat_records.map(&:keys).first
|
672
704
|
raw_vals = flat_records.map(&:values)
|
673
|
-
|
705
|
+
|
674
706
|
# create Markdown hyperlinks for any URLs
|
675
|
-
|
707
|
+
|
676
708
|
vals = raw_vals.map do |row|
|
677
709
|
|
678
710
|
row.map do |col|
|
@@ -688,35 +720,64 @@ class Martile
|
|
688
720
|
url_title = (a.join('.') + path)[0..39] + '...'
|
689
721
|
|
690
722
|
"[%s](%s)" % [url_title, col]
|
691
|
-
|
723
|
+
|
692
724
|
else
|
693
|
-
|
694
|
-
if markdown then
|
695
|
-
"{::nomarkdown}" +
|
725
|
+
|
726
|
+
if markdown then
|
727
|
+
"{::nomarkdown}" +
|
696
728
|
RDiscount.new(col).to_html.strip.gsub("\n",'') + "{:/}"
|
697
729
|
else
|
698
730
|
|
699
731
|
col
|
700
|
-
|
732
|
+
|
701
733
|
end
|
702
|
-
|
734
|
+
|
703
735
|
end
|
704
|
-
|
736
|
+
|
705
737
|
r
|
706
738
|
end
|
707
|
-
end
|
739
|
+
end
|
708
740
|
|
709
741
|
widths = ([keys] + vals).transpose.map{|x| x.max_by(&:length).length}
|
710
|
-
|
711
|
-
|
742
|
+
|
743
|
+
|
712
744
|
th = heading ? print_row.call(keys, widths) : ''
|
713
|
-
th_line = print_thline.call widths.map {|x| '-' * (x+1)}, widths
|
714
|
-
tb = print_rows.call(vals, widths)
|
715
|
-
|
745
|
+
th_line = print_thline.call widths.map {|x| '-' * (x+1)}, widths
|
746
|
+
tb = print_rows.call(vals, widths)
|
747
|
+
|
716
748
|
table = th + th_line + tb
|
717
|
-
|
749
|
+
|
750
|
+
end
|
751
|
+
|
752
|
+
|
753
|
+
def mindwords(s1)
|
754
|
+
|
755
|
+
s = s1.clone
|
756
|
+
|
757
|
+
doc = Rexle.new("<root>#{s}</root>")
|
758
|
+
puts 'doc.root.xml: ' + doc.root.xml.inspect if @debug
|
759
|
+
a = doc.root.xpath('mindwords').map.with_index do |e, i |
|
760
|
+
puts 'e: ' + e.text.inspect if @debug
|
761
|
+
"<pre>%s</pre>" % MindWords.new(e.text).to_outline
|
762
|
+
|
718
763
|
end
|
719
|
-
|
764
|
+
puts 'mindwords a:' + a.inspect if @debug
|
765
|
+
|
766
|
+
# replaces the <mindwords> XML with HTML
|
767
|
+
a.each do |html|
|
768
|
+
|
769
|
+
istart = s =~ /^<mindwords[^>]*>/
|
770
|
+
iend = s =~ /<\/mindwords>/
|
771
|
+
puts [istart, iend].inspect if @debug
|
772
|
+
s.slice!(istart, (iend - istart) + '</mindwords>'.length + 1)
|
773
|
+
s.insert(istart, html)
|
774
|
+
|
775
|
+
end
|
776
|
+
|
777
|
+
return s
|
778
|
+
|
779
|
+
end
|
780
|
+
|
720
781
|
def unordered_list_to_html(s)
|
721
782
|
list_to_html s, '\*'
|
722
783
|
end
|
@@ -724,131 +785,131 @@ class Martile
|
|
724
785
|
def parse__data__(s)
|
725
786
|
|
726
787
|
puts 'inside parse__data__'.info if @debug
|
727
|
-
|
788
|
+
|
728
789
|
a = s.split(/^__DATA__$/,2)
|
729
790
|
|
730
791
|
data = a[-1]
|
731
|
-
|
792
|
+
|
732
793
|
links, locals = data.split(/(?=<)/, 2)
|
733
|
-
|
794
|
+
|
734
795
|
links.strip.split("\n").each do |line|
|
735
|
-
|
796
|
+
|
736
797
|
puts ('line:' + line.inspect).debug if @debug
|
737
798
|
next if line.nil?
|
738
|
-
|
799
|
+
|
739
800
|
id, url = line.split(/:\s+/,2)
|
740
801
|
puts 'id: ' + id.inspect if @debug
|
741
802
|
puts 'url: ' + url.inspect if @debug
|
742
|
-
|
803
|
+
|
743
804
|
obj, _ = RXFHelper.read(url, auto: true)
|
744
805
|
define_singleton_method(id.to_sym) { @data_source[id] }
|
745
|
-
@data_source[id] = obj
|
746
|
-
|
806
|
+
@data_source[id] = obj
|
807
|
+
|
747
808
|
end
|
748
|
-
|
809
|
+
|
749
810
|
puts 'before locals' if @debug
|
750
|
-
|
811
|
+
|
751
812
|
locals ||= ''
|
752
|
-
|
813
|
+
|
753
814
|
locals.split(/(?=<\?)/).each do |x|
|
754
815
|
|
755
816
|
puts ('__data__ x: ' + x.inspect).debug if @debug
|
756
|
-
|
817
|
+
|
757
818
|
s2 = x.strip
|
758
819
|
next if s2.empty?
|
759
|
-
|
820
|
+
|
760
821
|
id = s2.lines.first[/id=["']([^"']+)/,1]
|
761
|
-
|
762
|
-
@data_source[id] = case s2
|
822
|
+
|
823
|
+
@data_source[id] = case s2
|
763
824
|
when /^<\?dynarex /
|
764
|
-
|
825
|
+
|
765
826
|
dx = Dynarex.new
|
766
827
|
dx.import s2
|
767
828
|
dx
|
768
|
-
|
829
|
+
|
769
830
|
when /^<\?mindmap(?:viz)? /
|
770
831
|
puts 's2: ' + s2.inspect if @debug
|
771
832
|
Mindmapviz.new s2
|
772
|
-
|
833
|
+
|
773
834
|
when /^<\?flowchart(?:viz)? /
|
774
|
-
|
775
|
-
Flowchartviz.new s2
|
776
|
-
|
835
|
+
|
836
|
+
Flowchartviz.new s2
|
837
|
+
|
777
838
|
when /^<\?graphvizml /
|
778
|
-
|
779
|
-
GraphVizML.new s2
|
780
|
-
|
839
|
+
|
840
|
+
GraphVizML.new s2
|
841
|
+
|
781
842
|
when /^<\?pxgraphviz /
|
782
843
|
puts 'before PxGraphViz.new'.info if @debug
|
783
|
-
PxGraphViz.new s2, debug: @debug
|
784
|
-
|
844
|
+
PxGraphViz.new s2, debug: @debug
|
845
|
+
|
785
846
|
when /^<\?depviz /
|
786
|
-
|
787
|
-
DepViz.new s2
|
788
|
-
|
847
|
+
|
848
|
+
DepViz.new s2
|
849
|
+
|
789
850
|
when /^<\?sectionx /
|
790
|
-
|
851
|
+
|
791
852
|
sx = SectionX.new
|
792
853
|
sx.import s2
|
793
854
|
define_singleton_method(id.to_sym) { @data_source[id] }
|
794
855
|
sx
|
795
|
-
|
856
|
+
|
796
857
|
when /^<\?kvx /
|
797
|
-
|
858
|
+
|
798
859
|
kvx = Kvx.new s2
|
799
860
|
|
800
861
|
define_singleton_method(id.to_sym) { @data_source[id] }
|
801
|
-
kvx
|
802
|
-
|
803
|
-
end
|
862
|
+
kvx
|
863
|
+
|
864
|
+
end
|
804
865
|
end
|
805
|
-
|
866
|
+
|
806
867
|
a[0..-2].join
|
807
|
-
|
868
|
+
|
808
869
|
end
|
809
|
-
|
870
|
+
|
810
871
|
def sidenav(s1)
|
811
|
-
|
872
|
+
|
812
873
|
s = s1.clone
|
813
874
|
if s =~ /^<sidenav/ then
|
814
|
-
|
875
|
+
|
815
876
|
content = s[/(<sidenav[^>]+\/>|<sidenav[^>]+>([^<]*<[^>]+>)?)/]
|
816
877
|
puts ('content: ' + content.inspect) if @debug
|
817
|
-
|
878
|
+
|
818
879
|
doc = if content then
|
819
|
-
|
880
|
+
|
820
881
|
s.sub!(content,'')
|
821
882
|
doc2 = Rexle.new(content)
|
822
|
-
|
883
|
+
|
823
884
|
h = doc2.root.attributes
|
824
885
|
target = h[:target] || 'pgview'
|
825
|
-
|
886
|
+
|
826
887
|
txt = if h[:src] then
|
827
|
-
|
888
|
+
RXFReader.read(h[:src]).first.sub(/<\?links[^>]+>\n/,'')
|
828
889
|
else
|
829
890
|
doc2.root.text
|
830
891
|
end
|
831
|
-
|
892
|
+
|
832
893
|
puts 'txt: ' + txt.inspect if @debug
|
833
|
-
|
894
|
+
|
834
895
|
html = HtmlCom::Tree.new(txt).to_webpage
|
835
|
-
puts 'html: ' + html.inspect if @debug
|
836
|
-
|
896
|
+
puts 'html: ' + html.inspect if @debug
|
897
|
+
|
837
898
|
doc2 = Rexle.new(html)
|
838
|
-
|
899
|
+
|
839
900
|
doc2.root.xpath('body/ul[@class="sidenav"]/li//a').each do |node|
|
840
901
|
node.attributes[:target] = target
|
841
902
|
end
|
842
|
-
|
903
|
+
|
843
904
|
doc2
|
844
|
-
|
905
|
+
|
845
906
|
else
|
846
907
|
s.sub!(/^<sidenav\/>/,'')
|
847
908
|
html = HtmlCom::Tree.new(s).to_webpage
|
848
909
|
Rexle.new(html)
|
849
910
|
end
|
850
|
-
|
851
|
-
|
911
|
+
|
912
|
+
|
852
913
|
html2 = Kramdown::Document.new(Martile.new(s, toc: false).to_html)\
|
853
914
|
.to_html
|
854
915
|
div = Rexle.new("<div class='main'>%s</div>" % html2)
|
@@ -862,7 +923,7 @@ class Martile
|
|
862
923
|
end
|
863
924
|
|
864
925
|
def table_to_html(s)
|
865
|
-
|
926
|
+
|
866
927
|
# create any tables
|
867
928
|
s.gsub!(/^\[[^|]+\|[^\n]+\n\|[^\]]+\]/) do |x|
|
868
929
|
|
@@ -884,50 +945,50 @@ class Martile
|
|
884
945
|
end
|
885
946
|
return s
|
886
947
|
end
|
887
|
-
|
948
|
+
|
888
949
|
def tabs(s1)
|
889
|
-
|
950
|
+
|
890
951
|
s = s1.clone
|
891
|
-
|
952
|
+
|
892
953
|
doc = Rexle.new("<root>#{s}</root>")
|
893
954
|
puts 'doc.root.xml: ' + doc.root.xml.inspect if @debug
|
894
955
|
a = doc.root.xpath('tabs').map.with_index do |e, i |
|
895
|
-
|
956
|
+
|
896
957
|
build = JsMenuBuilder.new()
|
897
958
|
build.import(e.xml)
|
898
|
-
|
959
|
+
|
899
960
|
if i < 1 then
|
900
|
-
@css << build.to_css
|
961
|
+
@css << build.to_css
|
901
962
|
@js << build.to_js
|
902
963
|
end
|
903
|
-
|
964
|
+
|
904
965
|
build.to_html
|
905
|
-
|
966
|
+
|
906
967
|
end
|
907
968
|
puts 'tabs a:' + a.inspect if @debug
|
908
969
|
|
909
970
|
# replaces the <tabs> XML with HTML
|
910
971
|
a.each do |html|
|
911
|
-
|
972
|
+
|
912
973
|
istart = s =~ /^<tabs[^>]*>/
|
913
974
|
iend = s =~ /<\/tabs>/
|
914
975
|
s.slice!(istart, (iend - istart) + '</tab>'.length + 1)
|
915
976
|
s.insert(istart, html)
|
916
|
-
|
977
|
+
|
917
978
|
end
|
918
|
-
|
979
|
+
|
919
980
|
return s
|
920
|
-
|
981
|
+
|
921
982
|
end
|
922
983
|
|
923
984
|
def underline(s)
|
924
985
|
|
925
|
-
s.gsub(/_[^_\(\)\n]+_\b/) do |x|
|
986
|
+
s.gsub(/_[^_\(\)\n]+_\b/) do |x|
|
926
987
|
"<span class='underline'>%s</span>" % x[1..-2]
|
927
988
|
end
|
928
989
|
|
929
990
|
end
|
930
|
-
|
991
|
+
|
931
992
|
def highlight(s)
|
932
993
|
|
933
994
|
s.gsub(/\^[\w ]+\^/) {|x| "<mark>%s</mark>" % x[1..-2] }
|
@@ -937,41 +998,41 @@ class Martile
|
|
937
998
|
def script_out(s)
|
938
999
|
s.gsub(/({!)[^}]+\}/) {|x| eval(x[/(?<={!)[^}]+/]) }
|
939
1000
|
end
|
940
|
-
|
1001
|
+
|
941
1002
|
def smartlink(s)
|
942
|
-
|
1003
|
+
|
943
1004
|
s.split(/(?= \?)/).inject('') do |r, substring|
|
944
1005
|
|
945
1006
|
r << substring.gsub(/\B\?([^\n]+) +(https?:\/\/.[^\?]+\?)(?=\B)/) do |x|
|
946
|
-
|
1007
|
+
|
947
1008
|
content, link = $1, ($2).chop
|
948
|
-
|
1009
|
+
|
949
1010
|
if (link)[/\)$/] then
|
950
1011
|
"<a href='%s'>%s</a>" % [link, content]
|
951
1012
|
else
|
952
1013
|
"[%s](%s)" % [content, link]
|
953
1014
|
end
|
954
1015
|
end
|
955
|
-
|
956
|
-
end
|
957
1016
|
|
958
|
-
|
959
|
-
|
1017
|
+
end
|
1018
|
+
|
1019
|
+
end
|
1020
|
+
|
960
1021
|
def slashpre(s)
|
961
1022
|
s.gsub(/^\/\/([^\/]+)^\/\//) do |x|
|
962
1023
|
"<pre>#{($1).lines.map{|y| y.sub(/^ +/,'')}.join}</pre>"
|
963
1024
|
end
|
964
|
-
|
1025
|
+
|
965
1026
|
end
|
966
|
-
|
967
|
-
# makes HTML sections out of string blocks which start with an
|
1027
|
+
|
1028
|
+
# makes HTML sections out of string blocks which start with an
|
968
1029
|
# equals sign and end with an equals sign
|
969
1030
|
def section(s)
|
970
1031
|
|
971
1032
|
a = s.lines
|
972
1033
|
|
973
1034
|
a2 = a.inject([[]]) do |r,x|
|
974
|
-
|
1035
|
+
|
975
1036
|
match = x.match(/^={1}(?:#)?([\w-]+)?$/)
|
976
1037
|
|
977
1038
|
if match then
|
@@ -981,10 +1042,10 @@ class Martile
|
|
981
1042
|
list = r.pop
|
982
1043
|
puts ('section | list: ' + list.inspect).debug if @debug
|
983
1044
|
|
984
|
-
r << ["%s%s</section>" %
|
1045
|
+
r << ["%s%s</section>" %
|
985
1046
|
[list[0], \
|
986
1047
|
Martile.new(list[1..-1].join, \
|
987
|
-
ignore_domainlabel: @ignore_domainlabel).to_s
|
1048
|
+
ignore_domainlabel: @ignore_domainlabel, embedded: true).to_s
|
988
1049
|
]
|
989
1050
|
]
|
990
1051
|
puts ('section | r: ' + r.inspect) if @debug
|
@@ -992,10 +1053,10 @@ class Martile
|
|
992
1053
|
else
|
993
1054
|
|
994
1055
|
raw_id = match.captures.first
|
995
|
-
id = raw_id ? (" id='%s'" % raw_id) : ''
|
1056
|
+
id = raw_id ? (" id='%s'" % raw_id) : ''
|
996
1057
|
r << ["<section#{id} markdown='1'>"]
|
997
1058
|
end
|
998
|
-
|
1059
|
+
|
999
1060
|
else
|
1000
1061
|
|
1001
1062
|
r.last << x
|
@@ -1006,44 +1067,44 @@ class Martile
|
|
1006
1067
|
|
1007
1068
|
a2.join
|
1008
1069
|
end
|
1009
|
-
|
1070
|
+
|
1010
1071
|
def svgtag(s)
|
1011
|
-
|
1012
|
-
s.gsub(/\B!s\[\]\((#\w+|https?:\/\/[^\)]+)\)/) do
|
1013
|
-
|
1014
|
-
source = ($1)
|
1015
|
-
|
1072
|
+
|
1073
|
+
s.gsub(/\B!s\[\]\((#\w+|https?:\/\/[^\)]+)\)/) do
|
1074
|
+
|
1075
|
+
source = ($1)
|
1076
|
+
|
1016
1077
|
svg = if source =~ /^http/ then
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1078
|
+
|
1079
|
+
RXFReader.read(source).first
|
1080
|
+
|
1020
1081
|
else
|
1021
|
-
|
1082
|
+
|
1022
1083
|
@data_source[source[/\w+/]].to_svg
|
1023
|
-
|
1024
|
-
end
|
1025
|
-
|
1084
|
+
|
1085
|
+
end
|
1086
|
+
|
1026
1087
|
svg.slice!(/.*(?=<svg)/m)
|
1027
1088
|
svg
|
1028
1089
|
end
|
1029
1090
|
|
1030
1091
|
end
|
1031
|
-
|
1032
|
-
|
1092
|
+
|
1093
|
+
|
1033
1094
|
def videotag(s)
|
1034
|
-
|
1095
|
+
|
1035
1096
|
s.gsub(/\B!v\[\]\((https?:\/\/[^\)]+)\)(\{[^\}]+\})?/) do |match|
|
1036
1097
|
|
1037
1098
|
files = ($1).split
|
1038
1099
|
attr = ($2)
|
1039
1100
|
|
1040
1101
|
h = attr ? attr.scan(/(\w+):\s+(\w+)/).to_h : {}
|
1041
|
-
attributes = h.any? ? (' ' +
|
1102
|
+
attributes = h.any? ? (' ' +
|
1042
1103
|
h.map {|k,v| "%s='%s'" % [k,v]}.join(' ')) : ''
|
1043
1104
|
|
1044
1105
|
h2 = {
|
1045
|
-
/\.og[gv]$/ => 'ogg', /\.mp4$/ => 'mp4', /\.mov$/ => 'mov',
|
1046
|
-
/\.webm$/ => 'webm'
|
1106
|
+
/\.og[gv]$/ => 'ogg', /\.mp4$/ => 'mp4', /\.mov$/ => 'mov',
|
1107
|
+
/\.webm$/ => 'webm'
|
1047
1108
|
}
|
1048
1109
|
|
1049
1110
|
sources = files.map do |file|
|
@@ -1053,13 +1114,13 @@ class Martile
|
|
1053
1114
|
end
|
1054
1115
|
|
1055
1116
|
"<video controls='controls'%s>\n%s\n</video>" % [attributes, sources.join("\n")]
|
1056
|
-
end
|
1057
|
-
|
1117
|
+
end
|
1118
|
+
|
1058
1119
|
end
|
1059
|
-
|
1120
|
+
|
1060
1121
|
def list_item_to_hyperlink(s)
|
1061
|
-
|
1122
|
+
|
1062
1123
|
s.gsub(/\B(\* +)([^\n]+)\s+(https?:\/\/.*)/,'\1[\2](\3)')
|
1063
1124
|
|
1064
|
-
end
|
1125
|
+
end
|
1065
1126
|
end
|