mdless 2.0.15 → 2.0.17
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +8 -2
- data/lib/mdless/console.rb +110 -35
- data/lib/mdless/converter.rb +82 -51
- data/lib/mdless/string.rb +49 -0
- data/lib/mdless/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9d80ed856b198db9752c7ac96f964b2b2e05f7706288aef8fbf901417952a967
|
4
|
+
data.tar.gz: ad820a3d6a885fc2f50decf0b6f52444d267ca84f9b3bbf5f3945cce8413df15
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 60dcb01d030a0115bb49616dd507c53a2b605dc8f0d28a194092150489c36adfb33450b7ba3c87f54b4048bc6b5114cfce2b914c240e129a2cbf36f4d76ec420
|
7
|
+
data.tar.gz: b67938b0f651c324845d107074f04a647d8b46c60ee09386be627a1ad2d5ff50b08f31ef9a12984a6a209aeaa7d632cb47313c425c01a47f49b6b72b7a1f6022
|
data/README.md
CHANGED
@@ -60,8 +60,6 @@ The pager used is determined by system configuration in this order of preference
|
|
60
60
|
-h, --help Display this screen
|
61
61
|
-i, --images=TYPE Include [local|remote (both)|none] images in output (requires chafa or imgcat, default none).
|
62
62
|
-I, --all-images Include local and remote images in output (requires imgcat or chafa)
|
63
|
-
--syntax Syntax highlight code blocks
|
64
|
-
--links=FORMAT Link style ([inline, reference, paragraph], default inline, "paragraph" will position reference links after each paragraph)
|
65
63
|
-l, --list List headers in document and exit
|
66
64
|
-p, --[no-]pager Formatted output to pager (default on)
|
67
65
|
-P Disable pager (same as --no-pager)
|
@@ -71,6 +69,14 @@ The pager used is determined by system configuration in this order of preference
|
|
71
69
|
-v, --version Display version number
|
72
70
|
-w, --width=COLUMNS Column width to format for (default: terminal width)
|
73
71
|
--[no-]inline_footnotes Display footnotes immediately after the paragraph that references them
|
72
|
+
--[no-]intra-emphasis Parse emphasis inside of words (e.g. Mark_down_)
|
73
|
+
--[no-]lax-spacing Allow lax spacing
|
74
|
+
--links=FORMAT Link style ([inline, reference, paragraph], default inline,
|
75
|
+
"paragraph" will position reference links after each paragraph)
|
76
|
+
--[no-]syntax Syntax highlight code blocks
|
77
|
+
--taskpaper=OPTION Highlight TaskPaper format (true|false|auto)
|
78
|
+
--update_config Update the configuration file with new keys and current command line options
|
79
|
+
--[no-]wiki-links Highlight [[wiki links]]
|
74
80
|
|
75
81
|
## Configuration
|
76
82
|
|
data/lib/mdless/console.rb
CHANGED
@@ -105,14 +105,14 @@ module Redcarpet
|
|
105
105
|
[
|
106
106
|
xc,
|
107
107
|
color('code_block border'),
|
108
|
-
'-' *
|
108
|
+
'-' * 20,
|
109
109
|
xc,
|
110
110
|
"\n",
|
111
111
|
color('code_block color'),
|
112
112
|
hilite.chomp,
|
113
113
|
"\n",
|
114
114
|
color('code_block border'),
|
115
|
-
'-' *
|
115
|
+
'-' * 20,
|
116
116
|
xc
|
117
117
|
].join
|
118
118
|
end
|
@@ -204,33 +204,6 @@ module Redcarpet
|
|
204
204
|
"\n\n#{color('hr color')}#{'_' * @cols}#{xc}\n\n"
|
205
205
|
end
|
206
206
|
|
207
|
-
def list(contents, list_type)
|
208
|
-
@@listitemid = 0
|
209
|
-
@@listid += 1
|
210
|
-
"<<list#{@@listid}>>#{contents}<</list#{@@listid}>>"
|
211
|
-
end
|
212
|
-
|
213
|
-
def list_item(text, list_type)
|
214
|
-
case list_type
|
215
|
-
when :unordered
|
216
|
-
[
|
217
|
-
"#{color('list bullet')}• ",
|
218
|
-
color('list color'),
|
219
|
-
text,
|
220
|
-
xc
|
221
|
-
].join('')
|
222
|
-
when :ordered
|
223
|
-
@@listitemid += 1
|
224
|
-
[
|
225
|
-
color('list number'),
|
226
|
-
"#{@@listitemid}. ",
|
227
|
-
color('list color'),
|
228
|
-
text,
|
229
|
-
xc
|
230
|
-
].join('')
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
207
|
def paragraph(text)
|
235
208
|
"#{xc}#{text}#{xc}#{x}\n\n"
|
236
209
|
end
|
@@ -510,16 +483,118 @@ module Redcarpet
|
|
510
483
|
end.join("\n")
|
511
484
|
end
|
512
485
|
|
513
|
-
def
|
514
|
-
|
486
|
+
def list(contents, list_type)
|
487
|
+
@@listid += 1
|
488
|
+
"<<list#{@@listid}-#{list_type}>>#{contents}<</list#{@@listid}>>"
|
489
|
+
end
|
490
|
+
|
491
|
+
def list_item(text, list_type)
|
492
|
+
@@listitemid += 1
|
493
|
+
case list_type
|
494
|
+
when :unordered
|
495
|
+
"<<listitem#{@@listitemid}-#{list_type}>>#{text.strip}<</listitem#{@@listitemid}>>\n"
|
496
|
+
when :ordered
|
497
|
+
"<<listitem#{@@listitemid}-#{list_type}>>#{text.strip}<</listitem#{@@listitemid}>>\n"
|
498
|
+
end
|
499
|
+
end
|
500
|
+
|
501
|
+
def indent_lines(input, spaces)
|
502
|
+
return nil if input.nil?
|
503
|
+
|
504
|
+
indent = spaces.scan(/ /).count
|
505
|
+
|
506
|
+
lines = input.split(/\n/)
|
507
|
+
line1 = lines.shift
|
508
|
+
body = lines.map { |l| "#{' ' * (indent + 1)}#{l}" }.join("\n")
|
509
|
+
"#{line1}\n#{body}"
|
510
|
+
end
|
511
|
+
|
512
|
+
def color_list_item(indent, content, type, counter)
|
513
|
+
case type
|
514
|
+
when :unordered
|
515
|
+
[
|
516
|
+
indent,
|
517
|
+
color('list bullet'),
|
518
|
+
"* ",
|
519
|
+
color('list color'),
|
520
|
+
indent_lines(content, indent).strip,
|
521
|
+
xc
|
522
|
+
].join
|
523
|
+
when :ordered
|
524
|
+
[
|
525
|
+
indent,
|
526
|
+
color('list number'),
|
527
|
+
"#{counter}. ",
|
528
|
+
color('list color'),
|
529
|
+
indent_lines(content, indent).strip,
|
530
|
+
xc
|
531
|
+
].join
|
532
|
+
end
|
533
|
+
end
|
534
|
+
|
535
|
+
def fix_lists(input)
|
536
|
+
input = nest_lists(input)
|
537
|
+
input = fix_list_spacing(input)
|
538
|
+
fix_list_items(input)
|
539
|
+
end
|
540
|
+
|
541
|
+
def fix_list_spacing(input)
|
542
|
+
input.gsub(/( *\n)+( *)<<listitem/, "\n\\2<<listitem").gsub(/\n{2,}/, "\n\n")
|
543
|
+
end
|
544
|
+
|
545
|
+
def nest_lists(input, indent = 0)
|
546
|
+
input.gsub!(%r{<<list(?<id>\d+)-(?<type>.*?)>>(?<content>.*?)<</list\k<id>>>}m) do
|
515
547
|
m = Regexp.last_match
|
516
|
-
|
548
|
+
lines = m['content'].split(/\n/)
|
549
|
+
list = nest_lists(lines.map do |l|
|
517
550
|
outdent = l.scan(%r{<</list\d+>>}).count
|
518
|
-
indent += l.scan(/<<list\d
|
551
|
+
indent += l.scan(/<<list\d+-.*?>>/).count
|
519
552
|
indent -= outdent
|
520
553
|
"#{' ' * indent}#{l}"
|
521
554
|
end.join("\n"), indent)
|
522
|
-
|
555
|
+
next if list.nil?
|
556
|
+
|
557
|
+
"<<main#{m['id']}>>#{list}<</main#{m['id']}>>"
|
558
|
+
end
|
559
|
+
|
560
|
+
input.gsub(/^(?<indent> +)<<main(?<id>\d+)>>(?<content>.*?)<<\/main\k<id>>>/m) do
|
561
|
+
m = Regexp.last_match
|
562
|
+
"#{m['indent']}#{m['content']}"
|
563
|
+
end
|
564
|
+
end
|
565
|
+
|
566
|
+
def normalize_indentation(line)
|
567
|
+
line.gsub(/^([ \t]+)/) do |pre|
|
568
|
+
pre.gsub(/\t/, ' ')
|
569
|
+
end
|
570
|
+
end
|
571
|
+
|
572
|
+
def fix_items(content, last_indent = 0, levels = [0])
|
573
|
+
content.gsub(%r{^(?<indent> *)<<listitem(?<id>\d+)-(?<type>(?:un)?ordered)>>(?<content>.*?)<</listitem\k<id>>>}m) do
|
574
|
+
m = Regexp.last_match
|
575
|
+
indent = m['indent'].length
|
576
|
+
if indent == last_indent
|
577
|
+
levels[indent] ||= 0
|
578
|
+
levels[indent] += 1
|
579
|
+
elsif indent < last_indent
|
580
|
+
levels[last_indent] = 0
|
581
|
+
levels[indent] += 1
|
582
|
+
last_indent = indent
|
583
|
+
else
|
584
|
+
levels[indent] = 1
|
585
|
+
last_indent = indent
|
586
|
+
end
|
587
|
+
|
588
|
+
content = m['content'] =~/<<listitem/ ? fix_items(m['content'], indent, levels) : m['content']
|
589
|
+
color_list_item(' ' * indent, content, m['type'].to_sym, levels[indent])
|
590
|
+
end
|
591
|
+
end
|
592
|
+
|
593
|
+
def fix_list_items(input)
|
594
|
+
input.gsub(%r{<<main(?<id>\d+)>>(?<content>.*?)<</main\k<id>>>}m) do
|
595
|
+
m = Regexp.last_match
|
596
|
+
fix_items(m['content'])
|
597
|
+
end
|
523
598
|
end
|
524
599
|
|
525
600
|
def get_headers(input)
|
@@ -897,7 +972,7 @@ module Redcarpet
|
|
897
972
|
# format links
|
898
973
|
input = reference_links(input) if @options[:links] == :reference || @options[:links] == :paragraph
|
899
974
|
# lists
|
900
|
-
input = fix_lists(input
|
975
|
+
input = fix_lists(input)
|
901
976
|
input = render_images(input) if @options[:local_images]
|
902
977
|
input = highlight_tags(input) if @options[:at_tags] || @options[:taskpaper]
|
903
978
|
fix_colors(input)
|
data/lib/mdless/converter.rb
CHANGED
@@ -61,6 +61,7 @@ module CLIMarkdown
|
|
61
61
|
@log.warn('images turned on but imgcat/chafa not found')
|
62
62
|
end
|
63
63
|
end
|
64
|
+
|
64
65
|
opts.on('-I', '--all-images', 'Include local and remote images in output (requires imgcat or chafa)') do
|
65
66
|
if exec_available('imgcat') || exec_available('chafa') # && ENV['TERM_PROGRAM'] == 'iTerm.app'
|
66
67
|
@options[:local_images] = true
|
@@ -70,51 +71,6 @@ module CLIMarkdown
|
|
70
71
|
end
|
71
72
|
end
|
72
73
|
|
73
|
-
@options[:syntax_higlight] ||= false
|
74
|
-
opts.on('--syntax', 'Syntax highlight code blocks') do |p|
|
75
|
-
@options[:syntax_higlight] = p
|
76
|
-
end
|
77
|
-
|
78
|
-
@options[:update_config] ||= false
|
79
|
-
opts.on('--update_config', 'Update the configuration file with new keys and current command line options') do
|
80
|
-
@options[:update_config] = true
|
81
|
-
end
|
82
|
-
|
83
|
-
@options[:taskpaper] ||= false
|
84
|
-
opts.on('--taskpaper=OPTION', 'Highlight TaskPaper format (true|false|auto)') do |tp|
|
85
|
-
@options[:taskpaper] = case tp
|
86
|
-
when /^[ty1]/
|
87
|
-
true
|
88
|
-
when /^a/
|
89
|
-
:auto
|
90
|
-
else
|
91
|
-
false
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
@options[:links] ||= :inline
|
96
|
-
opts.on('--links=FORMAT',
|
97
|
-
'Link style ([inline, reference, paragraph], default inline, "paragraph" will position reference links after each paragraph)') do |fmt|
|
98
|
-
@options[:links] = case fmt
|
99
|
-
when /^:?r/i
|
100
|
-
:reference
|
101
|
-
when /^:?p/i
|
102
|
-
:paragraph
|
103
|
-
else
|
104
|
-
:inline
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
@options[:lax_spacing] ||= true
|
109
|
-
opts.on('--[no-]lax-spacing', 'Allow lax spacing') do |opt|
|
110
|
-
@options[:lax_spacing] = opt
|
111
|
-
end
|
112
|
-
|
113
|
-
@options[:intra_emphasis] ||= true
|
114
|
-
opts.on('--[no-]intra-emphasis', 'Parse emphasis inside of words (e.g. Mark_down_)') do |opt|
|
115
|
-
@options[:intra_emphasis] = opt
|
116
|
-
end
|
117
|
-
|
118
74
|
@options[:list] ||= false
|
119
75
|
opts.on('-l', '--list', 'List headers in document and exit') do
|
120
76
|
@options[:list] = true
|
@@ -146,11 +102,6 @@ module CLIMarkdown
|
|
146
102
|
@options[:at_tags] = true
|
147
103
|
end
|
148
104
|
|
149
|
-
@options[:wiki_links] ||= false
|
150
|
-
opts.on('--[no-]wiki-links', 'Highlight [[wiki links]]') do |opt|
|
151
|
-
@options[:wiki_links] = opt
|
152
|
-
end
|
153
|
-
|
154
105
|
opts.on('-v', '--version', 'Display version number') do
|
155
106
|
puts version
|
156
107
|
exit
|
@@ -166,6 +117,68 @@ module CLIMarkdown
|
|
166
117
|
'Display footnotes immediately after the paragraph that references them') do |p|
|
167
118
|
@options[:inline_footnotes] = p
|
168
119
|
end
|
120
|
+
|
121
|
+
@options[:intra_emphasis] ||= true
|
122
|
+
opts.on('--[no-]intra-emphasis', 'Parse emphasis inside of words (e.g. Mark_down_)') do |opt|
|
123
|
+
@options[:intra_emphasis] = opt
|
124
|
+
end
|
125
|
+
|
126
|
+
@options[:lax_spacing] ||= true
|
127
|
+
opts.on('--[no-]lax-spacing', 'Allow lax spacing') do |opt|
|
128
|
+
@options[:lax_spacing] = opt
|
129
|
+
end
|
130
|
+
|
131
|
+
@options[:links] ||= :inline
|
132
|
+
opts.on('--links=FORMAT',
|
133
|
+
'Link style ([inline, reference, paragraph], default inline,
|
134
|
+
"paragraph" will position reference links after each paragraph)') do |fmt|
|
135
|
+
@options[:links] = case fmt
|
136
|
+
when /^:?r/i
|
137
|
+
:reference
|
138
|
+
when /^:?p/i
|
139
|
+
:paragraph
|
140
|
+
else
|
141
|
+
:inline
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
@options[:syntax_higlight] ||= false
|
146
|
+
opts.on('--[no-]syntax', 'Syntax highlight code blocks') do |p|
|
147
|
+
@options[:syntax_higlight] = p
|
148
|
+
end
|
149
|
+
|
150
|
+
@options[:taskpaper] = if @options[:taskpaper]
|
151
|
+
case @options[:taskpaper].to_s
|
152
|
+
when /^[ty1]/
|
153
|
+
true
|
154
|
+
when /^a/
|
155
|
+
:auto
|
156
|
+
else
|
157
|
+
false
|
158
|
+
end
|
159
|
+
else
|
160
|
+
false
|
161
|
+
end
|
162
|
+
opts.on('--taskpaper=OPTION', 'Highlight TaskPaper format (true|false|auto)') do |tp|
|
163
|
+
@options[:taskpaper] = case tp
|
164
|
+
when /^[ty1]/
|
165
|
+
true
|
166
|
+
when /^a/
|
167
|
+
:auto
|
168
|
+
else
|
169
|
+
false
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
@options[:update_config] ||= false
|
174
|
+
opts.on('--update_config', 'Update the configuration file with new keys and current command line options') do
|
175
|
+
@options[:update_config] = true
|
176
|
+
end
|
177
|
+
|
178
|
+
@options[:wiki_links] ||= false
|
179
|
+
opts.on('--[no-]wiki-links', 'Highlight [[wiki links]]') do |opt|
|
180
|
+
@options[:wiki_links] = opt
|
181
|
+
end
|
169
182
|
end
|
170
183
|
|
171
184
|
begin
|
@@ -233,11 +246,29 @@ module CLIMarkdown
|
|
233
246
|
|
234
247
|
input.scrub!
|
235
248
|
input.gsub!(/\r?\n/, "\n")
|
249
|
+
|
236
250
|
if @options[:list]
|
237
251
|
puts list_headers(input)
|
238
252
|
Process.exit 0
|
239
253
|
else
|
240
|
-
@
|
254
|
+
if @options[:taskpaper] == :auto
|
255
|
+
@options[:taskpaper] = if file =~ /\.taskpaper/
|
256
|
+
@log.info('TaskPaper extension detected')
|
257
|
+
true
|
258
|
+
elsif CLIMarkdown::TaskPaper.is_taskpaper?(input)
|
259
|
+
@log.info('TaskPaper document detected')
|
260
|
+
true
|
261
|
+
else
|
262
|
+
false
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
if @options[:taskpaper]
|
267
|
+
input = CLIMarkdown::TaskPaper.highlight(input, @theme)
|
268
|
+
@output = input.highlight_tags(@theme, @log)
|
269
|
+
else
|
270
|
+
@output = markdown.render(input)
|
271
|
+
end
|
241
272
|
end
|
242
273
|
end
|
243
274
|
printout
|
data/lib/mdless/string.rb
CHANGED
@@ -2,6 +2,55 @@
|
|
2
2
|
|
3
3
|
# String helpers
|
4
4
|
class ::String
|
5
|
+
include CLIMarkdown::Colors
|
6
|
+
|
7
|
+
def color(key, theme, log)
|
8
|
+
val = nil
|
9
|
+
keys = key.split(/[ ,>]/)
|
10
|
+
if theme.key?(keys[0])
|
11
|
+
val = theme[keys.shift]
|
12
|
+
else
|
13
|
+
log.error("Invalid theme key: #{key}") unless keys[0] =~ /^text/
|
14
|
+
return c([:reset])
|
15
|
+
end
|
16
|
+
keys.each do |k|
|
17
|
+
if val.key?(k)
|
18
|
+
val = val[k]
|
19
|
+
else
|
20
|
+
log.error("Invalid theme key: #{k}")
|
21
|
+
return c([:reset])
|
22
|
+
end
|
23
|
+
end
|
24
|
+
if val.is_a? String
|
25
|
+
val = "x #{val}"
|
26
|
+
res = val.split(/ /).map(&:to_sym)
|
27
|
+
c(res)
|
28
|
+
else
|
29
|
+
c([:reset])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def highlight_tags(theme, log)
|
34
|
+
tag_color = color('at_tags tag', theme, log)
|
35
|
+
value_color = color('at_tags value', theme, log)
|
36
|
+
gsub(/(?<pre>\s|m)(?<tag>@[^ \].?!,("']+)(?:(?<lparen>\()(?<value>.*?)(?<rparen>\)))?/) do
|
37
|
+
m = Regexp.last_match
|
38
|
+
last_color = m.pre_match.last_color_code
|
39
|
+
[
|
40
|
+
m['pre'],
|
41
|
+
tag_color,
|
42
|
+
m['tag'],
|
43
|
+
m['lparen'],
|
44
|
+
value_color,
|
45
|
+
m['value'],
|
46
|
+
tag_color,
|
47
|
+
m['rparen'],
|
48
|
+
xc,
|
49
|
+
last_color
|
50
|
+
].join
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
5
54
|
def scrub
|
6
55
|
encode('utf-16', invalid: :replace).encode('utf-8')
|
7
56
|
end
|
data/lib/mdless/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mdless
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.17
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brett Terpstra
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-11-
|
11
|
+
date: 2023-11-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redcarpet
|