mdless 2.0.16 → 2.0.18

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: 3c2164454fac4fd82af1ef1594166585de749e87cca73c7c83c25c38c3288dd9
4
- data.tar.gz: 7b2008f35bd4ddc66fac4438fda186964a538ef0715739410b0b4c429323d96b
3
+ metadata.gz: c8cad0405ab64bec59625210dfbf2708d23609ccc5f682b1a7c26d435ffb3d49
4
+ data.tar.gz: 747d4a04599b35b21a1a83c2607145cac4c0c5748acf6d0bde8ec024bcb7fd69
5
5
  SHA512:
6
- metadata.gz: e119669e34faaa577b8956eb5817f3b391887108e425b0cb5fcb630f14ea5aa6ffa3282c531c7602fc07912c7a75299bd10169d9ba95375485c664226f30a930
7
- data.tar.gz: caae8bb09f9c48e25ad144b401ff74a58a379bb5b10b63ffa66c3afef707ccd39af6699a7301c3467ba180395d8e4ab025cd9a10900d44ae7dfafadde2954fa3
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`).
@@ -60,8 +54,6 @@ The pager used is determined by system configuration in this order of preference
60
54
  -h, --help Display this screen
61
55
  -i, --images=TYPE Include [local|remote (both)|none] images in output (requires chafa or imgcat, default none).
62
56
  -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
57
  -l, --list List headers in document and exit
66
58
  -p, --[no-]pager Formatted output to pager (default on)
67
59
  -P Disable pager (same as --no-pager)
@@ -71,6 +63,14 @@ The pager used is determined by system configuration in this order of preference
71
63
  -v, --version Display version number
72
64
  -w, --width=COLUMNS Column width to format for (default: terminal width)
73
65
  --[no-]inline_footnotes Display footnotes immediately after the paragraph that references them
66
+ --[no-]intra-emphasis Parse emphasis inside of words (e.g. Mark_down_)
67
+ --[no-]lax-spacing Allow lax spacing
68
+ --links=FORMAT Link style ([inline, reference, paragraph], default inline,
69
+ "paragraph" will position reference links after each paragraph)
70
+ --[no-]syntax Syntax highlight code blocks
71
+ --taskpaper=OPTION Highlight TaskPaper format (true|false|auto)
72
+ --update_config Update the configuration file with new keys and current command line options
73
+ --[no-]wiki-links Highlight [[wiki links]]
74
74
 
75
75
  ## Configuration
76
76
 
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ::Array
4
+ def longest_element
5
+ group_by(&:size).max.last[0]
6
+ end
7
+
8
+ def longest_elements
9
+ group_by(&:size).max.last
10
+ end
11
+ end
data/lib/mdless/colors.rb CHANGED
@@ -55,7 +55,11 @@ module CLIMarkdown
55
55
  }
56
56
 
57
57
  def uncolor
58
- self.gsub(/\e\[[\d;]+m/,'')
58
+ self.unpad.gsub(/\e\[[\d;]+m/,'')
59
+ end
60
+
61
+ def unpad
62
+ self.gsub(/\u00A0/, ' ')
59
63
  end
60
64
 
61
65
  # Get the calculated ANSI color at the end of the
@@ -58,20 +58,36 @@ module Redcarpet
58
58
  end
59
59
  end
60
60
 
61
- def valid_lexer?(language)
62
- lexers = %w(Clipper XBase Cucumber cucumber Gherkin gherkin RobotFramework robotframework abap ada ada95ada2005 ahk antlr-as antlr-actionscript antlr-cpp antlr-csharp antlr-c# antlr-java antlr-objc antlr-perl antlr-python antlr-ruby antlr-rb antlr apacheconf aconf apache applescript as actionscript as3 actionscript3 aspectj aspx-cs aspx-vb asy asymptote autoit Autoit awk gawk mawk nawk basemake bash sh ksh bat bbcode befunge blitzmax bmax boo brainfuck bf bro bugs winbugs openbugs c-objdump c ca65 cbmbas ceylon cfengine3 cf3 cfm cfs cheetah spitfire clojure clj cmake cobol cobolfree coffee-script coffeescript common-lisp cl console control coq cpp c++ cpp-objdump c++-objdumb cxx-objdump croc csharp c# css+django css+jinja css+erb css+ruby css+genshitext css+genshi css+lasso css+mako css+myghty css+php css+smarty css cuda cu cython pyx d-objdump d dart delphi pas pascal objectpascal dg diff udiff django jinja dpatch dtd duel Duel Engine Duel View JBST jbst JsonML+BST dylan-console dylan-repl dylan-lid lid dylan ec ecl elixir ex exs erb erl erlang evoque factor fan fancy fy felix flx fortran fsharp gas genshi kid xml+genshi xml+kid genshitext glsl gnuplot go gooddata-cl gosu groff nroff man groovy gst haml HAML haskell hs haxeml hxml html+cheetah html+spitfire html+django html+jinja html+evoque html+genshi html+kid html+lasso html+mako html+myghty html+php html+smarty html+velocity html http hx haXe hybris hy idl iex ini cfg io ioke ik irc jade JADE jags java jlcon js+cheetah javascript+cheetah js+spitfire javascript+spitfire js+django javascript+django js+jinja javascript+jinja js+erb javascript+erb js+ruby javascript+ruby js+genshitext js+genshi javascript+genshitext javascript+genshi js+lasso javascript+lasso js+mako javascript+mako js+myghty javascript+myghty js+php javascript+php js+smarty javascript+smarty js javascript json jsp julia jl kconfig menuconfig linux-config kernel-config koka kotlin lasso lassoscript lhs literate-haskell lighty lighttpd live-script livescript llvm logos logtalk lua make makefile mf bsdmake mako maql mason matlab matlabsession minid modelica modula2 m2 monkey moocode moon moonscript mscgen msc mupad mxml myghty mysql nasm nemerle newlisp newspeak nginx nimrod nim nsis nsi nsh numpy objdump objective-c++ objectivec++ obj-c++ objc++ objective-c objectivec obj-c objc objective-j objectivej obj-j objj ocaml octave ooc opa openedge abl progress perl pl php php3 php4 php5 plpgsql postgresql postgres postscript pot po pov powershell posh ps1 prolog properties protobuf psql postgresql-console postgres-console puppet py3tb pycon pypylog pypy pytb python py sage python3 py3 qml Qt Meta Language Qt modeling Language racket rkt ragel-c ragel-cpp ragel-d ragel-em ragel-java ragel-objc ragel-ruby ragel-rb ragel raw rb ruby duby rbcon irb rconsole rout rd rebol redcode registry rhtml html+erb html+ruby rst rest restructuredtext rust sass SASS scala scaml SCAML scheme scm scilab scss shell-session smali smalltalk squeak smarty sml snobol sourceslist sources.list sp spec splus s r sql sqlite3 squidconf squid.conf squid ssp stan systemverilog sv tcl tcsh csh tea tex latex text trac-wiki moin treetop ts urbiscript vala vapi vb.net vbnet velocity verilog v vgl vhdl vim xml+cheetah xml+spitfire xml+django xml+jinja xml+erb xml+ruby xml+evoque xml+lasso xml+mako xml+myghty xml+php xml+smarty xml+velocity xml xquery xqy xq xql xqm xslt xtend yaml)
63
- lexers.include? language.strip
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
- @log.error('Syntax highlighting requested by pygmentize is not available') if @options[:syntax_higlight] && !exec_available('pygmentize')
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] && exec_available('pygmentize')
70
- lexer = language && valid_lexer?(language) ? "-l #{language}" : '-g'
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
- 'pygmentize -f terminal256',
74
- "-O style=#{@theme['code_block']['pygments_theme']}",
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
- '-' * 20,
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
- '-' * 20,
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
- body = lines.map { |l| "#{' ' * (indent + 1)}#{l}" }.join("\n")
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.inject { |memo, word| memo.length > word.length ? memo : word }.length
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")
@@ -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
- @options[:color] ||= true
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
- @options[:local_images] ||= false
46
- @options[:remote_images] ||= false
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')
@@ -61,6 +67,7 @@ module CLIMarkdown
61
67
  @log.warn('images turned on but imgcat/chafa not found')
62
68
  end
63
69
  end
70
+
64
71
  opts.on('-I', '--all-images', 'Include local and remote images in output (requires imgcat or chafa)') do
65
72
  if exec_available('imgcat') || exec_available('chafa') # && ENV['TERM_PROGRAM'] == 'iTerm.app'
66
73
  @options[:local_images] = true
@@ -70,102 +77,122 @@ module CLIMarkdown
70
77
  end
71
78
  end
72
79
 
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
80
 
118
- @options[:list] ||= false
81
+ default(:list, false)
119
82
  opts.on('-l', '--list', 'List headers in document and exit') do
120
83
  @options[:list] = true
121
84
  end
122
85
 
123
- @options[:pager] ||= true
86
+ default(:pager, true)
124
87
  opts.on('-p', '--[no-]pager', 'Formatted output to pager (default on)') do |p|
125
88
  @options[:pager] = p
126
89
  end
127
90
 
128
- @options[:pager] ||= true
91
+ default(:pager, true)
129
92
  opts.on('-P', 'Disable pager (same as --no-pager)') do
130
93
  @options[:pager] = false
131
94
  end
132
95
 
133
- @options[:section] ||= nil
96
+ default(:section, nil)
134
97
  opts.on('-s', '--section=NUMBER[,NUMBER]',
135
98
  'Output only a headline-based section of the input (numeric from --list)') do |section|
136
99
  @options[:section] = section.split(/ *, */).map(&:strip).map(&:to_i)
137
100
  end
138
101
 
139
- @options[:theme] ||= 'default'
102
+ default(:theme, 'default')
140
103
  opts.on('-t', '--theme=THEME_NAME', 'Specify an alternate color theme to load') do |theme|
141
104
  @options[:theme] = theme
142
105
  end
143
106
 
144
- @options[:at_tags] ||= false
107
+ default(:at_tags, false)
145
108
  opts.on('-@', '--at_tags', 'Highlight @tags and values in the document') do
146
109
  @options[:at_tags] = true
147
110
  end
148
111
 
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
112
  opts.on('-v', '--version', 'Display version number') do
155
113
  puts version
156
114
  exit
157
115
  end
158
116
 
159
- @options[:width] = `tput cols`.strip.to_i
117
+ default(:width, TTY::Screen.cols)
160
118
  opts.on('-w', '--width=COLUMNS', 'Column width to format for (default: terminal width)') do |columns|
161
119
  @options[:width] = columns.to_i
162
120
  end
121
+ cols = TTY::Screen.cols
122
+ @options[:width] = cols if @options[:width] > cols
123
+
124
+ default(:autolink, true)
125
+ opts.on('--[no-]autolink', 'Convert bare URLs and emails to <links>') do |p|
126
+ @options[:autolink] = p
127
+ end
163
128
 
164
- @options[:inline_footnotes] ||= false
129
+ default(:inline_footnotes, false)
165
130
  opts.on('--[no-]inline_footnotes',
166
131
  'Display footnotes immediately after the paragraph that references them') do |p|
167
132
  @options[:inline_footnotes] = p
168
133
  end
134
+
135
+ default(:intra_emphasis, true)
136
+ opts.on('--[no-]intra-emphasis', 'Parse emphasis inside of words (e.g. Mark_down_)') do |opt|
137
+ @options[:intra_emphasis] = opt
138
+ end
139
+
140
+ default(:lax_spacing, true)
141
+ opts.on('--[no-]lax-spacing', 'Allow lax spacing') do |opt|
142
+ @options[:lax_spacing] = opt
143
+ end
144
+
145
+ default(:links, :inline)
146
+ opts.on('--links=FORMAT',
147
+ 'Link style ([inline, reference, paragraph], default inline,
148
+ "paragraph" will position reference links after each paragraph)') do |fmt|
149
+ @options[:links] = case fmt
150
+ when /^:?r/i
151
+ :reference
152
+ when /^:?p/i
153
+ :paragraph
154
+ else
155
+ :inline
156
+ end
157
+ end
158
+
159
+ default(:syntax_higlight, false)
160
+ opts.on('--[no-]syntax', 'Syntax highlight code blocks') do |p|
161
+ @options[:syntax_higlight] = p
162
+ end
163
+
164
+ @options[:taskpaper] = if @options[:taskpaper]
165
+ case @options[:taskpaper].to_s
166
+ when /^[ty1]/
167
+ true
168
+ when /^a/
169
+ :auto
170
+ else
171
+ false
172
+ end
173
+ else
174
+ false
175
+ end
176
+ opts.on('--taskpaper=OPTION', 'Highlight TaskPaper format (true|false|auto)') do |tp|
177
+ @options[:taskpaper] = case tp
178
+ when /^[ty1]/
179
+ true
180
+ when /^a/
181
+ :auto
182
+ else
183
+ false
184
+ end
185
+ end
186
+
187
+ default(:update_config, false)
188
+ opts.on('--update_config', 'Update the configuration file with new keys and current command line options') do
189
+ @options[:update_config] = true
190
+ end
191
+
192
+ default(:wiki_links, false)
193
+ opts.on('--[no-]wiki-links', 'Highlight [[wiki links]]') do |opt|
194
+ @options[:wiki_links] = opt
195
+ end
169
196
  end
170
197
 
171
198
  begin
@@ -189,6 +216,7 @@ module CLIMarkdown
189
216
 
190
217
  @theme = load_theme(@options[:theme])
191
218
  @cols = @options[:width] - 2
219
+
192
220
  @output = ''
193
221
  @headers = []
194
222
  @setheaders = []
@@ -205,7 +233,7 @@ module CLIMarkdown
205
233
 
206
234
  markdown = Redcarpet::Markdown.new(renderer,
207
235
  no_intra_emphasis: !@options[:intra_emphasis],
208
- autolink: true,
236
+ autolink: @options[:autolink],
209
237
  fenced_code_blocks: true,
210
238
  footnotes: true,
211
239
  hard_wrap: false,
@@ -251,6 +279,7 @@ module CLIMarkdown
251
279
  end
252
280
 
253
281
  if @options[:taskpaper]
282
+ input = input.color_meta(@theme, @log, @cols)
254
283
  input = CLIMarkdown::TaskPaper.highlight(input, @theme)
255
284
  @output = input.highlight_tags(@theme, @log)
256
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CLIMarkdown
4
- VERSION = '2.0.16'
4
+ VERSION = '2.0.18'
5
5
  end
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.16
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
@@ -114,7 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
114
129
  - !ruby/object:Gem::Version
115
130
  version: '0'
116
131
  requirements: []
117
- rubygems_version: 3.2.15
132
+ rubygems_version: 3.2.16
118
133
  signing_key:
119
134
  specification_version: 4
120
135
  summary: A pager like less, but for Markdown files