mdless 2.0.17 → 2.0.18
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 +5 -1
- data/lib/mdless/console.rb +39 -34
- data/lib/mdless/converter.rb +34 -18
- data/lib/mdless/string.rb +80 -0
- data/lib/mdless/version.rb +1 -1
- data/lib/mdless.rb +2 -0
- metadata +16 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c8cad0405ab64bec59625210dfbf2708d23609ccc5f682b1a7c26d435ffb3d49
|
4
|
+
data.tar.gz: 747d4a04599b35b21a1a83c2607145cac4c0c5748acf6d0bde8ec024bcb7fd69
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aacd16705ef1fa770536f10b3642fa536a6db9418248c760e9c47dce8ffbfca9fb55401d7f0507ae82bf6805080f530777d640eebb41dc513772c2c98b5c1e66
|
7
|
+
data.tar.gz: 69243a2f1968d871b222740ea9f3a8dd8f76895be6c49e8fb59db20f2ef85c78046b880eab0e95f4a6e1a6b377954904b15670d4f7ed1397cfa821da7a70f857
|
data/README.md
CHANGED
@@ -31,12 +31,6 @@ If you run into errors, try `gem install --user-install mdless`, or `sudo gem in
|
|
31
31
|
|
32
32
|
### Dependencies
|
33
33
|
|
34
|
-
Some OSs are missing `tput`, which is necessary for mdless.
|
35
|
-
|
36
|
-
apt update
|
37
|
-
apt install ruby ncurses-utils
|
38
|
-
gem install mdless
|
39
|
-
|
40
34
|
To render images, you need `imgcat` or `chafa` installed (`brew install chafa`).
|
41
35
|
|
42
36
|
For syntax highlighting, the `pygmentize` command must be available, part of the [Pygments](http://pygments.org/) package (`brew install pygments`).
|
data/lib/mdless/array.rb
ADDED
data/lib/mdless/colors.rb
CHANGED
data/lib/mdless/console.rb
CHANGED
@@ -58,20 +58,36 @@ module Redcarpet
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
-
def
|
62
|
-
|
63
|
-
|
61
|
+
def code_bg(input, width)
|
62
|
+
input.split(/\n/).map do |line|
|
63
|
+
tail = line.uncolor.length < width ? "\u00A0" * (width - line.uncolor.length) : ''
|
64
|
+
"#{x}#{line}#{tail}#{x}"
|
65
|
+
end.join("\n")
|
64
66
|
end
|
65
67
|
|
66
68
|
def hilite_code(code_block, language)
|
67
|
-
|
69
|
+
if @options[:syntax_higlight] && !exec_available('pygmentize')
|
70
|
+
@log.error('Syntax highlighting requested by pygmentize is not available')
|
71
|
+
@options[:syntax_higlight] = false
|
72
|
+
end
|
73
|
+
|
74
|
+
longest_line = code_block.uncolor.split(/\n/).longest_element.length + 4
|
75
|
+
longest_line = longest_line > @cols ? @cols : longest_line
|
68
76
|
|
69
|
-
if @options[:syntax_higlight]
|
70
|
-
|
77
|
+
if @options[:syntax_higlight]
|
78
|
+
pyg = TTY::Which.which('pygmentize')
|
79
|
+
lexer = language&.valid_lexer? ? "-l #{language}" : '-g'
|
71
80
|
begin
|
81
|
+
pygments_theme = @options[:pygments_theme] || @theme['code_block']['pygments_theme']
|
82
|
+
|
83
|
+
unless pygments_theme.valid_pygments_theme?
|
84
|
+
@log.error("Invalid Pygments theme #{pygments_theme}, defaulting to 'default' for highlighting")
|
85
|
+
pygments_theme = 'default'
|
86
|
+
end
|
87
|
+
|
72
88
|
cmd = [
|
73
|
-
|
74
|
-
"-O style=#{
|
89
|
+
"#{pyg} -f terminal256",
|
90
|
+
"-O style=#{pygments_theme}",
|
75
91
|
lexer,
|
76
92
|
'2> /dev/null'
|
77
93
|
].join(' ')
|
@@ -102,17 +118,23 @@ module Redcarpet
|
|
102
118
|
end.join("\n").blackout(@theme['code_block']['bg']) + "#{xc}\n"
|
103
119
|
end
|
104
120
|
|
121
|
+
top_border = if language.nil? || language.empty?
|
122
|
+
'-' * longest_line
|
123
|
+
else
|
124
|
+
"--[ #{language} ]#{'-' * (longest_line - 6 - language.length)}"
|
125
|
+
end
|
126
|
+
|
105
127
|
[
|
106
128
|
xc,
|
107
129
|
color('code_block border'),
|
108
|
-
|
130
|
+
top_border,
|
109
131
|
xc,
|
110
132
|
"\n",
|
111
133
|
color('code_block color'),
|
112
|
-
hilite.chomp,
|
134
|
+
code_bg(hilite.chomp, longest_line),
|
113
135
|
"\n",
|
114
136
|
color('code_block border'),
|
115
|
-
'-' *
|
137
|
+
'-' * longest_line,
|
116
138
|
xc
|
117
139
|
].join
|
118
140
|
end
|
@@ -505,7 +527,9 @@ module Redcarpet
|
|
505
527
|
|
506
528
|
lines = input.split(/\n/)
|
507
529
|
line1 = lines.shift
|
508
|
-
|
530
|
+
pre = ' ' * (indent + 1)
|
531
|
+
cols = @cols - pre.length
|
532
|
+
body = lines.map { |l| "#{pre}#{l}" }.join("\n")
|
509
533
|
"#{line1}\n#{body}"
|
510
534
|
end
|
511
535
|
|
@@ -628,6 +652,8 @@ module Redcarpet
|
|
628
652
|
|
629
653
|
def color_meta(text)
|
630
654
|
input = text.dup
|
655
|
+
input.clean_empty_lines!
|
656
|
+
|
631
657
|
first_line = input.split("\n").first
|
632
658
|
if first_line =~ /(?i-m)^---[ \t]*?$/
|
633
659
|
@log.info('Found YAML')
|
@@ -637,7 +663,7 @@ module Redcarpet
|
|
637
663
|
m = Regexp.last_match
|
638
664
|
@log.info('Processing YAML Header')
|
639
665
|
lines = m[0].split(/\n/)
|
640
|
-
longest = lines.
|
666
|
+
longest = lines.longest_element.length
|
641
667
|
longest = longest < @cols ? longest + 1 : @cols
|
642
668
|
lines.map do |line|
|
643
669
|
if line =~ /^[-.]{3}\s*$/
|
@@ -674,29 +700,8 @@ module Redcarpet
|
|
674
700
|
end
|
675
701
|
|
676
702
|
def preprocess(input)
|
677
|
-
in_yaml = false
|
678
|
-
|
679
|
-
if @options[:taskpaper] == :auto
|
680
|
-
@options[:taskpaper] = if @file =~ /\.taskpaper/
|
681
|
-
@log.info('TaskPaper extension detected')
|
682
|
-
true
|
683
|
-
elsif CLIMarkdown::TaskPaper.is_taskpaper?(input)
|
684
|
-
@log.info('TaskPaper document detected')
|
685
|
-
true
|
686
|
-
else
|
687
|
-
false
|
688
|
-
end
|
689
|
-
end
|
690
|
-
|
691
703
|
input = color_meta(input)
|
692
704
|
|
693
|
-
if @options[:taskpaper]
|
694
|
-
input = CLIMarkdown::TaskPaper.highlight(input, @theme)
|
695
|
-
input = highlight_tags(input)
|
696
|
-
return input
|
697
|
-
end
|
698
|
-
|
699
|
-
|
700
705
|
## Replace setex headers with ATX
|
701
706
|
input.gsub!(/^([^\n]+)\n={2,}\s*$/m, "# \\1\n")
|
702
707
|
input.gsub!(/^([^\n]+?)\n-{2,}\s*$/m, "## \\1\n")
|
data/lib/mdless/converter.rb
CHANGED
@@ -12,6 +12,12 @@ module CLIMarkdown
|
|
12
12
|
"#{CLIMarkdown::EXECUTABLE_NAME} #{CLIMarkdown::VERSION}"
|
13
13
|
end
|
14
14
|
|
15
|
+
def default(option, default)
|
16
|
+
if @options[option].nil?
|
17
|
+
@options[option] = default
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
15
21
|
def initialize(args)
|
16
22
|
@log = Logger.new($stderr)
|
17
23
|
@log.level = Logger::WARN
|
@@ -23,7 +29,7 @@ module CLIMarkdown
|
|
23
29
|
optparse = OptionParser.new do |opts|
|
24
30
|
opts.banner = "#{version} by Brett Terpstra\n\n> Usage: #{CLIMarkdown::EXECUTABLE_NAME} [options] [path]\n\n"
|
25
31
|
|
26
|
-
|
32
|
+
default(:color, true)
|
27
33
|
opts.on('-c', '--[no-]color', 'Colorize output (default on)') do |c|
|
28
34
|
@options[:color] = c
|
29
35
|
end
|
@@ -42,8 +48,8 @@ module CLIMarkdown
|
|
42
48
|
exit
|
43
49
|
end
|
44
50
|
|
45
|
-
|
46
|
-
|
51
|
+
default(:local_images, false)
|
52
|
+
default(:remote_images, false)
|
47
53
|
opts.on('-i', '--images=TYPE',
|
48
54
|
'Include [local|remote (both)|none] images in output (requires chafa or imgcat, default none).') do |type|
|
49
55
|
if exec_available('imgcat') || exec_available('chafa')
|
@@ -71,33 +77,34 @@ module CLIMarkdown
|
|
71
77
|
end
|
72
78
|
end
|
73
79
|
|
74
|
-
|
80
|
+
|
81
|
+
default(:list, false)
|
75
82
|
opts.on('-l', '--list', 'List headers in document and exit') do
|
76
83
|
@options[:list] = true
|
77
84
|
end
|
78
85
|
|
79
|
-
|
86
|
+
default(:pager, true)
|
80
87
|
opts.on('-p', '--[no-]pager', 'Formatted output to pager (default on)') do |p|
|
81
88
|
@options[:pager] = p
|
82
89
|
end
|
83
90
|
|
84
|
-
|
91
|
+
default(:pager, true)
|
85
92
|
opts.on('-P', 'Disable pager (same as --no-pager)') do
|
86
93
|
@options[:pager] = false
|
87
94
|
end
|
88
95
|
|
89
|
-
|
96
|
+
default(:section, nil)
|
90
97
|
opts.on('-s', '--section=NUMBER[,NUMBER]',
|
91
98
|
'Output only a headline-based section of the input (numeric from --list)') do |section|
|
92
99
|
@options[:section] = section.split(/ *, */).map(&:strip).map(&:to_i)
|
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
|
@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
|
@options[:at_tags] = true
|
103
110
|
end
|
@@ -107,28 +114,35 @@ 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
|
@options[:width] = columns.to_i
|
113
120
|
end
|
121
|
+
cols = TTY::Screen.cols
|
122
|
+
@options[:width] = cols if @options[:width] > cols
|
114
123
|
|
115
|
-
|
124
|
+
default(:autolink, true)
|
125
|
+
opts.on('--[no-]autolink', 'Convert bare URLs and emails to <links>') do |p|
|
126
|
+
@options[:autolink] = p
|
127
|
+
end
|
128
|
+
|
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
|
@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
|
@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
|
@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|
|
@@ -142,7 +156,7 @@ 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
|
@options[:syntax_higlight] = p
|
148
162
|
end
|
@@ -170,12 +184,12 @@ 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
|
@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
|
@options[:wiki_links] = opt
|
181
195
|
end
|
@@ -202,6 +216,7 @@ module CLIMarkdown
|
|
202
216
|
|
203
217
|
@theme = load_theme(@options[:theme])
|
204
218
|
@cols = @options[:width] - 2
|
219
|
+
|
205
220
|
@output = ''
|
206
221
|
@headers = []
|
207
222
|
@setheaders = []
|
@@ -218,7 +233,7 @@ module CLIMarkdown
|
|
218
233
|
|
219
234
|
markdown = Redcarpet::Markdown.new(renderer,
|
220
235
|
no_intra_emphasis: !@options[:intra_emphasis],
|
221
|
-
autolink:
|
236
|
+
autolink: @options[:autolink],
|
222
237
|
fenced_code_blocks: true,
|
223
238
|
footnotes: true,
|
224
239
|
hard_wrap: false,
|
@@ -264,6 +279,7 @@ module CLIMarkdown
|
|
264
279
|
end
|
265
280
|
|
266
281
|
if @options[:taskpaper]
|
282
|
+
input = input.color_meta(@theme, @log, @cols)
|
267
283
|
input = CLIMarkdown::TaskPaper.highlight(input, @theme)
|
268
284
|
@output = input.highlight_tags(@theme, @log)
|
269
285
|
else
|
data/lib/mdless/string.rb
CHANGED
@@ -4,6 +4,14 @@
|
|
4
4
|
class ::String
|
5
5
|
include CLIMarkdown::Colors
|
6
6
|
|
7
|
+
def clean_empty_lines
|
8
|
+
gsub(/^[ \t]+$/, '')
|
9
|
+
end
|
10
|
+
|
11
|
+
def clean_empty_lines!
|
12
|
+
replace clean_empty_lines
|
13
|
+
end
|
14
|
+
|
7
15
|
def color(key, theme, log)
|
8
16
|
val = nil
|
9
17
|
keys = key.split(/[ ,>]/)
|
@@ -30,6 +38,59 @@ class ::String
|
|
30
38
|
end
|
31
39
|
end
|
32
40
|
|
41
|
+
def color_meta(theme, log, cols)
|
42
|
+
@theme = theme
|
43
|
+
@log = log
|
44
|
+
@cols = cols
|
45
|
+
input = dup
|
46
|
+
input.clean_empty_lines!
|
47
|
+
|
48
|
+
in_yaml = false
|
49
|
+
first_line = input.split("\n").first
|
50
|
+
if first_line =~ /(?i-m)^---[ \t]*?$/
|
51
|
+
@log.info('Found YAML')
|
52
|
+
# YAML
|
53
|
+
in_yaml = true
|
54
|
+
input.sub!(/(?i-m)^---[ \t]*\n([\s\S]*?)\n[-.]{3}[ \t]*\n/m) do
|
55
|
+
m = Regexp.last_match
|
56
|
+
@log.info('Processing YAML Header')
|
57
|
+
lines = m[0].split(/\n/)
|
58
|
+
longest = lines.inject { |memo, word| memo.length > word.length ? memo : word }.length
|
59
|
+
longest = longest < @cols ? longest + 1 : @cols
|
60
|
+
lines.map do |line|
|
61
|
+
if line =~ /^[-.]{3}\s*$/
|
62
|
+
line = "#{color('metadata marker', @theme, @log)}#{'%' * longest}"
|
63
|
+
else
|
64
|
+
line.sub!(/^(.*?:)[ \t]+(\S)/, '\1 \2')
|
65
|
+
line = "#{color('metadata color', @theme, @log)}#{line}"
|
66
|
+
end
|
67
|
+
|
68
|
+
line += "\u00A0" * (longest - line.uncolor.strip.length) + xc
|
69
|
+
line
|
70
|
+
end.join("\n") + "#{xc}\n"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
if !in_yaml && first_line =~ /(?i-m)^[\w ]+:\s+\S+/
|
75
|
+
@log.info('Found MMD Headers')
|
76
|
+
input.sub!(/(?i-m)^([\S ]+:[\s\S]*?)+(?=\n\n)/) do |mmd|
|
77
|
+
lines = mmd.split(/\n/)
|
78
|
+
return mmd if lines.count > 20
|
79
|
+
|
80
|
+
longest = lines.inject { |memo, word| memo.length > word.length ? memo : word }.length
|
81
|
+
longest = longest < @cols ? longest + 1 : @cols
|
82
|
+
lines.map do |line|
|
83
|
+
line.sub!(/^(.*?:)[ \t]+(\S)/, '\1 \2')
|
84
|
+
line = "#{color('metadata color', @theme, @log)}#{line}"
|
85
|
+
line += "\u00A0" * (longest - line.uncolor.strip.length)
|
86
|
+
line + xc
|
87
|
+
end.join("\n") + "#{"\u00A0" * longest}#{xc}\n"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
input
|
92
|
+
end
|
93
|
+
|
33
94
|
def highlight_tags(theme, log)
|
34
95
|
tag_color = color('at_tags tag', theme, log)
|
35
96
|
value_color = color('at_tags value', theme, log)
|
@@ -58,4 +119,23 @@ class ::String
|
|
58
119
|
def scrub!
|
59
120
|
replace scrub
|
60
121
|
end
|
122
|
+
|
123
|
+
def valid_pygments_theme?
|
124
|
+
return false unless TTY::Which.exist?('pygmentize')
|
125
|
+
pyg = TTY::Which.which('pygmentize')
|
126
|
+
res = `#{pyg} -L styles`
|
127
|
+
styles = res.scan(/\* ([\w-]+):/).map { |l| l[0] }
|
128
|
+
styles.include?(self)
|
129
|
+
end
|
130
|
+
|
131
|
+
def valid_lexer?
|
132
|
+
return false unless TTY::Which.exist?('pygmentize')
|
133
|
+
pyg = TTY::Which.which('pygmentize')
|
134
|
+
res = `#{pyg} -L lexers`
|
135
|
+
lexers = res.scan(/\* ([\w-]+(?:, [\w-]+)*):/).map { |l| l[0] }
|
136
|
+
lexers_a = []
|
137
|
+
lexers.each { |l| lexers_a.concat(l.split(/, /)) }
|
138
|
+
|
139
|
+
lexers_a.include?(self.downcase)
|
140
|
+
end
|
61
141
|
end
|
data/lib/mdless/version.rb
CHANGED
data/lib/mdless.rb
CHANGED
@@ -4,11 +4,13 @@ require 'open3'
|
|
4
4
|
require 'fileutils'
|
5
5
|
require 'logger'
|
6
6
|
require 'tty-which'
|
7
|
+
require 'tty-screen'
|
7
8
|
require 'mdless/version.rb'
|
8
9
|
require 'mdless/colors'
|
9
10
|
require 'mdless/tables'
|
10
11
|
require 'mdless/hash'
|
11
12
|
require 'mdless/string'
|
13
|
+
require 'mdless/array'
|
12
14
|
require 'mdless/taskpaper'
|
13
15
|
require 'mdless/theme'
|
14
16
|
require 'redcarpet'
|
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.
|
4
|
+
version: 2.0.18
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brett Terpstra
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0.5'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: tty-screen
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.8'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.8'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: rake
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -78,6 +92,7 @@ files:
|
|
78
92
|
- README.md
|
79
93
|
- bin/mdless
|
80
94
|
- lib/mdless.rb
|
95
|
+
- lib/mdless/array.rb
|
81
96
|
- lib/mdless/colors.rb
|
82
97
|
- lib/mdless/console.rb
|
83
98
|
- lib/mdless/converter.rb
|