mdless 2.0.17 → 2.0.18
Sign up to get free protection for your applications and to get access to all the features.
- 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
|