mdless 2.1.64 → 2.1.65

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 61c5d8821a192399e2b85ac727b26e31b154414cf0e14ec71d07b686c0806179
4
- data.tar.gz: 3487c52d8dd4feaaccdbe383fb90afc7b6cc6820dc3eb511b5e27a36630cf764
3
+ metadata.gz: 05ec922e3d766c2ba7ba1e89f427e57666e1fedbe965e97448f96a727292459e
4
+ data.tar.gz: 84b81ddd4cf08c34bf96db99b768afe81f4c7d10859164af991720ede8c2ab51
5
5
  SHA512:
6
- metadata.gz: 2ff5faacaf20b4687043b9c1caa8fe8496d01b11398c7717620b265aa80a9fdb25867b0d2046e98bcb4b2d0ac7867aad52ee402cd9b8d5ef0f211115e3da9c82
7
- data.tar.gz: 81512704d042815e9162ad3406c86648617f01bd5de57a1c6a26889f403b83734c5a33817fe32ef24f3e5ed59f29d868a3f189d64f03c6b286afe671c616fd28
6
+ metadata.gz: 35453ae25117eb919ee039fd479951e8435108188a60eb0f8d4ae5d010b1c713808a8e247bae4212f3ea5ec9e47b34f2826ee90b1e576c676b9be21bb38e19a2
7
+ data.tar.gz: 56525e3d80217a08dac2f26d5e6eeb763dd14eeed7f92f60016c1482b58419bb29d988460d4df49b324f2c2aad5cfb837362080a0cf93161960023fcb817b4db
data/CHANGELOG.md CHANGED
@@ -249,3 +249,5 @@
249
249
  : Missing logger in Ruby 4.0.1, added to gemspec
250
250
 
251
251
  2.1.64
252
+
253
+ 2.1.65
data/README.md CHANGED
@@ -82,6 +82,8 @@ The pager used is determined by system configuration in this order of preference
82
82
  --links=FORMAT Link style ([inline, reference, paragraph], default inline,
83
83
  "paragraph" will position reference links after each paragraph)
84
84
  --[no-]linebreaks Preserve line breaks
85
+ --[no-]nbsp-padding Pad code blocks and metadata headers with non-breaking spaces
86
+ (default on; disable for clipboard-safe yank+paste in tmux et al)
85
87
  --[no-]syntax Syntax highlight code blocks
86
88
  --taskpaper=OPTION Highlight TaskPaper format (true|false|auto)
87
89
  --update_config Update the configuration file with new keys and current command line options
@@ -101,6 +103,7 @@ The first time mdless is run, a config file will be written to `~/.config/mdless
101
103
  :lax_spacing: true
102
104
  :links: :paragraph
103
105
  :local_images: true
106
+ :nbsp_padding: true
104
107
  :pager: true
105
108
  :preserve_linebreaks: false
106
109
  :remote_images: false
@@ -119,6 +122,7 @@ The first time mdless is run, a config file will be written to `~/.config/mdless
119
122
  - `:lax_spacing` determines whether a blank line is required around HTML elements.
120
123
  - `:links` can be `inline`, `reference`, or `paragraph`. Paragraph puts reference links directly after the graf that refers to them.
121
124
  - `:local_images` determines whether local images are processed using `chafa` or `imgcat` (whichever is available). `:remote_images` does the same for images referenced with web urls. If `:remote_images` is true, then `:local_images` is automatically enabled.
125
+ - `:nbsp_padding` controls the character used to right-pad fenced code blocks and metadata header lines out to a uniform block width. When `true` (the default, preserving historical behavior), padding is rendered with non-breaking spaces (U+00A0) so it survives `String#strip` and similar transforms. Set to `false` to use regular ASCII spaces instead, which makes terminal selections (e.g. tmux `shift+v`) yank a shell-safe string — non-breaking spaces are not treated as whitespace by most shells and otherwise get glued to the last argument of a pasted command.
122
126
  - `:pager` turns on or off pagination using `less` or closest available substitute.
123
127
  - `:preserve_linebreaks` determines whether hard breaks within paragraphs are preserved. When converting to HTML, most Markdown processors will cause consecutive lines to be merged together, which is the default behavior for `mdless`. Turning this option on will cause lines to remain hard wrapped.
124
128
  - `:syntax_highlight` will turn on/off syntax highlighting of code blocks (requires Pygments)
@@ -59,8 +59,9 @@ module Redcarpet
59
59
  end
60
60
 
61
61
  def code_bg(input, width)
62
+ pad_char = MDLess.options[:nbsp_padding] ? "\u00A0" : ' '
62
63
  input.split(/\n/).map do |line|
63
- tail = line.uncolor.length < width ? "\u00A0" * (width - line.uncolor.length) : ''
64
+ tail = line.uncolor.length < width ? pad_char * (width - line.uncolor.length) : ''
64
65
  "#{x}#{line}#{tail}#{x}"
65
66
  end.join("\n")
66
67
  end
@@ -122,19 +123,26 @@ module Redcarpet
122
123
  stdin_data: code_block)
123
124
 
124
125
  if s.success?
126
+ # NOTE: do NOT append xc/\n after blackout. blackout's `$` regex
127
+ # injects the bg-color escape at the end of every line; anything
128
+ # appended after that becomes part of the last line when code_bg
129
+ # later splits on \n, and a trailing xc there resets the bg so
130
+ # the last line's right-padding renders without the block bg.
131
+ # code_bg now emits its own per-line xc trailer instead.
125
132
  hilite = xc + hilite.split(/\n/).map do |l|
126
133
  [
127
134
  color('code_block marker'),
128
135
  MDLess.theme['code_block']['character'],
129
136
  "#{color('code_block bg')}#{l}#{xc}"
130
137
  ].join
131
- end.join("\n").blackout(MDLess.theme['code_block']['bg']) + "#{xc}\n"
138
+ end.join("\n").blackout(MDLess.theme['code_block']['bg'])
132
139
  end
133
140
  rescue StandardError => e
134
141
  MDLess.log.error(e)
135
142
  hilite = code_block
136
143
  end
137
144
  else
145
+ # See note above re: dropping the trailing xc/\n.
138
146
  hilite = code_block.split(/\n/).map do |line|
139
147
  [
140
148
  color('code_block marker'),
@@ -143,7 +151,7 @@ module Redcarpet
143
151
  line,
144
152
  xc
145
153
  ].join
146
- end.join("\n").blackout(MDLess.theme['code_block']['bg']) + "#{xc}\n"
154
+ end.join("\n").blackout(MDLess.theme['code_block']['bg'])
147
155
  end
148
156
 
149
157
  top_border = if language.nil? || language.empty?
@@ -195,7 +203,11 @@ module Redcarpet
195
203
  end
196
204
 
197
205
  def block_code(code, language)
198
- "\n\n#{hilite_code(code, language)}#{xc}\n\n"
206
+ # Wrap in <<codeblock>>...<</codeblock>> markers so postprocess can
207
+ # skip the backslash-escape strip inside code-block content (per the
208
+ # CommonMark spec, backslash-escapes do not apply inside code blocks).
209
+ # The markers are removed in postprocess after the strip pass.
210
+ "\n\n<<codeblock>>#{hilite_code(code, language)}#{xc}<</codeblock>>\n\n"
199
211
  end
200
212
 
201
213
  def block_quote(quote)
@@ -744,6 +756,7 @@ module Redcarpet
744
756
  input = text.dup
745
757
  input.clean_empty_lines!
746
758
  MDLess.meta = {}
759
+ pad_char = MDLess.options[:nbsp_padding] ? "\u00A0" : ' '
747
760
  first_line = input.split("\n").first
748
761
  if first_line =~ /(?i-m)^---[ \t]*?$/
749
762
  MDLess.log.info('Found YAML')
@@ -773,7 +786,7 @@ module Redcarpet
773
786
  line = "#{color('metadata marker')}% #{color('metadata color')}#{line}"
774
787
  end
775
788
  if (longest - line.uncolor.strip.length).positive?
776
- line += "\u00A0" * (longest - line.uncolor.strip.length)
789
+ line += pad_char * (longest - line.uncolor.strip.length)
777
790
  end
778
791
  line + xc
779
792
  end.join("\n") + "#{xc}\n"
@@ -799,7 +812,7 @@ module Redcarpet
799
812
  end
800
813
  line = "#{color('metadata marker')}%#{color('metadata color')}#{line}"
801
814
  if (longest - line.uncolor.strip.length).positive?
802
- line += "\u00A0" * (longest - line.uncolor.strip.length)
815
+ line += pad_char * (longest - line.uncolor.strip.length)
803
816
  end
804
817
  line + xc
805
818
  end.join("\n") + "#{xc}\n"
@@ -1144,8 +1157,19 @@ module Redcarpet
1144
1157
  end.join("\n")
1145
1158
  input = "#{input}\n\n#{footnotes}"
1146
1159
  end
1147
- # escaped characters
1148
- input.gsub!(/\\(\S)/, '\1')
1160
+ # Escaped characters: strip backslash-escapes per CommonMark spec
1161
+ # (https://spec.commonmark.org/0.31.2/#backslash-escapes), but only
1162
+ # for the ASCII punctuation set the spec actually recognizes, and
1163
+ # only on non-code-block content. block_code wraps its output in
1164
+ # <<codeblock>>...<</codeblock>> markers so we can isolate those
1165
+ # regions here. The previous `\\(\S)` form ate every backslash-
1166
+ # followed-by-non-space, including `\n \t \s \S \d \w \1 \2 ...`
1167
+ # inside code blocks, which shifted padding-aligned right edges
1168
+ # left by N chars per stripped backslash.
1169
+ input = input.split(%r{(<<codeblock>>.*?<</codeblock>>)}m).map.with_index do |seg, i|
1170
+ i.odd? ? seg : seg.gsub(/\\([!"\#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~])/, '\1')
1171
+ end.join
1172
+ input.gsub!(%r{<</?codeblock>>}, '')
1149
1173
  # equations
1150
1174
  input = fix_equations(input)
1151
1175
  # misc html
@@ -196,6 +196,13 @@ module CLIMarkdown
196
196
  MDLess.options[:mmd_metadata] = opt
197
197
  end
198
198
 
199
+ default(:nbsp_padding, true)
200
+ opts.on("--[no-]nbsp-padding",
201
+ "Pad code blocks and metadata headers with non-breaking spaces" \
202
+ " (default true; disable for clipboard-safe yank+paste in terminal multiplexers)") do |opt|
203
+ MDLess.options[:nbsp_padding] = opt
204
+ end
205
+
199
206
  default(:syntax_higlight, false)
200
207
  opts.on("--[no-]syntax", "Syntax highlight code blocks") do |opt|
201
208
  MDLess.options[:syntax_higlight] = opt
data/lib/mdless/string.rb CHANGED
@@ -57,6 +57,7 @@ class ::String
57
57
  input = dup
58
58
  input.clean_empty_lines!
59
59
  MDLess.meta = {}
60
+ pad_char = MDLess.options[:nbsp_padding] ? "\u00A0" : ' '
60
61
 
61
62
  in_yaml = false
62
63
  first_line = input.split("\n").first
@@ -79,7 +80,7 @@ class ::String
79
80
  line = "#{color('metadata marker')}%#{color('metadata color')}#{line}#{xc}"
80
81
  end
81
82
 
82
- line += "\u00A0" * (longest - line.uncolor.strip.length) if (longest - line.uncolor.strip.length).positive?
83
+ line += pad_char * (longest - line.uncolor.strip.length) if (longest - line.uncolor.strip.length).positive?
83
84
  line + xc
84
85
  end.join("\n") + "#{xc}\n"
85
86
  end
@@ -100,9 +101,9 @@ class ::String
100
101
  value = parts[2].strip
101
102
  MDLess.meta[key] = value
102
103
  line = "#{color('metadata color')}#{line}#{xc}"
103
- line += "\u00A0" * (longest - line.uncolor.strip.length) if (longest - line.uncolor.strip.length).positive?
104
+ line += pad_char * (longest - line.uncolor.strip.length) if (longest - line.uncolor.strip.length).positive?
104
105
  line + xc
105
- end.join("\n") + "#{"\u00A0" * longest}#{xc}\n"
106
+ end.join("\n") + "#{pad_char * longest}#{xc}\n"
106
107
  end
107
108
  end
108
109
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CLIMarkdown
4
- VERSION = '2.1.64'
4
+ VERSION = '2.1.65'
5
5
  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: 2.1.64
4
+ version: 2.1.65
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Terpstra
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-03-12 00:00:00.000000000 Z
11
+ date: 2026-05-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redcarpet