martile 1.4.6 → 1.6.1

Sign up to get free protection for your applications and to get access to all the features.
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