mdless 2.0.17 → 2.0.19
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 +0 -6
- data/lib/mdless/array.rb +11 -0
- data/lib/mdless/colors.rb +13 -5
- data/lib/mdless/console.rb +105 -94
- data/lib/mdless/converter.rb +140 -103
- data/lib/mdless/string.rb +94 -8
- data/lib/mdless/taskpaper.rb +79 -9
- data/lib/mdless/version.rb +1 -1
- data/lib/mdless.rb +46 -0
- metadata +17 -2
data/lib/mdless/converter.rb
CHANGED
@@ -4,33 +4,33 @@ require 'yaml'
|
|
4
4
|
module CLIMarkdown
|
5
5
|
class Converter
|
6
6
|
include Colors
|
7
|
-
include Theme
|
8
|
-
|
9
|
-
attr_reader :helpers, :log
|
10
7
|
|
11
8
|
def version
|
12
9
|
"#{CLIMarkdown::EXECUTABLE_NAME} #{CLIMarkdown::VERSION}"
|
13
10
|
end
|
14
11
|
|
12
|
+
def default(option, default)
|
13
|
+
MDLess.options[option] = default if MDLess.options[option].nil?
|
14
|
+
end
|
15
|
+
|
15
16
|
def initialize(args)
|
16
|
-
|
17
|
-
@log.level = Logger::WARN
|
17
|
+
MDLess.log.level = Logger::WARN
|
18
18
|
|
19
|
-
|
19
|
+
MDLess.options = {}
|
20
20
|
config = File.expand_path('~/.config/mdless/config.yml')
|
21
|
-
|
21
|
+
MDLess.options = YAML.load(IO.read(config)) if File.exist?(config)
|
22
22
|
|
23
23
|
optparse = OptionParser.new do |opts|
|
24
24
|
opts.banner = "#{version} by Brett Terpstra\n\n> Usage: #{CLIMarkdown::EXECUTABLE_NAME} [options] [path]\n\n"
|
25
25
|
|
26
|
-
|
26
|
+
default(:color, true)
|
27
27
|
opts.on('-c', '--[no-]color', 'Colorize output (default on)') do |c|
|
28
|
-
|
28
|
+
MDLess.options[:color] = c
|
29
29
|
end
|
30
30
|
|
31
31
|
opts.on('-d', '--debug LEVEL', 'Level of debug messages to output (1-4, 4 to see all messages)') do |level|
|
32
32
|
if level.to_i.positive? && level.to_i < 5
|
33
|
-
|
33
|
+
MDLess.log.level = 5 - level.to_i
|
34
34
|
else
|
35
35
|
puts 'Error: Debug level out of range (1-4)'
|
36
36
|
Process.exit 1
|
@@ -42,64 +42,71 @@ module CLIMarkdown
|
|
42
42
|
exit
|
43
43
|
end
|
44
44
|
|
45
|
-
|
46
|
-
|
45
|
+
default(:local_images, false)
|
46
|
+
default(:remote_images, false)
|
47
47
|
opts.on('-i', '--images=TYPE',
|
48
48
|
'Include [local|remote (both)|none] images in output (requires chafa or imgcat, default none).') do |type|
|
49
49
|
if exec_available('imgcat') || exec_available('chafa')
|
50
50
|
case type
|
51
51
|
when /^(r|b|a)/i
|
52
|
-
|
53
|
-
|
52
|
+
MDLess.options[:local_images] = true
|
53
|
+
MDLess.options[:remote_images] = true
|
54
54
|
when /^l/i
|
55
|
-
|
55
|
+
MDLess.options[:local_images] = true
|
56
56
|
when /^n/
|
57
|
-
|
58
|
-
|
57
|
+
MDLess.options[:local_images] = false
|
58
|
+
MDLess.options[:remote_images] = false
|
59
59
|
end
|
60
60
|
else
|
61
|
-
|
61
|
+
MDLess.log.warn('images turned on but imgcat/chafa not found')
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
65
|
opts.on('-I', '--all-images', 'Include local and remote images in output (requires imgcat or chafa)') do
|
66
66
|
if exec_available('imgcat') || exec_available('chafa') # && ENV['TERM_PROGRAM'] == 'iTerm.app'
|
67
|
-
|
68
|
-
|
67
|
+
MDLess.options[:local_images] = true
|
68
|
+
MDLess.options[:remote_images] = true
|
69
69
|
else
|
70
|
-
|
70
|
+
MDLess.log.warn('images turned on but imgcat/chafa not found')
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
-
|
74
|
+
default(:list, false)
|
75
75
|
opts.on('-l', '--list', 'List headers in document and exit') do
|
76
|
-
|
76
|
+
MDLess.options[:list] = true
|
77
77
|
end
|
78
78
|
|
79
|
-
|
79
|
+
default(:pager, true)
|
80
80
|
opts.on('-p', '--[no-]pager', 'Formatted output to pager (default on)') do |p|
|
81
|
-
|
81
|
+
MDLess.options[:pager] = p
|
82
82
|
end
|
83
83
|
|
84
|
-
|
84
|
+
default(:pager, true)
|
85
85
|
opts.on('-P', 'Disable pager (same as --no-pager)') do
|
86
|
-
|
86
|
+
MDLess.options[:pager] = false
|
87
87
|
end
|
88
88
|
|
89
|
-
|
89
|
+
default(:section, nil)
|
90
90
|
opts.on('-s', '--section=NUMBER[,NUMBER]',
|
91
91
|
'Output only a headline-based section of the input (numeric from --list)') do |section|
|
92
|
-
|
92
|
+
sections = section.split(/ *, */).map(&:strip)
|
93
|
+
MDLess.options[:section] = sections.map do |sect|
|
94
|
+
if sect =~ /^\d+$/
|
95
|
+
sect.to_i
|
96
|
+
else
|
97
|
+
sect
|
98
|
+
end
|
99
|
+
end
|
93
100
|
end
|
94
101
|
|
95
|
-
|
102
|
+
default(:theme, 'default')
|
96
103
|
opts.on('-t', '--theme=THEME_NAME', 'Specify an alternate color theme to load') do |theme|
|
97
|
-
|
104
|
+
MDLess.options[:theme] = theme
|
98
105
|
end
|
99
106
|
|
100
|
-
|
107
|
+
default(:at_tags, false)
|
101
108
|
opts.on('-@', '--at_tags', 'Highlight @tags and values in the document') do
|
102
|
-
|
109
|
+
MDLess.options[:at_tags] = true
|
103
110
|
end
|
104
111
|
|
105
112
|
opts.on('-v', '--version', 'Display version number') do
|
@@ -107,32 +114,39 @@ module CLIMarkdown
|
|
107
114
|
exit
|
108
115
|
end
|
109
116
|
|
110
|
-
|
117
|
+
default(:width, TTY::Screen.cols)
|
111
118
|
opts.on('-w', '--width=COLUMNS', 'Column width to format for (default: terminal width)') do |columns|
|
112
|
-
|
119
|
+
MDLess.options[:width] = columns.to_i
|
120
|
+
end
|
121
|
+
cols = TTY::Screen.cols
|
122
|
+
MDLess.options[:width] = cols if MDLess.options[:width] > cols
|
123
|
+
|
124
|
+
default(:autolink, true)
|
125
|
+
opts.on('--[no-]autolink', 'Convert bare URLs and emails to <links>') do |p|
|
126
|
+
MDLess.options[:autolink] = p
|
113
127
|
end
|
114
128
|
|
115
|
-
|
129
|
+
default(:inline_footnotes, false)
|
116
130
|
opts.on('--[no-]inline_footnotes',
|
117
131
|
'Display footnotes immediately after the paragraph that references them') do |p|
|
118
|
-
|
132
|
+
MDLess.options[:inline_footnotes] = p
|
119
133
|
end
|
120
134
|
|
121
|
-
|
135
|
+
default(:intra_emphasis, true)
|
122
136
|
opts.on('--[no-]intra-emphasis', 'Parse emphasis inside of words (e.g. Mark_down_)') do |opt|
|
123
|
-
|
137
|
+
MDLess.options[:intra_emphasis] = opt
|
124
138
|
end
|
125
139
|
|
126
|
-
|
140
|
+
default(:lax_spacing, true)
|
127
141
|
opts.on('--[no-]lax-spacing', 'Allow lax spacing') do |opt|
|
128
|
-
|
142
|
+
MDLess.options[:lax_spacing] = opt
|
129
143
|
end
|
130
144
|
|
131
|
-
|
145
|
+
default(:links, :inline)
|
132
146
|
opts.on('--links=FORMAT',
|
133
147
|
'Link style ([inline, reference, paragraph], default inline,
|
134
148
|
"paragraph" will position reference links after each paragraph)') do |fmt|
|
135
|
-
|
149
|
+
MDLess.options[:links] = case fmt
|
136
150
|
when /^:?r/i
|
137
151
|
:reference
|
138
152
|
when /^:?p/i
|
@@ -142,13 +156,13 @@ module CLIMarkdown
|
|
142
156
|
end
|
143
157
|
end
|
144
158
|
|
145
|
-
|
159
|
+
default(:syntax_higlight, false)
|
146
160
|
opts.on('--[no-]syntax', 'Syntax highlight code blocks') do |p|
|
147
|
-
|
161
|
+
MDLess.options[:syntax_higlight] = p
|
148
162
|
end
|
149
163
|
|
150
|
-
|
151
|
-
case
|
164
|
+
MDLess.options[:taskpaper] = if MDLess.options[:taskpaper]
|
165
|
+
case MDLess.options[:taskpaper].to_s
|
152
166
|
when /^[ty1]/
|
153
167
|
true
|
154
168
|
when /^a/
|
@@ -160,7 +174,7 @@ module CLIMarkdown
|
|
160
174
|
false
|
161
175
|
end
|
162
176
|
opts.on('--taskpaper=OPTION', 'Highlight TaskPaper format (true|false|auto)') do |tp|
|
163
|
-
|
177
|
+
MDLess.options[:taskpaper] = case tp
|
164
178
|
when /^[ty1]/
|
165
179
|
true
|
166
180
|
when /^a/
|
@@ -170,14 +184,14 @@ module CLIMarkdown
|
|
170
184
|
end
|
171
185
|
end
|
172
186
|
|
173
|
-
|
187
|
+
default(:update_config, false)
|
174
188
|
opts.on('--update_config', 'Update the configuration file with new keys and current command line options') do
|
175
|
-
|
189
|
+
MDLess.options[:update_config] = true
|
176
190
|
end
|
177
191
|
|
178
|
-
|
192
|
+
default(:wiki_links, false)
|
179
193
|
opts.on('--[no-]wiki-links', 'Highlight [[wiki links]]') do |opt|
|
180
|
-
|
194
|
+
MDLess.options[:wiki_links] = opt
|
181
195
|
end
|
182
196
|
end
|
183
197
|
|
@@ -188,20 +202,21 @@ module CLIMarkdown
|
|
188
202
|
exit 1
|
189
203
|
end
|
190
204
|
|
191
|
-
if !File.exist?(config) ||
|
205
|
+
if !File.exist?(config) || MDLess.options[:update_config]
|
192
206
|
FileUtils.mkdir_p(File.dirname(config))
|
193
207
|
File.open(config, 'w') do |f|
|
194
|
-
opts =
|
208
|
+
opts = MDLess.options.dup
|
195
209
|
opts.delete(:list)
|
196
210
|
opts.delete(:section)
|
197
211
|
opts.delete(:update_config)
|
212
|
+
opts = opts.keys.map(&:to_s).sort.map { |k| [k.to_sym, opts[k.to_sym]] }.to_h
|
198
213
|
f.puts YAML.dump(opts)
|
199
214
|
warn "Config file saved to #{config}"
|
200
215
|
end
|
201
216
|
end
|
202
217
|
|
203
|
-
|
204
|
-
|
218
|
+
MDLess.cols = MDLess.options[:width] - 2
|
219
|
+
|
205
220
|
@output = ''
|
206
221
|
@headers = []
|
207
222
|
@setheaders = []
|
@@ -211,19 +226,15 @@ module CLIMarkdown
|
|
211
226
|
@footnotes = {}
|
212
227
|
|
213
228
|
renderer = Redcarpet::Render::Console.new
|
214
|
-
renderer.theme = @theme
|
215
|
-
renderer.cols = @cols
|
216
|
-
renderer.log = @log
|
217
|
-
renderer.options = @options
|
218
229
|
|
219
230
|
markdown = Redcarpet::Markdown.new(renderer,
|
220
|
-
no_intra_emphasis:
|
221
|
-
autolink:
|
231
|
+
no_intra_emphasis: !MDLess.options[:intra_emphasis],
|
232
|
+
autolink: MDLess.options[:autolink],
|
222
233
|
fenced_code_blocks: true,
|
223
234
|
footnotes: true,
|
224
235
|
hard_wrap: false,
|
225
236
|
highlight: true,
|
226
|
-
lax_spacing:
|
237
|
+
lax_spacing: MDLess.options[:lax_spacing],
|
227
238
|
quote: false,
|
228
239
|
space_after_headers: false,
|
229
240
|
strikethrough: true,
|
@@ -234,9 +245,9 @@ module CLIMarkdown
|
|
234
245
|
if !args.empty?
|
235
246
|
files = args.delete_if { |f| !File.exist?(f) }
|
236
247
|
files.each do |file|
|
237
|
-
|
238
|
-
|
239
|
-
|
248
|
+
MDLess.log.info(%(Processing "#{file}"))
|
249
|
+
MDLess.file = file
|
250
|
+
|
240
251
|
begin
|
241
252
|
input = IO.read(file).force_encoding('utf-8')
|
242
253
|
rescue StandardError
|
@@ -247,25 +258,27 @@ module CLIMarkdown
|
|
247
258
|
input.scrub!
|
248
259
|
input.gsub!(/\r?\n/, "\n")
|
249
260
|
|
250
|
-
if
|
251
|
-
|
261
|
+
if MDLess.options[:taskpaper] == :auto
|
262
|
+
MDLess.options[:taskpaper] = if CLIMarkdown::TaskPaper.is_taskpaper?(input)
|
263
|
+
MDLess.log.info('TaskPaper detected')
|
264
|
+
true
|
265
|
+
else
|
266
|
+
false
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
if MDLess.options[:list]
|
271
|
+
if MDLess.options[:taskpaper]
|
272
|
+
puts CLIMarkdown::TaskPaper.list_projects(input)
|
273
|
+
else
|
274
|
+
puts list_headers(input)
|
275
|
+
end
|
252
276
|
Process.exit 0
|
253
277
|
else
|
254
|
-
if
|
255
|
-
|
256
|
-
|
257
|
-
|
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)
|
278
|
+
if MDLess.options[:taskpaper]
|
279
|
+
input = input.color_meta(MDLess.cols)
|
280
|
+
input = CLIMarkdown::TaskPaper.highlight(input)
|
281
|
+
@output = input.highlight_tags
|
269
282
|
else
|
270
283
|
@output = markdown.render(input)
|
271
284
|
end
|
@@ -273,14 +286,34 @@ module CLIMarkdown
|
|
273
286
|
end
|
274
287
|
printout
|
275
288
|
elsif !$stdin.isatty
|
276
|
-
|
289
|
+
MDLess.file = nil
|
277
290
|
input = $stdin.read.scrub
|
278
291
|
input.gsub!(/\r?\n/, "\n")
|
279
|
-
|
280
|
-
|
292
|
+
|
293
|
+
if MDLess.options[:taskpaper] == :auto
|
294
|
+
MDLess.options[:taskpaper] = if CLIMarkdown::TaskPaper.is_taskpaper?(input)
|
295
|
+
MDLess.log.info('TaskPaper detected')
|
296
|
+
true
|
297
|
+
else
|
298
|
+
false
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
if MDLess.options[:list]
|
303
|
+
if MDLess.options[:taskpaper]
|
304
|
+
puts CLIMarkdown::TaskPaper.list_projects(input)
|
305
|
+
else
|
306
|
+
puts list_headers(input)
|
307
|
+
end
|
281
308
|
Process.exit 0
|
282
309
|
else
|
283
|
-
|
310
|
+
if MDLess.options[:taskpaper]
|
311
|
+
input = input.color_meta(MDLess.cols)
|
312
|
+
input = CLIMarkdown::TaskPaper.highlight(input)
|
313
|
+
@output = input.highlight_tags
|
314
|
+
else
|
315
|
+
@output = markdown.render(input)
|
316
|
+
end
|
284
317
|
end
|
285
318
|
printout
|
286
319
|
else
|
@@ -292,17 +325,17 @@ module CLIMarkdown
|
|
292
325
|
def color(key)
|
293
326
|
val = nil
|
294
327
|
keys = key.split(/[ ,>]/)
|
295
|
-
if
|
296
|
-
val =
|
328
|
+
if MDLess.theme.key?(keys[0])
|
329
|
+
val = MDLess.theme[keys.shift]
|
297
330
|
else
|
298
|
-
|
331
|
+
MDLess.log.error("Invalid theme key: #{key}") unless keys[0] =~ /^text/
|
299
332
|
return c([:reset])
|
300
333
|
end
|
301
334
|
keys.each do |k|
|
302
335
|
if val.key?(k)
|
303
336
|
val = val[k]
|
304
337
|
else
|
305
|
-
|
338
|
+
MDLess.log.error("Invalid theme key: #{k}")
|
306
339
|
return c([:reset])
|
307
340
|
end
|
308
341
|
end
|
@@ -394,8 +427,8 @@ module CLIMarkdown
|
|
394
427
|
|
395
428
|
def clean_markers(input)
|
396
429
|
input.gsub!(/^(\e\[[\d;]+m)?[%~] ?/, '\1')
|
397
|
-
input.gsub!(/^(\e\[[\d;]+m)*>(\e\[[\d;]+m)?( +)/, ' \3\1\2')
|
398
|
-
input.gsub!(/^(\e\[[\d;]+m)*>(\e\[[\d;]+m)?/, '\1\2')
|
430
|
+
# input.gsub!(/^(\e\[[\d;]+m)*>(\e\[[\d;]+m)?( +)/, ' \3\1\2')
|
431
|
+
# input.gsub!(/^(\e\[[\d;]+m)*>(\e\[[\d;]+m)?/, '\1\2')
|
399
432
|
input.gsub!(/(\e\[[\d;]+m)?@@@(\e\[[\d;]+m)?$/, '')
|
400
433
|
input
|
401
434
|
end
|
@@ -424,7 +457,7 @@ module CLIMarkdown
|
|
424
457
|
block.split(/\n/).map do |l|
|
425
458
|
new_code_line = l.gsub(/\t/, ' ')
|
426
459
|
orig_length = new_code_line.size + 8 + eol.size
|
427
|
-
pad_count = [
|
460
|
+
pad_count = [MDLess.cols - orig_length, 0].max
|
428
461
|
|
429
462
|
[
|
430
463
|
new_code_line,
|
@@ -448,11 +481,11 @@ module CLIMarkdown
|
|
448
481
|
IO.select [input]
|
449
482
|
|
450
483
|
pager = which_pager
|
451
|
-
|
484
|
+
MDLess.log.info("Using #{pager} as pager")
|
452
485
|
begin
|
453
486
|
exec(pager.join(' '))
|
454
487
|
rescue SystemCallError => e
|
455
|
-
|
488
|
+
MDLess.log.error(e)
|
456
489
|
exit 1
|
457
490
|
end
|
458
491
|
end
|
@@ -470,21 +503,25 @@ module CLIMarkdown
|
|
470
503
|
end
|
471
504
|
|
472
505
|
def printout
|
473
|
-
|
474
|
-
|
475
|
-
|
506
|
+
if MDLess.options[:taskpaper]
|
507
|
+
out = @output
|
508
|
+
else
|
509
|
+
out = @output.rstrip.split(/\n/).map do |p|
|
510
|
+
p.wrap(MDLess.cols, color('text'))
|
511
|
+
end.join("\n")
|
512
|
+
end
|
476
513
|
|
477
514
|
unless out.size&.positive?
|
478
|
-
|
515
|
+
MDLess.log.warn 'No results'
|
479
516
|
Process.exit
|
480
517
|
end
|
481
518
|
|
482
519
|
out = clean_markers(out)
|
483
520
|
out = "#{out.gsub(/\n{2,}/m, "\n\n")}#{xc}"
|
484
521
|
|
485
|
-
out.uncolor! unless
|
522
|
+
out.uncolor! unless MDLess.options[:color]
|
486
523
|
|
487
|
-
if
|
524
|
+
if MDLess.options[:pager]
|
488
525
|
page(out)
|
489
526
|
else
|
490
527
|
$stdout.print out.rstrip
|
@@ -507,7 +544,7 @@ module CLIMarkdown
|
|
507
544
|
if f.strip =~ /[ |]/
|
508
545
|
f
|
509
546
|
elsif f == 'most'
|
510
|
-
|
547
|
+
MDLess.log.warn('most not allowed as pager')
|
511
548
|
false
|
512
549
|
else
|
513
550
|
system "which #{f}", out: File::NULL, err: File::NULL
|
data/lib/mdless/string.rb
CHANGED
@@ -4,20 +4,28 @@
|
|
4
4
|
class ::String
|
5
5
|
include CLIMarkdown::Colors
|
6
6
|
|
7
|
-
def
|
7
|
+
def clean_empty_lines
|
8
|
+
gsub(/^[ \t]+$/, '')
|
9
|
+
end
|
10
|
+
|
11
|
+
def clean_empty_lines!
|
12
|
+
replace clean_empty_lines
|
13
|
+
end
|
14
|
+
|
15
|
+
def color(key)
|
8
16
|
val = nil
|
9
17
|
keys = key.split(/[ ,>]/)
|
10
|
-
if theme.key?(keys[0])
|
11
|
-
val = theme[keys.shift]
|
18
|
+
if MDLess.theme.key?(keys[0])
|
19
|
+
val = MDLess.theme[keys.shift]
|
12
20
|
else
|
13
|
-
log.error("Invalid theme key: #{key}") unless keys[0] =~ /^text/
|
21
|
+
MDLess.log.error("Invalid theme key: #{key}") unless keys[0] =~ /^text/
|
14
22
|
return c([:reset])
|
15
23
|
end
|
16
24
|
keys.each do |k|
|
17
25
|
if val.key?(k)
|
18
26
|
val = val[k]
|
19
27
|
else
|
20
|
-
log.error("Invalid theme key: #{k}")
|
28
|
+
MDLess.log.error("Invalid theme key: #{k}")
|
21
29
|
return c([:reset])
|
22
30
|
end
|
23
31
|
end
|
@@ -30,9 +38,75 @@ class ::String
|
|
30
38
|
end
|
31
39
|
end
|
32
40
|
|
33
|
-
def
|
34
|
-
|
35
|
-
|
41
|
+
def to_rx(distance: 2, string_start: false)
|
42
|
+
chars = downcase.split(//)
|
43
|
+
pre = string_start ? '^' : '^.*?'
|
44
|
+
/#{pre}#{chars.join(".{,#{distance}}")}.*?$/
|
45
|
+
end
|
46
|
+
|
47
|
+
def clean_header_ids!
|
48
|
+
replace clean_header_ids
|
49
|
+
end
|
50
|
+
|
51
|
+
def clean_header_ids
|
52
|
+
gsub(/ +\[.*?\] *$/, '').gsub(/ *\{#.*?\} *$/, '').strip
|
53
|
+
end
|
54
|
+
|
55
|
+
def color_meta(cols)
|
56
|
+
@cols = cols
|
57
|
+
input = dup
|
58
|
+
input.clean_empty_lines!
|
59
|
+
|
60
|
+
in_yaml = false
|
61
|
+
first_line = input.split("\n").first
|
62
|
+
if first_line =~ /(?i-m)^---[ \t]*?$/
|
63
|
+
MDLess.log.info('Found YAML')
|
64
|
+
# YAML
|
65
|
+
in_yaml = true
|
66
|
+
input.sub!(/(?i-m)^---[ \t]*\n([\s\S]*?)\n[-.]{3}[ \t]*\n/m) do
|
67
|
+
m = Regexp.last_match
|
68
|
+
MDLess.log.info('Processing YAML Header')
|
69
|
+
lines = m[0].split(/\n/)
|
70
|
+
longest = lines.inject { |memo, word| memo.length > word.length ? memo : word }.length
|
71
|
+
longest = longest < @cols ? longest + 1 : @cols
|
72
|
+
lines.map do |line|
|
73
|
+
if line =~ /^[-.]{3}\s*$/
|
74
|
+
line = "#{color('metadata marker')}#{'%' * longest}"
|
75
|
+
else
|
76
|
+
line.sub!(/^(.*?:)[ \t]+(\S)/, '\1 \2')
|
77
|
+
line = "#{color('metadata color')}#{line}"
|
78
|
+
end
|
79
|
+
|
80
|
+
line += "\u00A0" * (longest - line.uncolor.strip.length) + xc
|
81
|
+
line
|
82
|
+
end.join("\n") + "#{xc}\n"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
if !in_yaml && first_line =~ /(?i-m)^[\w ]+:\s+\S+/
|
87
|
+
MDLess.log.info('Found MMD Headers')
|
88
|
+
input.sub!(/(?i-m)^([\S ]+:[\s\S]*?)+(?=\n\n)/) do |mmd|
|
89
|
+
lines = mmd.split(/\n/)
|
90
|
+
return mmd if lines.count > 20
|
91
|
+
|
92
|
+
longest = lines.inject { |memo, word| memo.length > word.length ? memo : word }.length
|
93
|
+
longest = longest < @cols ? longest + 1 : @cols
|
94
|
+
lines.map do |line|
|
95
|
+
line.sub!(/^(.*?:)[ \t]+(\S)/, '\1 \2')
|
96
|
+
line = "#{color('metadata color')}#{line}"
|
97
|
+
line += "\u00A0" * (longest - line.uncolor.strip.length)
|
98
|
+
line + xc
|
99
|
+
end.join("\n") + "#{"\u00A0" * longest}#{xc}\n"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
input
|
104
|
+
end
|
105
|
+
|
106
|
+
def highlight_tags
|
107
|
+
log = MDLess.log
|
108
|
+
tag_color = color('at_tags tag')
|
109
|
+
value_color = color('at_tags value')
|
36
110
|
gsub(/(?<pre>\s|m)(?<tag>@[^ \].?!,("']+)(?:(?<lparen>\()(?<value>.*?)(?<rparen>\)))?/) do
|
37
111
|
m = Regexp.last_match
|
38
112
|
last_color = m.pre_match.last_color_code
|
@@ -58,4 +132,16 @@ class ::String
|
|
58
132
|
def scrub!
|
59
133
|
replace scrub
|
60
134
|
end
|
135
|
+
|
136
|
+
def valid_pygments_theme?
|
137
|
+
return false unless TTY::Which.exist?('pygmentize')
|
138
|
+
|
139
|
+
MDLess.pygments_styles.include?(self)
|
140
|
+
end
|
141
|
+
|
142
|
+
def valid_lexer?
|
143
|
+
return false unless TTY::Which.exist?('pygmentize')
|
144
|
+
|
145
|
+
MDLess.pygments_lexers.include?(self.downcase)
|
146
|
+
end
|
61
147
|
end
|