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.
Files changed (6) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/lib/martile.rb +358 -297
  4. data.tar.gz.sig +0 -0
  5. metadata +56 -36
  6. 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
- def initialize(raw_s='', ignore_domainlabel: nil, toc: true, debug: false,
98
- log: nil)
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
- #puts 's4 : ' + s4.inspect
144
+ puts ('s50: ' + s50.inspect).debug if @debug
128
145
 
129
146
  s60 = apply_filter(s50) {|x| unordered_list_to_html x }
130
- #puts 's5 : ' + s5.inspect
147
+ puts ('s60: ' + s60.inspect).debug if @debug
131
148
 
132
149
  s70 = apply_filter(s60) {|x| dynarex_to_markdown x }
133
- #puts 's6 :' + s6.inspect
150
+ puts ('s70: ' + s70.inspect).debug if @debug
134
151
 
135
152
  s80 = apply_filter(s70) {|x| table_to_html x }
136
- #puts 's7 : ' + s7.inspect
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
- #puts 's12 : ' + s12.inspect
168
+ puts 's120 : ' + s120.inspect if @debug
151
169
  s130 = apply_filter(s120) {|x| videotag x }
152
- #puts 's13 : ' + s13.inspect
170
+ puts 's130 : ' + s130.inspect if @debug
153
171
  s140 = apply_filter(s130) {|x| iframetag x }
154
- #puts 's14 : ' + s14.inspect
172
+ puts 's140 : ' + s140.inspect if @debug
155
173
  s150 = apply_filter(s140) {|x| kvx_to_dl x }
156
- #puts 's15 : ' + s15.inspect
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
- #puts 's16 : ' + s16.inspect
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
- @to_s = s245.to_s
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 ('s235 after bang_xml: ' + s253.inspect).debug if @debug
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
- toc = false if s257 =~ /class=['"]sidenav['"]>/
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(/(?=^\!\w+)/)
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
- s.lines.chunk {|x| x =~ /^\n|^ |\n/ }.map do |_, x|
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
- RXFHelper.read(source=($1) ).first
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('<','&lt;').gsub('>','&gt;')
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/,' &#9744; ').gsub(/\s\[x\]\s/,' &#9745; ')
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
- dx.to_table(markdown: true, fields: fields, innermarkdown: inner,
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
- RXFHelper.read(h[:src]).first.sub(/<\?links[^>]+>\n/,'')
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
- end
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
- RXFHelper.read(source).first
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