mdless 0.0.14 → 0.0.15

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: 0a4f667f7783166c9dd1d60ae77698058d9c240d014cd911ac27c4cce2b616b7
4
- data.tar.gz: f1db62b7e655e58a2c391fa3092e2497f69ba36b31b327686ed7e79846fdd3a0
3
+ metadata.gz: 350da3408205b06f5ef3b792190c11f0a1f2a22139f40472da1922486f2b1358
4
+ data.tar.gz: aad6fe5044525feab00af45cd757c1f5d5b1f3478a429db681a1bf86d9ea863e
5
5
  SHA512:
6
- metadata.gz: 3ee079617708ae07d18265be581c983631c01ef19187079e137d2244493b09fef7ce6048c0104fb2fc4123a8fce46abadc301d46d391180e1d2f8c2fd6443bfd
7
- data.tar.gz: 1710ad0309375ef8728521c1d883a7f2b13c7bef2cf5ac5325f497de27b690d36b208f706ec8a8f9fec178a994f0abef698619636815c5d5425b949c6722e708
6
+ metadata.gz: 1a5a65f8caf5a8c62b3c0e2ba7a712df1d6d1ce1948e90e76c0ee599833f9b4844683c3d6d86874cb477b9ca307ec7f5b75339e26c7696117ac564ddd99b5cef
7
+ data.tar.gz: 9038fbdc4b9e161b6531af8ad59bbc9707f3eab158818e9b0b15b9434fd388f716d9e11602d8bfc15a8cbdbabe14efe462081a8d90ff41f3543106d924d07dc1
data/README.md CHANGED
@@ -1,7 +1,6 @@
1
1
 
2
2
  # mdless
3
3
 
4
-
5
4
  `mdless` is a utility that provides a formatted and highlighted view of Markdown files in Terminal.
6
5
 
7
6
  I often use iTerm2 in visor mode, so `qlmanage -p` is annoying. I still wanted a way to view Markdown files quickly and without cruft.
@@ -16,9 +15,12 @@ I often use iTerm2 in visor mode, so `qlmanage -p` is annoying. I still wanted a
16
15
  - Normalize spacing and link formatting
17
16
  - Display footnotes after each paragraph
18
17
  - Inline image display (local, optionally remote) if using iTerm2 2.9+
19
- - Syntax highlighting when `pygmentize` is available
18
+ - Syntax highlighting when [Pygments](http://pygments.org/) is installed
19
+ - Only fenced code with a language defined (e.g. `\`\`\`python`) will be highlighted
20
+ - Languages can also be determined by hashbang in the code block
20
21
  - List headlines in document
21
- - Display single section of the document based on headlines
22
+ - Display single section of the document based on headlines
23
+ - Customizable colors
22
24
 
23
25
  ## Installation
24
26
 
@@ -40,7 +42,7 @@ The pager used is determined by system configuration in this order of preference
40
42
 
41
43
  ### Options
42
44
 
43
- -s, --section=TITLE Output only a headline-based section of
45
+ -s, --section=NUMBER Output only a headline-based section of
44
46
  the input (numeric based on --list output)
45
47
  -w, --width=COLUMNS Column width to format for (default terminal width)
46
48
  -p, --[no-]pager Formatted output to pager (default on)
@@ -54,5 +56,51 @@ The pager used is determined by system configuration in this order of preference
54
56
  -h, --help Display this screen
55
57
  -v, --version Display version number
56
58
 
59
+ ## Customization
60
+
61
+ On first run a default theme file will be placed in `~/.config/mdless/mdless.theme`. You can edit this file to modify the colors mdless uses when highlighting your files.
62
+
63
+ Colors are limited to basic ANSI codes, with support for bold, underline, italics (if available for the terminal/font), dark and bright, and foreground and background colors.
64
+
65
+ Customizeable settings are stored in [YAML](https://yaml.org) format. A chunk of the settings file looks like this:
66
+
67
+ ```yaml
68
+ h1:
69
+ color: b intense_black on_white
70
+ pad: d black on_white
71
+ pad_char: "="
72
+ ```
73
+
74
+ Font and color settings are set using a string of color names and modifiers. A typical string looks like `b red on_white`, which would give you a bold red font on a white background. In the YAML settings file there's no need for quotes, just put the string following the colon for the setting.
75
+
76
+ Some extra (non-color) settings are available for certain keys, e.g. `pad_char` to define the right padding character used on level 1 and 2 headlines. Note that you can change the [Pygments](http://pygments.org/) theme used for syntax highlighting with the code_block.pygments_theme setting. For a list of available styles (assuming you have Pygments installed), use `pygmentize -L styles`.
77
+
78
+ *Note:* the ANSI escape codes are reset every time the color changes, so, for example, if you have a key that defines underlines for the url in a link, the underline will automatically be removed when it gets to a bracket. This also means that if you define a background color, you'll need to define it again on all the keys that it should affect.
79
+
80
+ Base colors:
81
+
82
+ - black
83
+ - red
84
+ - green
85
+ - yellow
86
+ - blue
87
+ - magenta
88
+ - cyan
89
+ - white
90
+
91
+ Emphasis:
92
+
93
+ - b (bold)
94
+ - d (dark)
95
+ - i (italic)
96
+ - u (underline)
97
+ - r (reverse, negative)
98
+
99
+ To modify the emphasis, use 'b' (bold), 'i' (italic), 'u' (underline), e.g. `u yellow` for underlined yellow. These can be combined, e.g. `b u red`.
100
+
101
+ Use 'r' to reverse foreground and background colors. `r white on_black` would display as `black on_white`. 'r' alone will reverse the current color set for a line.
102
+
103
+ To set a background color, use `on_[color]` with one of the 8 colors. This can be used with foreground colors in the same setting, e.g. `white on_black`.
57
104
 
105
+ Use 'd' (dark) to indicate the darker version of a foreground color. On macOS (and possibly other systems) you can use the brighter version of a color by prefixing with "intense", e.g. `intense_red` or `on_intense_black`.
58
106
 
data/lib/mdless/colors.rb CHANGED
@@ -1,12 +1,66 @@
1
1
  module CLIMarkdown
2
2
  module Colors
3
3
 
4
+ COLORS = {
5
+ :reset => 0, # synonym for :clear
6
+ :x => 0,
7
+ :bold => 1,
8
+ :b => 1,
9
+ :dark => 2,
10
+ :d => 2,
11
+ :italic => 3, # not widely implemented
12
+ :i => 3,
13
+ :underline => 4,
14
+ :underscore => 4, # synonym for :underline
15
+ :u => 4,
16
+ :blink => 5,
17
+ :rapid_blink => 6, # not widely implemented
18
+ :negative => 7, # no reverse because of String#reverse
19
+ :r => 7,
20
+ :concealed => 8,
21
+ :strikethrough => 9, # not widely implemented
22
+ :black => 30,
23
+ :red => 31,
24
+ :green => 32,
25
+ :yellow => 33,
26
+ :blue => 34,
27
+ :magenta => 35,
28
+ :cyan => 36,
29
+ :white => 37,
30
+ :on_black => 40,
31
+ :on_red => 41,
32
+ :on_green => 42,
33
+ :on_yellow => 43,
34
+ :on_blue => 44,
35
+ :on_magenta => 45,
36
+ :on_cyan => 46,
37
+ :on_white => 47,
38
+ :intense_black => 90, # High intensity, aixterm (works in OS X)
39
+ :intense_red => 91,
40
+ :intense_green => 92,
41
+ :intense_yellow => 93,
42
+ :intense_blue => 94,
43
+ :intense_magenta => 95,
44
+ :intense_cyan => 96,
45
+ :intense_white => 97,
46
+ :on_intense_black => 100, # High intensity background, aixterm (works in OS X)
47
+ :on_intense_red => 101,
48
+ :on_intense_green => 102,
49
+ :on_intense_yellow => 103,
50
+ :on_intense_blue => 104,
51
+ :on_intense_magenta => 105,
52
+ :on_intense_cyan => 106,
53
+ :on_intense_white => 107
54
+ }
55
+
4
56
  def uncolor
5
57
  self.gsub(/\e\[[\d;]+m/,'')
6
58
  end
7
59
 
8
- def blackout
9
- self.gsub(/(^|$)/,"\e[40m").gsub(/3([89])m/,"40;3\\1m")
60
+ def blackout(bgcolor)
61
+ key = bgcolor.to_sym
62
+ bg = COLORS.key?(key) ? COLORS[key] : 40
63
+ self.gsub(/(^|$)/,"\e[#{bg}m").gsub(/3([89])m/,"#{bg};3\\1m")
10
64
  end
11
65
 
12
66
  def uncolor!
@@ -54,63 +108,13 @@ module CLIMarkdown
54
108
 
55
109
  def c(args)
56
110
 
57
- colors = {
58
- :reset => 0, # synonym for :clear
59
- :x => 0,
60
- :bold => 1,
61
- :b => 1,
62
- :dark => 2,
63
- :d => 2,
64
- :italic => 3, # not widely implemented
65
- :i => 3,
66
- :underline => 4,
67
- :underscore => 4, # synonym for :underline
68
- :u => 4,
69
- :blink => 5,
70
- :rapid_blink => 6, # not widely implemented
71
- :negative => 7, # no reverse because of String#reverse
72
- :r => 7,
73
- :concealed => 8,
74
- :strikethrough => 9, # not widely implemented
75
- :black => 30,
76
- :red => 31,
77
- :green => 32,
78
- :yellow => 33,
79
- :blue => 34,
80
- :magenta => 35,
81
- :cyan => 36,
82
- :white => 37,
83
- :on_black => 40,
84
- :on_red => 41,
85
- :on_green => 42,
86
- :on_yellow => 43,
87
- :on_blue => 44,
88
- :on_magenta => 45,
89
- :on_cyan => 46,
90
- :on_white => 47,
91
- :intense_black => 90, # High intensity, aixterm (works in OS X)
92
- :intense_red => 91,
93
- :intense_green => 92,
94
- :intense_yellow => 93,
95
- :intense_blue => 94,
96
- :intense_magenta => 95,
97
- :intense_cyan => 96,
98
- :intense_white => 97,
99
- :on_intense_black => 100, # High intensity background, aixterm (works in OS X)
100
- :on_intense_red => 101,
101
- :on_intense_green => 102,
102
- :on_intense_yellow => 103,
103
- :on_intense_blue => 104,
104
- :on_intense_magenta => 105,
105
- :on_intense_cyan => 106,
106
- :on_intense_white => 107
107
- }
111
+
108
112
 
109
113
  out = []
110
114
 
111
115
  args.each {|arg|
112
- if colors.key? arg
113
- out << colors[arg]
116
+ if COLORS.key? arg
117
+ out << COLORS[arg]
114
118
  end
115
119
  }
116
120
 
@@ -1,3 +1,13 @@
1
+ require 'fileutils'
2
+ require 'yaml'
3
+
4
+ class ::Hash
5
+ def deep_merge(second)
6
+ merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : Array === v1 && Array === v2 ? v1 | v2 : [:undefined, nil, :nil].include?(v2) ? v1 : v2 }
7
+ self.merge(second.to_h, &merger)
8
+ end
9
+ end
10
+
1
11
  module CLIMarkdown
2
12
  class Converter
3
13
  include Colors
@@ -12,12 +22,119 @@ module CLIMarkdown
12
22
  @log = Logger.new(STDERR)
13
23
  @log.level = Logger::ERROR
14
24
 
25
+ config_dir = File.expand_path('~/.config/mdless')
26
+ theme_file = File.join(config_dir,'mdless.theme')
27
+
28
+ theme_defaults = {
29
+ 'metadata' => {
30
+ 'border' => 'd blue on_black',
31
+ 'marker' => 'd black on_black',
32
+ 'color' => 'd white on_black'
33
+ },
34
+ 'h1' => {
35
+ 'color' => 'b intense_black on_white',
36
+ 'pad' => 'd black on_white',
37
+ 'pad_char' => '='
38
+ },
39
+ 'h2' => {
40
+ 'color' => 'b white on_intense_black',
41
+ 'pad' => 'd white on_intense_black',
42
+ 'pad_char' => '-'
43
+ },
44
+ 'h3' => {
45
+ 'color' => 'u b yellow'
46
+ },
47
+ 'h4' => {
48
+ 'color' => 'u yellow'
49
+ },
50
+ 'h5' => {
51
+ 'color' => 'b white'
52
+ },
53
+ 'h6' => {
54
+ 'color' => 'b white'
55
+ },
56
+ 'link' => {
57
+ 'brackets' => 'b black',
58
+ 'text' => 'u b blue',
59
+ 'url' => 'cyan'
60
+ },
61
+ 'image' => {
62
+ 'bang' => 'red',
63
+ 'brackets' => 'b black',
64
+ 'title' => 'cyan',
65
+ 'url' => 'u yellow'
66
+ },
67
+ 'list' => {
68
+ 'bullet' => 'b intense_red',
69
+ 'number' => 'b intense_blue',
70
+ 'color' => 'intense_white'
71
+ },
72
+ 'footnote' => {
73
+ 'brackets' => 'b black on_black',
74
+ 'caret' => 'b yellow on_black',
75
+ 'title' => 'x yellow on_black',
76
+ 'note' => 'u white on_black'
77
+ },
78
+ 'code_span' => {
79
+ 'marker' => 'b white',
80
+ 'color' => 'b black on_intense_blue'
81
+ },
82
+ 'code_block' => {
83
+ 'marker' => 'intense_black',
84
+ 'bg' => 'on_black',
85
+ 'color' => 'white on_black',
86
+ 'border' => 'blue',
87
+ 'title' => 'magenta',
88
+ 'eol' => 'intense_black on_black',
89
+ 'pygments_theme' => 'monokai'
90
+ },
91
+ 'dd' => {
92
+ 'marker' => 'd red',
93
+ 'color' => 'b white'
94
+ },
95
+ 'hr' => {
96
+ 'color' => 'd white'
97
+ },
98
+ 'table' => {
99
+ 'border' => 'd black',
100
+ 'header' => 'yellow',
101
+ 'divider' => 'b black',
102
+ 'color' => 'white'
103
+ },
104
+ 'html' => {
105
+ 'brackets' => 'd yellow on_black',
106
+ 'color' => 'yellow on_black'
107
+ }
108
+ }
109
+
110
+ unless File.directory?(config_dir)
111
+ @log.info("Creating config directory at #{config_dir}")
112
+ FileUtils.mkdir_p(config_dir)
113
+ end
114
+
115
+ unless File.exists?(theme_file)
116
+ @log.info("Writing fresh theme file to #{theme_file}")
117
+ File.open(theme_file,'w') {|f|
118
+ f.puts @theme.to_yaml
119
+ }
120
+ @theme = theme_defaults
121
+ else
122
+ new_theme = YAML.load(IO.read(theme_file))
123
+ begin
124
+ @theme = theme_defaults.deep_merge(new_theme)
125
+ rescue
126
+ @log.warn('Error merging user theme')
127
+ @theme = theme_defaults
128
+ end
129
+ end
130
+
131
+
15
132
  @options = {}
16
133
  optparse = OptionParser.new do |opts|
17
134
  opts.banner = "#{version} by Brett Terpstra\n\n> Usage: #{CLIMarkdown::EXECUTABLE_NAME} [options] [path]\n\n"
18
135
 
19
136
  @options[:section] = nil
20
- opts.on( '-s', '--section=TITLE', 'Output only a headline-based section of the input (numeric from -l)' ) do |section|
137
+ opts.on( '-s', '--section=NUMBER', 'Output only a headline-based section of the input (numeric from --list)' ) do |section|
21
138
  @options[:section] = section.to_i
22
139
  end
23
140
 
@@ -41,7 +158,7 @@ module CLIMarkdown
41
158
  end
42
159
 
43
160
  @options[:links] = :inline
44
- opts.on( '--links=FORMAT', 'Link style ([inline, reference], default inline)' ) do |format|
161
+ opts.on( '--links=FORMAT', 'Link style ([inline, reference], default inline) [NOT CURRENTLY IMPLEMENTED]' ) do |format|
45
162
  if format =~ /^r/i
46
163
  @options[:links] = :reference
47
164
  end
@@ -95,7 +212,8 @@ module CLIMarkdown
95
212
 
96
213
  @cols = @options[:width]
97
214
  @output = ''
98
- @header_arr = []
215
+ @headers = []
216
+ @setheaders = []
99
217
 
100
218
  input = ''
101
219
  @ref_links = {}
@@ -139,9 +257,58 @@ module CLIMarkdown
139
257
  end
140
258
  end
141
259
 
260
+ def color(key)
261
+ val = nil
262
+ keys = key.split(/[ ,>]/)
263
+ if @theme.key?(keys[0])
264
+ val = @theme[keys.shift]
265
+ else
266
+ @log.error("Invalid theme key: #{key}")
267
+ return c([:reset])
268
+ end
269
+ keys.each {|k|
270
+ if val.key?(k)
271
+ val = val[k]
272
+ else
273
+ @log.error("Invalid theme key: #{k}")
274
+ return c([:reset])
275
+ end
276
+ }
277
+ if val.kind_of? String
278
+ val = "x #{val}"
279
+ res = val.split(/ /).map {|k|
280
+ k.to_sym
281
+ }
282
+ c(res)
283
+ else
284
+ c([:reset])
285
+ end
286
+ end
287
+
142
288
  def get_headers(input)
143
289
  unless @headers && @headers.length > 0
144
- @headers = input.scan(/^(#+)\s*(.*?)( #+)?\s*$/)
290
+ @headers = []
291
+ headers = input.scan(/^((?!#!)(\#{1,6})\s*([^#]+?)(?: #+)?\s*|(.*?)\n([=-]+))$/i)
292
+
293
+ headers.each {|h|
294
+ hlevel = 6
295
+ title = nil
296
+ if h[4] =~ /=+/
297
+ hlevel = 1
298
+ title = h[3]
299
+ elsif h[4] =~ /-+/
300
+ hlevel = 2
301
+ title = h[3]
302
+ else
303
+ hlevel = h[1].length
304
+ title = h[2]
305
+ end
306
+ @headers << [
307
+ '#'*hlevel,
308
+ title,
309
+ h[0]
310
+ ]
311
+ }
145
312
  end
146
313
  @headers
147
314
  end
@@ -192,9 +359,9 @@ module CLIMarkdown
192
359
  end
193
360
 
194
361
  def highest_header(input)
195
- headers = input.scan(/^(#+)/)
362
+ @headers = get_headers(input)
196
363
  top = 6
197
- headers.each {|h|
364
+ @headers.each {|h|
198
365
  top = h[0].length if h[0].length < top
199
366
  }
200
367
  top
@@ -205,12 +372,12 @@ module CLIMarkdown
205
372
  input.split(/\n/).map{|line|
206
373
  if first
207
374
  first = false
208
- line.gsub!(/\|/, "#{c(%i[d black])}|#{c(%i[x yellow])}")
375
+ line.gsub!(/\|/, "#{color('table border')}|#{color('table header')}")
209
376
  elsif line.strip =~ /^[|:\- ]+$/
210
- line.gsub!(/^(.*)$/, "#{c(%i[d black])}\\1#{c(%i[x white])}")
211
- line.gsub!(/([:\-]+)/,"#{c(%i[b black])}\\1#{c(%i[d black])}")
377
+ line.gsub!(/^(.*)$/, "#{color('table border')}\\1#{color('table color')}")
378
+ line.gsub!(/([:\-]+)/,"#{color('table divider')}\\1#{color('table border')}")
212
379
  else
213
- line.gsub!(/\|/, "#{c(%i[d black])}|#{c(%i[x white])}")
380
+ line.gsub!(/\|/, "#{color('table border')}|#{color('table color')}")
214
381
  end
215
382
  }.join("\n")
216
383
  end
@@ -289,22 +456,39 @@ module CLIMarkdown
289
456
  end
290
457
 
291
458
  def color_link(line, text, url)
292
- out = c(%i[b black])
293
- out += "[#{c(%i[u blue])}#{text}"
294
- out += c(%i[b black])
295
- out += "]("
296
- out += c(%i[x cyan])
297
- out += url
298
- out += c(%i[b black])
299
- out += ")"
300
- out += find_color(line)
301
- out
459
+ [
460
+ color('link brackets'),
461
+ "[",
462
+ color('link text'),
463
+ text,
464
+ color('link brackets'),
465
+ "](",
466
+ color('link url'),
467
+ url,
468
+ color('link brackets'),
469
+ ")",
470
+ find_color(line)
471
+ ].join
302
472
  end
303
473
 
304
474
  def color_image(line, text, url)
305
- text.gsub!(/\e\[0m/,c(%i[x cyan]))
306
-
307
- "#{c(%i[x red])}!#{c(%i[b black])}[#{c(%i[x cyan])}#{text}#{c(%i[b black])}](#{c(%i[u yellow])}#{url}#{c(%i[b black])})" + find_color(line)
475
+ text.gsub!(/\e\[0m/,color('image title'))
476
+
477
+ [
478
+ color('image bang'),
479
+ "!",
480
+ color('image brackets'),
481
+ "[",
482
+ color('image title'),
483
+ text,
484
+ color('image brackets'),
485
+ "](",
486
+ color('image url'),
487
+ url,
488
+ color('image brackets'),
489
+ ")",
490
+ find_color(line)
491
+ ].join
308
492
  end
309
493
 
310
494
  def valid_lexer?(language)
@@ -333,19 +517,19 @@ module CLIMarkdown
333
517
  if exec_available('pygmentize') && language && valid_lexer?(language)
334
518
  lexer = "-l #{language}"
335
519
  begin
336
- hilite, s = Open3.capture2(%Q{pygmentize -f terminal256 -O style=monokai #{lexer} 2> /dev/null}, :stdin_data=>codeBlock)
520
+ hilite, s = Open3.capture2(%Q{pygmentize -f terminal256 -O style=#{@theme['code_block']['pygments_theme']} #{lexer} 2> /dev/null}, :stdin_data=>codeBlock)
337
521
  if s.success?
338
522
 
339
523
  hilite = xc + hilite.split(/\n/).map{|l|
340
524
  new_code_line = l.gsub(/\t/, ' ')
341
525
  new_code_line.sub!(/^#{" "*first_indent}/,'')
342
526
  [
343
- c(%i[x intense_black]),
527
+ color('code_block marker'),
344
528
  "> ",
345
529
  " "*first_indent,
346
- "#{c([:on_black])}#{l}"
530
+ "#{color('code_block bg')}#{l}"
347
531
  ].join
348
- }.join("\n").blackout + "#{xc}\n"
532
+ }.join("\n").blackout(@theme['code_block']['bg']) + "#{xc}\n"
349
533
  end
350
534
  rescue => e
351
535
  @log.error(e)
@@ -355,19 +539,38 @@ module CLIMarkdown
355
539
  hilite = codeBlock.split(/\n/).map do |line|
356
540
  new_code_line = line.gsub(/\t/, ' ')
357
541
  new_code_line.sub!(/^#{" "*first_indent}/,'')
358
- new_code_line.gsub!(/ /, "#{c(%i[x white on_black])} ")
542
+ new_code_line.gsub!(/ /, "#{color('code_block color')} ")
359
543
  [
360
- c(%i[x intense_black]),
544
+ color('code_block marker'),
361
545
  "> ",
362
546
  " "*first_indent,
363
- c(%i[x white on_black]),
547
+ color('code_block color'),
364
548
  new_code_line,
365
549
  xc
366
550
  ].join
367
551
  end.join("\n") + "\n"
368
552
  end
369
553
 
370
- "#{xc}\n#{" "*first_indent}#{c(%i[x blue]) + '--[ '}#{c(%i[x magenta])}#{leader}#{c(%i[x blue]) + ' ]' + '-'*(@cols-new_indent-leader.size+1) + xc}\n#{hilite}#{" "*(new_indent)}#{c(%i[x blue]) + '-'*(@cols-new_indent) + xc}\n"
554
+ [
555
+ xc,
556
+ "\n",
557
+ " "*first_indent,
558
+ color('code_block border'),
559
+ '--[ ',
560
+ color('code_block title'),
561
+ leader,
562
+ color('code_block border'),
563
+ ' ]',
564
+ '-'*(@cols-new_indent-leader.size+1),
565
+ xc,
566
+ "\n",
567
+ hilite,
568
+ " "*(new_indent),
569
+ color('code_block border'),
570
+ '-'*(@cols-new_indent),
571
+ xc,
572
+ "\n"
573
+ ].join
371
574
  end
372
575
 
373
576
  def convert_markdown(input)
@@ -380,14 +583,13 @@ module CLIMarkdown
380
583
  in_yaml = true
381
584
  input.sub!(/(?i-m)^---[ \t]*\n([\s\S]*?)\n[\-.]{3}[ \t]*\n/) do |yaml|
382
585
  m = Regexp.last_match
383
-
384
586
  @log.info("Processing YAML Header")
385
587
  m[0].split(/\n/).map {|line|
386
588
  if line =~ /^[\-.]{3}\s*$/
387
- line = c(%i[d black on_black]) + "% " + c(%i[d black on_black]) + line
589
+ line = color('metadata marker') + "%% " + color('metadata border') + line
388
590
  else
389
591
  line.sub!(/^(.*?:)[ \t]+(\S)/, '\1 \2')
390
- line = c(%i[d black on_black]) + "% " + c(%i[d white]) + line
592
+ line = color('metadata marker') + "%% " + color('metadata color') + line
391
593
  end
392
594
  if @cols - line.uncolor.size > 0
393
595
  line += " "*(@cols-line.uncolor.size)
@@ -399,10 +601,9 @@ module CLIMarkdown
399
601
  if !in_yaml && input.gsub(/\n/,' ') =~ /(?i-m)^\w.+:\s+\S+ /
400
602
  @log.info("Found MMD Headers")
401
603
  input.sub!(/(?i-m)^([\S ]+:[\s\S]*?)+(?=\n\n)/) do |mmd|
402
- puts mmd
403
604
  mmd.split(/\n/).map {|line|
404
605
  line.sub!(/^(.*?:)[ \t]+(\S)/, '\1 \2')
405
- line = c(%i[d black on_black]) + "% " + c(%i[d white on_black]) + line
606
+ line = color('metadata marker') + "%% " + color('metadata color') + line
406
607
  if @cols - line.uncolor.size > 0
407
608
  line += " "*(@cols - line.uncolor.size)
408
609
  end
@@ -420,6 +621,7 @@ module CLIMarkdown
420
621
  end
421
622
 
422
623
  # Gather footnotes (non-inline)
624
+ # TODO: Need to implement option to output links as references
423
625
  input.gsub!(/^ {,3}(?<!\*)(?:\e\[[\d;]+m)*\[(?:\e\[[\d;]+m)*\^(?:\e\[[\d;]+m)*\b(.+)\b(?:\e\[[\d;]+m)*\]: *(.*?)\n/) do |m|
424
626
  match = Regexp.last_match
425
627
  @footnotes[match[1].uncolor] = match[2].uncolor
@@ -483,7 +685,7 @@ module CLIMarkdown
483
685
  code_block = m[3]
484
686
  leader = shebang[1] ? shebang[1] : 'code'
485
687
  else
486
- code_block = pad_max(m[3].to_s, "#{c(%i[intense_black on_black])}¬")
688
+ code_block = pad_max(m[3].to_s, "#{color('code_block eol')}¬")
487
689
  leader = language ? language : 'code'
488
690
  end
489
691
  end
@@ -519,31 +721,6 @@ module CLIMarkdown
519
721
  # previous_indent = indent
520
722
  # end
521
723
  else
522
- # Headlines
523
- line.gsub!(/^(#+) *(.*?)(\s*#+)?\s*$/) do |match|
524
- m = Regexp.last_match
525
- pad = ""
526
- ansi = ''
527
- case m[1].length
528
- when 1
529
- ansi = c(%i[b black on_intense_white])
530
- pad = c(%i[b white])
531
- pad += m[2].length + 2 > @cols ? "*"*m[2].length : "*"*(@cols - (m[2].length + 2))
532
- when 2
533
- ansi = c(%i[b green on_black])
534
- pad = c(%i[b black])
535
- pad += m[2].length + 2 > @cols ? "-"*m[2].length : "-"*(@cols - (m[2].length + 2))
536
- when 3
537
- ansi = c(%i[u b yellow])
538
- when 4
539
- ansi = c(%i[x u yellow])
540
- else
541
- ansi = c(%i[b white])
542
- end
543
-
544
- "\n#{xc}#{ansi}#{m[2]} #{pad}#{xc}\n"
545
- end
546
-
547
724
  # place footnotes under paragraphs that reference them
548
725
  if line =~ /\[(?:\e\[[\d;]+m)*\^(?:\e\[[\d;]+m)*(\S+)(?:\e\[[\d;]+m)*\]/
549
726
  key = $1.uncolor
@@ -578,6 +755,7 @@ module CLIMarkdown
578
755
  end
579
756
 
580
757
  # make reference links inline
758
+
581
759
  line.gsub!(/(?<![\e*])\[(\b.*?\b)?\]\[(\b.+?\b)?\]/) do |m|
582
760
  match = Regexp.last_match
583
761
  title = match[2] || ''
@@ -607,12 +785,20 @@ module CLIMarkdown
607
785
  line.gsub!(/`(.*?)`/) do |m|
608
786
  match = Regexp.last_match
609
787
  last = find_color(match.pre_match, true)
610
- "#{c(%i[b black])}`#{c(%i[b white])}#{match[1]}#{c(%i[b black])}`" + (last ? last : xc)
788
+ [
789
+ color('code_span marker'),
790
+ '`',
791
+ color('code_span color'),
792
+ match[1],
793
+ color('code_span marker'),
794
+ '`',
795
+ last ? last : xc
796
+ ].join
611
797
  end
612
798
 
613
799
  # horizontal rules
614
800
  line.gsub!(/^ {,3}([\-*] ?){3,}$/) do |m|
615
- c(%i[x black]) + '_'*@cols + xc
801
+ color('hr color') + '_'*@cols + xc
616
802
  end
617
803
 
618
804
  # bold, bold/italic
@@ -659,14 +845,27 @@ module CLIMarkdown
659
845
  line.gsub!(/^(\s*)([*\-+]|\d+\.) /) do |m|
660
846
  match = Regexp.last_match
661
847
  last = find_color(match.pre_match)
848
+ mcolor = match[2] =~ /^\d+\./ ? 'list number' : 'list bullet'
662
849
  indent = match[1] || ''
663
- "#{indent}#{c(%i[d red])}#{match[2]} " + (last ? last : xc)
850
+ [
851
+ indent,
852
+ color(mcolor),
853
+ match[2], " ",
854
+ color('list color')
855
+ ].join
664
856
  end
665
857
 
666
858
  # definition lists
667
859
  line.gsub!(/^(:\s*)(.*?)/) do |m|
668
860
  match = Regexp.last_match
669
- "#{c(%i[d red])}#{match[1]} #{c(%i[b white])}#{match[2]}#{xc}"
861
+ [
862
+ color('dd marker'),
863
+ match[1],
864
+ " ",
865
+ color('dd color'),
866
+ match[2],
867
+ xc
868
+ ].join
670
869
  end
671
870
 
672
871
  # misc html
@@ -674,7 +873,15 @@ module CLIMarkdown
674
873
  line.gsub!(/(?i-m)((<\/?)(\w+[\s\S]*?)(>))/) do |tag|
675
874
  match = Regexp.last_match
676
875
  last = find_color(match.pre_match)
677
- "#{c(%i[d yellow on_black])}#{match[2]}#{match[3]}#{match[4]}" + (last ? last : xc)
876
+ [
877
+ color('html brackets'),
878
+ match[2],
879
+ color('html color'),
880
+ match[3],
881
+ color('html brackets'),
882
+ match[4],
883
+ last ? last : xc
884
+ ].join
678
885
  end
679
886
  end
680
887
 
@@ -683,6 +890,36 @@ module CLIMarkdown
683
890
 
684
891
  input = lines.join("\n")
685
892
 
893
+ # Headlines
894
+ @headers.each {|h|
895
+ input.sub!(/^#{h[2]}/) do |m|
896
+ pad = ""
897
+ ansi = ''
898
+ case h[0].length
899
+ when 1
900
+ ansi = color('h1 color')
901
+ pad = color('h1 pad')
902
+ char = @theme['h1']['pad_char'] || "="
903
+ pad += h[1].length + 2 > @cols ? char*h[1].length : char*(@cols - (h[1].length + 1))
904
+ when 2
905
+ ansi = color('h2 color')
906
+ pad = color('h2 pad')
907
+ char = @theme['h2']['pad_char'] || "-"
908
+ pad += h[1].length + 2 > @cols ? char*h[1].length : char*(@cols - (h[1].length + 1))
909
+ when 3
910
+ ansi = color('h3 color')
911
+ when 4
912
+ ansi = color('h4 color')
913
+ when 5
914
+ ansi = color('h5 color')
915
+ else
916
+ ansi = color('h6 color')
917
+ end
918
+
919
+ "\n#{xc}#{ansi}#{h[1]} #{pad}#{xc}\n"
920
+ end
921
+ }
922
+
686
923
  # images
687
924
  input.gsub!(/^(.*?)!\[(.*)?\]\((.*?\.(?:png|gif|jpg))( +.*)?\)/) do |m|
688
925
  match = Regexp.last_match
@@ -731,7 +968,20 @@ module CLIMarkdown
731
968
  end
732
969
 
733
970
  @footnotes.each {|t, v|
734
- input += "\n\n#{c(%i[b black on_black])}[#{c(%i[b yellow on_black])}^#{c(%i[x yellow on_black])}#{t}#{c(%i[b black on_black])}]: #{c(%i[u white on_black])}#{v}#{xc}"
971
+ input += [
972
+ "\n\n",
973
+ color('footnote brackets'),
974
+ "[",
975
+ color('footnote caret'),
976
+ "^",
977
+ color('footnote title'),
978
+ t,
979
+ color('footnote brackets'),
980
+ "]: ",
981
+ color('footnote note'),
982
+ v,
983
+ xc
984
+ ].join
735
985
  }
736
986
 
737
987
  @output += input
@@ -760,6 +1010,7 @@ module CLIMarkdown
760
1010
  IO.select [input]
761
1011
 
762
1012
  pager = which_pager
1013
+ @log.info(%{Using #{pager} as pager})
763
1014
  begin
764
1015
  exec(pager.join(' '))
765
1016
  rescue SystemCallError => e
@@ -805,13 +1056,13 @@ module CLIMarkdown
805
1056
  def which_pager
806
1057
  pagers = [ENV['GIT_PAGER'], ENV['PAGER'],
807
1058
  `git config --get-all core.pager || true`.split.first,
808
- 'less', 'more', 'cat', 'pager']
1059
+ 'bat', 'less', 'more', 'cat', 'pager']
809
1060
  pagers.select! do |f|
810
1061
  if f
811
1062
  if f.strip =~ /[ |]/
812
1063
  f
813
1064
  else
814
- system "which #{f}", :out => File::NULL
1065
+ system "which #{f}", :out => File::NULL
815
1066
  end
816
1067
  else
817
1068
  false
@@ -1,3 +1,3 @@
1
1
  module CLIMarkdown
2
- VERSION = '0.0.14'
2
+ VERSION = '0.0.15'
3
3
  end
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: 0.0.14
4
+ version: 0.0.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Terpstra
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-09-12 00:00:00.000000000 Z
11
+ date: 2019-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake