mdless 2.0.1 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c645677f1a192348600bf54180afe501b76888d14bad121c4577090ca81718b2
4
- data.tar.gz: 7e82688bd079cede12e529a813c628297070b91b47d68276e54b368b7155bc25
3
+ metadata.gz: 8cc069a55f00ad3b4165a8001caac96382742d1cb653ceb20b45402a76d2ec22
4
+ data.tar.gz: 1e9749a769176d7c9513c61d5edf51332525282e4067a4b63612028d05f89a3d
5
5
  SHA512:
6
- metadata.gz: 830a9aea162d1481ceca6a5dd9cfed3e1a46821a4f1ceaae0d77a843d19a9d0515338025120bc8cfd6bd55fec449009782be872f6558d01d55155bfea9699804
7
- data.tar.gz: ae994c34ece07c3fa05cad41c0e28c866e642dd268a6d175e8746bbd1c8e4d492ca1eef4b943ba506b4769079958296f0ac885e3a10eadc37d595164618db349
6
+ metadata.gz: ee64552eeb8c46715bcda2a3ce812affc8988837deacbc70fd856c426fc280108b561f5c2c005c2354cf02e1f09821441df8f0a1331bbf31c5c59e3991f73a70
7
+ data.tar.gz: 409a8507a1e6419aa2e408872a16a68af8e53e0d5b23594c0cec3175259d35b63474dd39428de78654a7b249cc914f23c03926768210e239de39bf6a8b1a6d06
@@ -0,0 +1,653 @@
1
+ module Redcarpet
2
+ module Render
3
+ class Console < Base
4
+ include CLIMarkdown::Colors
5
+ include CLIMarkdown::Theme
6
+ attr_writer :theme, :cols, :log, :options, :file
7
+
8
+ @@listitemid = 0
9
+ @@listid = 0
10
+ @@footnotes = []
11
+
12
+ def xc
13
+ x + color('text')
14
+ end
15
+
16
+ def x
17
+ c([:reset])
18
+ end
19
+
20
+ def color_table(input)
21
+ first = true
22
+ input.split(/\n/).map do |line|
23
+ if first
24
+ if line =~ /^\+-+/
25
+ line.gsub!(/^/, color('table border'))
26
+ else
27
+ first = false
28
+ line.gsub!(/\|/, "#{color('table border')}|#{color('table header')}")
29
+ end
30
+ elsif line.strip =~ /^[|:\- +]+$/
31
+ line.gsub!(/^(.*)$/, "#{color('table border')}\\1#{color('table color')}")
32
+ line.gsub!(/([:\-+]+)/, "#{color('table divider')}\\1#{color('table border')}")
33
+ else
34
+ line.gsub!(/\|/, "#{color('table border')}|#{color('table color')}")
35
+ end
36
+ end.join("\n")
37
+ end
38
+
39
+ def exec_available(cli)
40
+ if File.exist?(File.expand_path(cli))
41
+ File.executable?(File.expand_path(cli))
42
+ else
43
+ TTY::Which.exist?(cli)
44
+ end
45
+ end
46
+
47
+ def valid_lexer?(language)
48
+ lexers = %w(Clipper XBase Cucumber cucumber Gherkin gherkin RobotFramework robotframework abap ada ada95ada2005 ahk antlr-as antlr-actionscript antlr-cpp antlr-csharp antlr-c# antlr-java antlr-objc antlr-perl antlr-python antlr-ruby antlr-rb antlr apacheconf aconf apache applescript as actionscript as3 actionscript3 aspectj aspx-cs aspx-vb asy asymptote autoit Autoit awk gawk mawk nawk basemake bash sh ksh bat bbcode befunge blitzmax bmax boo brainfuck bf bro bugs winbugs openbugs c-objdump c ca65 cbmbas ceylon cfengine3 cf3 cfm cfs cheetah spitfire clojure clj cmake cobol cobolfree coffee-script coffeescript common-lisp cl console control coq cpp c++ cpp-objdump c++-objdumb cxx-objdump croc csharp c# css+django css+jinja css+erb css+ruby css+genshitext css+genshi css+lasso css+mako css+myghty css+php css+smarty css cuda cu cython pyx d-objdump d dart delphi pas pascal objectpascal dg diff udiff django jinja dpatch dtd duel Duel Engine Duel View JBST jbst JsonML+BST dylan-console dylan-repl dylan-lid lid dylan ec ecl elixir ex exs erb erl erlang evoque factor fan fancy fy felix flx fortran fsharp gas genshi kid xml+genshi xml+kid genshitext glsl gnuplot go gooddata-cl gosu groff nroff man groovy gst haml HAML haskell hs haxeml hxml html+cheetah html+spitfire html+django html+jinja html+evoque html+genshi html+kid html+lasso html+mako html+myghty html+php html+smarty html+velocity html http hx haXe hybris hy idl iex ini cfg io ioke ik irc jade JADE jags java jlcon js+cheetah javascript+cheetah js+spitfire javascript+spitfire js+django javascript+django js+jinja javascript+jinja js+erb javascript+erb js+ruby javascript+ruby js+genshitext js+genshi javascript+genshitext javascript+genshi js+lasso javascript+lasso js+mako javascript+mako js+myghty javascript+myghty js+php javascript+php js+smarty javascript+smarty js javascript json jsp julia jl kconfig menuconfig linux-config kernel-config koka kotlin lasso lassoscript lhs literate-haskell lighty lighttpd live-script livescript llvm logos logtalk lua make makefile mf bsdmake mako maql mason matlab matlabsession minid modelica modula2 m2 monkey moocode moon moonscript mscgen msc mupad mxml myghty mysql nasm nemerle newlisp newspeak nginx nimrod nim nsis nsi nsh numpy objdump objective-c++ objectivec++ obj-c++ objc++ objective-c objectivec obj-c objc objective-j objectivej obj-j objj ocaml octave ooc opa openedge abl progress perl pl php php3 php4 php5 plpgsql postgresql postgres postscript pot po pov powershell posh ps1 prolog properties protobuf psql postgresql-console postgres-console puppet py3tb pycon pypylog pypy pytb python py sage python3 py3 qml Qt Meta Language Qt modeling Language racket rkt ragel-c ragel-cpp ragel-d ragel-em ragel-java ragel-objc ragel-ruby ragel-rb ragel raw rb ruby duby rbcon irb rconsole rout rd rebol redcode registry rhtml html+erb html+ruby rst rest restructuredtext rust sass SASS scala scaml SCAML scheme scm scilab scss shell-session smali smalltalk squeak smarty sml snobol sourceslist sources.list sp spec splus s r sql sqlite3 squidconf squid.conf squid ssp stan systemverilog sv tcl tcsh csh tea tex latex text trac-wiki moin treetop ts urbiscript vala vapi vb.net vbnet velocity verilog v vgl vhdl vim xml+cheetah xml+spitfire xml+django xml+jinja xml+erb xml+ruby xml+evoque xml+lasso xml+mako xml+myghty xml+php xml+smarty xml+velocity xml xquery xqy xq xql xqm xslt xtend yaml)
49
+ lexers.include? language.strip
50
+ end
51
+
52
+ def hilite_code(code_block, language)
53
+ @log.error('Syntax highlighting requested by pygmentize is not available') if @options[:syntax_higlight] && !exec_available('pygmentize')
54
+
55
+ if @options[:syntax_higlight] && exec_available('pygmentize')
56
+ lexer = language && valid_lexer?(language) ? "-l #{language}" : '-g'
57
+ begin
58
+ cmd = [
59
+ 'pygmentize -f terminal256',
60
+ "-O style=#{@theme['code_block']['pygments_theme']}",
61
+ lexer,
62
+ '2> /dev/null'
63
+ ].join(' ')
64
+ hilite, s = Open3.capture2(cmd,
65
+ stdin_data: code_block)
66
+ if s.success?
67
+ hilite = xc + hilite.split(/\n/).map do |l|
68
+ [
69
+ color('code_block marker'),
70
+ '> ',
71
+ "#{color('code_block bg')}#{l.strip}#{xc}"
72
+ ].join
73
+ end.join("\n").blackout(@theme['code_block']['bg']) + "#{xc}\n"
74
+ end
75
+ rescue StandardError => e
76
+ @log.error(e)
77
+ hilite = code_block
78
+ end
79
+ else
80
+ hilite = code_block.split(/\n/).map do |line|
81
+ [
82
+ color('code_block marker'),
83
+ '> ',
84
+ color('code_block color'),
85
+ line,
86
+ xc
87
+ ].join
88
+ end.join("\n").blackout(@theme['code_block']['bg']) + "#{xc}\n"
89
+ end
90
+
91
+ [
92
+ xc,
93
+ color('code_block border'),
94
+ '-' * @cols,
95
+ xc,
96
+ "\n",
97
+ color('code_block color'),
98
+ hilite.chomp,
99
+ "\n",
100
+ color('code_block border'),
101
+ '-' * @cols,
102
+ xc
103
+ ].join
104
+ end
105
+
106
+ def color(key)
107
+ val = nil
108
+ keys = key.split(/[ ,>]/)
109
+ if @theme.key?(keys[0])
110
+ val = @theme[keys.shift]
111
+ else
112
+ @log.error("Invalid theme key: #{key}") unless keys[0] =~ /^text/
113
+ return c([:reset])
114
+ end
115
+ keys.each do |k|
116
+ if val.key?(k)
117
+ val = val[k]
118
+ else
119
+ @log.error("Invalid theme key: #{k}")
120
+ return c([:reset])
121
+ end
122
+ end
123
+ if val.is_a? String
124
+ val = "x #{val}"
125
+ res = val.split(/ /).map(&:to_sym)
126
+ c(res)
127
+ else
128
+ c([:reset])
129
+ end
130
+ end
131
+
132
+ def block_code(code, language)
133
+ "\n\n#{hilite_code(code, language)}#{xc}\n\n"
134
+ end
135
+
136
+ def block_quote(quote)
137
+ ret = "\n\n"
138
+ quote.split("\n").each do |line|
139
+ ret += [
140
+ color('blockquote marker color'),
141
+ @theme['blockquote']['marker']['character'],
142
+ color('blockquote color'),
143
+ line,
144
+ "\n"
145
+ ].join('')
146
+ end
147
+ "#{ret}\n\n"
148
+ end
149
+
150
+ def block_html(raw_html)
151
+ "#{color('html color')}#{color_tags(raw_html)}#{xc}"
152
+ end
153
+
154
+ def header(text, header_level)
155
+ pad = ''
156
+ ansi = ''
157
+ case header_level
158
+ when 1
159
+ ansi = color('h1 color')
160
+ pad = color('h1 pad')
161
+ char = @theme['h1']['pad_char'] || '='
162
+ pad += text.length + 2 > @cols ? char * text.length : char * (@cols - (text.length + 1))
163
+ when 2
164
+ ansi = color('h2 color')
165
+ pad = color('h2 pad')
166
+ char = @theme['h2']['pad_char'] || '-'
167
+ pad += text.length + 2 > @cols ? char * text.length : char * (@cols - (text.length + 1))
168
+ when 3
169
+ ansi = color('h3 color')
170
+ when 4
171
+ ansi = color('h4 color')
172
+ when 5
173
+ ansi = color('h5 color')
174
+ else
175
+ ansi = color('h6 color')
176
+ end
177
+
178
+ # If we're in iTerm and not paginating, add
179
+ # iTerm Marks for navigation on h1-3
180
+ if header_level < 4 &&
181
+ ENV['TERM_PROGRAM'] =~ /^iterm/i &&
182
+ @options[:pager] == false
183
+ ansi = "\e]1337;SetMark\a#{ansi}"
184
+ end
185
+
186
+ "\n#{xc}#{ansi}#{text} #{pad}#{xc}\n\n"
187
+ end
188
+
189
+ def hrule()
190
+ "\n\n#{color('hr color')}#{'_' * @cols}#{xc}\n\n"
191
+ end
192
+
193
+ def list(contents, list_type)
194
+ @@listitemid = 0
195
+ @@listid += 1
196
+ "<<list#{@@listid}>>#{contents}<</list#{@@listid}>>"
197
+ end
198
+
199
+ def list_item(text, list_type)
200
+ case list_type
201
+ when :unordered
202
+ [
203
+ "#{color('list bullet')}• ",
204
+ color('list color'),
205
+ text,
206
+ xc
207
+ ].join('')
208
+ when :ordered
209
+ @@listitemid += 1
210
+ [
211
+ color('list number'),
212
+ "#{@@listitemid}. ",
213
+ color('list color'),
214
+ text,
215
+ xc
216
+ ].join('')
217
+ end
218
+ end
219
+
220
+ def paragraph(text)
221
+ "#{xc}#{text}#{xc}#{x}\n\n"
222
+ end
223
+
224
+ @table_cols = nil
225
+
226
+ def table_header_row
227
+ @header_row.map do |alignment|
228
+ case alignment
229
+ when :left
230
+ '|:---'
231
+ when :right
232
+ '|---:'
233
+ when :center
234
+ '|:--:'
235
+ else
236
+ '|----'
237
+ end
238
+ end.join('') + '|'
239
+ end
240
+
241
+ def table(header, body)
242
+ formatted = CLIMarkdown::MDTableCleanup.new([
243
+ "#{header}",
244
+ table_header_row,
245
+ "|\n",
246
+ "#{body}\n\n"
247
+ ].join(''))
248
+ res = formatted.to_md
249
+ "#{color_table(res)}\n"
250
+ # res
251
+ end
252
+
253
+ def table_row(content)
254
+ @table_cols = content.scan(/\|/).count
255
+ %(#{content}\n)
256
+ end
257
+
258
+ def table_cell(content, alignment)
259
+ @header_row ||= []
260
+ if @table_cols && @header_row.count < @table_cols
261
+ @header_row << alignment
262
+ end
263
+ %(#{content} |)
264
+ end
265
+
266
+ def autolink(link, _)
267
+ [
268
+ color('link brackets'),
269
+ '<',
270
+ color('link url'),
271
+ link,
272
+ color('link brackets'),
273
+ '>',
274
+ xc
275
+ ].join('')
276
+ end
277
+
278
+ def codespan(code)
279
+ [
280
+ color('code_span marker'),
281
+ '`',
282
+ color('code_span color'),
283
+ code,
284
+ color('code_span marker'),
285
+ '`',
286
+ xc
287
+ ].join('')
288
+ end
289
+
290
+ def double_emphasis(text)
291
+ "#{color('emphasis bold')}#{text}#{xc}"
292
+ end
293
+
294
+ def emphasis(text)
295
+ "#{color('emphasis italic')}#{text}#{xc}"
296
+ end
297
+
298
+ def triple_emphasis(text)
299
+ "#{color('emphasis bold-italic')}#{text}#{xc}"
300
+ end
301
+
302
+ def highlight(text)
303
+ "#{color('highlight')}#{text}#{xc}"
304
+ end
305
+
306
+ def color_image_tag(link, title, alt_text)
307
+ [
308
+ color('image bang'),
309
+ '!',
310
+ color('image brackets'),
311
+ '[',
312
+ color('image title'),
313
+ alt_text,
314
+ color('image brackets'),
315
+ '](',
316
+ color('image url'),
317
+ link,
318
+ title.nil? ? '' : %( "#{title}"),
319
+ color('image brackets'),
320
+ ')',
321
+ xc
322
+ ].join
323
+ end
324
+
325
+ def image(link, title, alt_text)
326
+ if (exec_available('imgcat') || exec_available('chafa')) && @options[:local_images]
327
+ if exec_available('imgcat')
328
+ @log.info('Using imgcat for image rendering')
329
+ elsif exec_available('chafa')
330
+ @log.info('Using chafa for image rendering')
331
+ end
332
+ img_path = link
333
+ if img_path =~ /^http/ && @options[:remote_images]
334
+ if exec_available('imgcat')
335
+ @log.info('Using imgcat for image rendering')
336
+ begin
337
+ res, s = Open3.capture2(%(curl -sS "#{img_path}" 2> /dev/null | imgcat))
338
+
339
+ if s.success?
340
+ pre = !alt_text.nil? ? " #{c(%i[d blue])}[#{alt_text.strip}]\n" : ''
341
+ post = !title.nil? ? "\n #{c(%i[b blue])}-- #{title} --" : ''
342
+ result = pre + res + post
343
+ end
344
+ rescue StandardError => e
345
+ @log.error(e)
346
+ end
347
+ elsif exec_available('chafa')
348
+ @log.info('Using chafa for image rendering')
349
+ term = '-f sixels'
350
+ term = ENV['TERMINAL_PROGRAM'] =~ /iterm/i ? '-f iterm' : term
351
+ term = ENV['TERMINAL_PROGRAM'] =~ /kitty/i ? '-f kitty' : term
352
+ FileUtils.rm_r '.mdless_tmp', force: true if File.directory?('.mdless_tmp')
353
+ Dir.mkdir('.mdless_tmp')
354
+ Dir.chdir('.mdless_tmp')
355
+ `curl -SsO #{img_path} 2> /dev/null`
356
+ tmp_img = File.basename(img_path)
357
+ img = `chafa #{term} "#{tmp_img}"`
358
+ pre = alt_text ? " #{c(%i[d blue])}[#{alt_text.strip}]\n" : ''
359
+ post = title ? "\n #{c(%i[b blue])}-- #{tail} --" : ''
360
+ result = pre + img + post
361
+ Dir.chdir('..')
362
+ FileUtils.rm_r '.mdless_tmp', force: true
363
+ else
364
+ @log.warn('No viewer for remote images')
365
+ end
366
+ else
367
+ if img_path =~ %r{^[~/]}
368
+ img_path = File.expand_path(img_path)
369
+ elsif @file
370
+ base = File.expand_path(File.dirname(@file))
371
+ img_path = File.join(base, img_path)
372
+ end
373
+ if File.exist?(img_path)
374
+ pre = !alt_text.nil? ? " #{c(%i[d blue])}[#{alt_text.strip}]\n" : ''
375
+ post = !title.nil? ? "\n #{c(%i[b blue])}-- #{title} --" : ''
376
+ if exec_available('imgcat')
377
+ img = `imgcat "#{img_path}"`
378
+ elsif exec_available('chafa')
379
+ term = '-f sixels'
380
+ term = ENV['TERMINAL_PROGRAM'] =~ /iterm/i ? '-f iterm' : term
381
+ term = ENV['TERMINAL_PROGRAM'] =~ /kitty/i ? '-f kitty' : term
382
+ img = `chafa #{term} "#{img_path}"`
383
+ end
384
+ result = pre + img + post
385
+ end
386
+ end
387
+ end
388
+ if result.nil?
389
+ color_image_tag(link, title, alt_text)
390
+ else
391
+ result + xc
392
+ end
393
+ end
394
+
395
+ def linebreak()
396
+ "\n"
397
+ end
398
+
399
+ def link(link, title, content)
400
+ [
401
+ color('link brackets'),
402
+ '[',
403
+ color('link text'),
404
+ content,
405
+ color('link brackets'),
406
+ '](',
407
+ color('link url'),
408
+ link,
409
+ title.nil? ? '' : %( "#{title}"),
410
+ color('link brackets'),
411
+ ')',
412
+ xc
413
+ ].join
414
+ end
415
+
416
+ def color_tags(html)
417
+ html.gsub(%r{(<\S+( .*?)?/?>)}, "#{color('html brackets')}\\1#{xc}")
418
+ end
419
+
420
+ def raw_html(raw_html)
421
+ "#{color('html color')}#{color_tags(raw_html)}#{xc}"
422
+ end
423
+
424
+ def strikethrough(text)
425
+ "#{color('strikethrough')}#{text}#{xc}"
426
+ end
427
+
428
+ def superscript(text)
429
+ "#{color('super')}^#{text}#{xc}"
430
+ end
431
+
432
+ def footnotes(text)
433
+ # [
434
+ # color('footnote note'),
435
+ # text,
436
+ # "\n",
437
+ # xc,
438
+ # ].join('')
439
+ nil
440
+ end
441
+
442
+ def color_footnote_def(idx)
443
+ text = @@footnotes[idx]
444
+ [
445
+ color('footnote brackets'),
446
+ "[",
447
+ color('footnote caret'),
448
+ "^",
449
+ color('footnote title'),
450
+ idx,
451
+ color('footnote brackets'),
452
+ "]:",
453
+ color('footnote note'),
454
+ ' ',
455
+ text.uncolor.strip,
456
+ xc,
457
+ "\n"
458
+ ].join('')
459
+ end
460
+
461
+ def footnote_def(text, idx)
462
+ @@footnotes[idx] = text
463
+ end
464
+
465
+ def footnote_ref(text)
466
+ [
467
+ color('footnote title'),
468
+ "[^#{text}]",
469
+ xc
470
+ ].join('')
471
+ end
472
+
473
+ def insert_footnotes(input)
474
+ input.split(/\n/).map do |line|
475
+ notes = line.to_enum(:scan, /\[\^(?<ref>\d+)\]/).map { Regexp.last_match }
476
+ if notes.count.positive?
477
+ footnotes = notes.map { |n| color_footnote_def(n['ref'].to_i) }.join("\n")
478
+ "#{line}\n\n#{footnotes}\n\n"
479
+ else
480
+ line
481
+ end
482
+ end.join("\n")
483
+ end
484
+
485
+ def fix_lists(input, indent = 0)
486
+ input.gsub(%r{(?<line><<list(?<id>\d+)>>(?<content>.*?)<</list\k<id>>>)}m) do
487
+ m = Regexp.last_match
488
+ fix_lists(m['content'].split(/\n/).map do |l|
489
+ outdent = l.scan(%r{<</list\d+>>}).count
490
+ indent += l.scan(/<<list\d+>>/).count
491
+ indent -= outdent
492
+ "#{' ' * indent}#{l}"
493
+ end.join("\n"), indent)
494
+ end
495
+ end
496
+
497
+ def get_headers(input)
498
+ unless @headers && !@headers.empty?
499
+ @headers = []
500
+ headers = input.scan(/^((?!#!)(\#{1,6})\s*([^#]+?)(?: #+)?\s*|(\S.+)\n([=-]+))$/i)
501
+
502
+ headers.each do |h|
503
+ hlevel = 6
504
+ title = nil
505
+ if h[4] =~ /=+/
506
+ hlevel = 1
507
+ title = h[3]
508
+ elsif h[4] =~ /-+/
509
+ hlevel = 2
510
+ title = h[3]
511
+ else
512
+ hlevel = h[1].length
513
+ title = h[2]
514
+ end
515
+ @headers << [
516
+ '#' * hlevel,
517
+ title,
518
+ h[0]
519
+ ]
520
+ end
521
+ end
522
+
523
+ @headers
524
+ end
525
+
526
+ def preprocess(input)
527
+ in_yaml = false
528
+ if input.split("\n")[0] =~ /(?i-m)^---[ \t]*?(\n|$)/
529
+ @log.info('Found YAML')
530
+ # YAML
531
+ in_yaml = true
532
+ input.sub!(/(?i-m)^---[ \t]*\n([\s\S]*?)\n[-.]{3}[ \t]*\n/) do
533
+ m = Regexp.last_match
534
+ @log.info('Processing YAML Header')
535
+ m[0].split(/\n/).map do |line|
536
+ if line =~ /^[-.]{3}\s*$/
537
+ line = "#{color('metadata marker')}%% #{color('metadata border')}#{line}"
538
+ else
539
+ line.sub!(/^(.*?:)[ \t]+(\S)/, '\1 \2')
540
+ line = "#{color('metadata marker')}%% #{color('metadata color')}#{line}"
541
+ end
542
+ line += ' ' * (@cols - line.uncolor.size) if (@cols - line.uncolor.size).positive?
543
+ line
544
+ end.join("\n") + "#{xc}\n"
545
+ end
546
+ end
547
+
548
+ if !in_yaml && input.gsub(/\n/, ' ') =~ /(?i-m)^\w.+:\s+\S+/
549
+ @log.info('Found MMD Headers')
550
+ input.sub!(/(?i-m)^([\S ]+:[\s\S]*?)+(?=\n\n)/) do |mmd|
551
+ mmd.split(/\n/).map do |line|
552
+ line.sub!(/^(.*?:)[ \t]+(\S)/, '\1 \2')
553
+ line = "#{color('metadata marker')}%% #{color('metadata color')}#{line}"
554
+ line += ' ' * (@cols - line.uncolor.size) if (@cols - line.uncolor.size).positive?
555
+ line
556
+ end.join("\n") + "#{' ' * @cols}#{xc}\n"
557
+ end
558
+
559
+ end
560
+
561
+ ## Replace setex headers with ATX
562
+ input.gsub!(/^([^\n]+)\n={3,}\s*$/m, "# \\1\n")
563
+ input.gsub!(/^([^\n]+?)\n-{3,}\s*$/m, "## \\1\n")
564
+
565
+ @headers = get_headers(input)
566
+
567
+ if @options[:section]
568
+ new_content = []
569
+ @options[:section].each do |sect|
570
+ in_section = false
571
+ top_level = 1
572
+ input.split(/\n/).each do |graf|
573
+ if graf =~ /^(#+) *(.*?)( *#+)?$/
574
+ m = Regexp.last_match
575
+ level = m[1].length
576
+ title = m[2]
577
+ if in_section
578
+ if level >= top_level
579
+ new_content.push(graf)
580
+ else
581
+ in_section = false
582
+ break
583
+ end
584
+ elsif title.downcase == @headers[sect - 1][1].downcase
585
+ in_section = true
586
+ top_level = level + 1
587
+ new_content.push(graf)
588
+ else
589
+ next
590
+ end
591
+ elsif in_section
592
+ new_content.push(graf)
593
+ end
594
+ end
595
+ end
596
+ input = new_content.join("\n")
597
+ end
598
+
599
+ # definition lists
600
+ input.gsub!(/(?mi)(?<=\n|\A)(?<term>(?!<:)[^\n]+)(?<def>(\n+: [^\n]+)+)/) do
601
+ m = Regexp.last_match
602
+ "#{color('dd term')}#{m['term']}#{xc}#{color('dd color')}#{color_dd_def(m['def'])}"
603
+ end
604
+
605
+ input
606
+ end
607
+
608
+ def color_dd_def(input)
609
+ input.gsub(/(?<=\n|\A)(?::)\s+(.*)/) do
610
+ m = Regexp.last_match
611
+ [
612
+ color('dd marker'),
613
+ ": ",
614
+ color('dd color'),
615
+ m[1],
616
+ xc
617
+ ].join
618
+ end
619
+ end
620
+
621
+ def postprocess(input)
622
+ if @options[:inline_footnotes]
623
+ input = insert_footnotes(input)
624
+ else
625
+ footnotes = @@footnotes.map.with_index do |fn, i|
626
+ next if fn.nil?
627
+
628
+ color_footnote_def(i)
629
+ end.join("\n")
630
+ input = "#{input}\n\n#{footnotes}"
631
+ end
632
+ # escaped characters
633
+ input.gsub!(/\\(\S)/, '\1')
634
+ # equations
635
+ input.gsub!(/((\\\\\[|\$\$)(.*?)(\\\\\]|\$\$)|(\\\\\(|\$)(.*?)(\\\\\)|\$))/) do
636
+ m = Regexp.last_match
637
+ if m[2]
638
+ brackets = [m[2], m[4]]
639
+ equat = m[3]
640
+ else
641
+ brackets = [m[5], m[7]]
642
+ equat = m[6]
643
+ end
644
+ "#{c(%i[b black])}#{brackets[0]}#{xc}#{c(%i[b blue])}#{equat}#{c(%i[b black])}#{brackets[1]}" + xc
645
+ end
646
+ # misc html
647
+ input.gsub!(%r{<br */?>}, "\n")
648
+ # lists
649
+ fix_lists(input, 0)
650
+ end
651
+ end
652
+ end
653
+ end
@@ -1,3 +1,3 @@
1
1
  module CLIMarkdown
2
- VERSION = '2.0.1'
2
+ VERSION = '2.0.2'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mdless
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Terpstra
@@ -79,6 +79,7 @@ files:
79
79
  - bin/mdless
80
80
  - lib/mdless.rb
81
81
  - lib/mdless/colors.rb
82
+ - lib/mdless/console.rb
82
83
  - lib/mdless/converter.rb
83
84
  - lib/mdless/hash.rb
84
85
  - lib/mdless/tables.rb