mdless 2.0.15 → 2.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- 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
|