markbridge 0.4.0 → 0.4.1

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: 6d958f4d4c04108de2f92388f6a62ac37ab126700f535af2c6cf38f832928e20
4
- data.tar.gz: 86510bc530a71fefb9f30e350a7800d159dd9e5fa77231f2f6259253373c11b4
3
+ metadata.gz: 6bb47b7959df5ce79179a7edbe11ffff2126d6769ed70af335fa12f62467a7f9
4
+ data.tar.gz: e959d0e4c9e9f05abf66d2c57e79ac4ffa123b88304addcd2b2cfc18a8d4734d
5
5
  SHA512:
6
- metadata.gz: 828a0d60a75ac730dd882e7825e2ea2e0fec53ca6b2efea6329cac03030157fba4ea086118476445ea9505835ab28031221ed786be526bdfb1b2340e2c570c56
7
- data.tar.gz: 3df501c15e4050edcbd2225d356440e4672d30a5feb8d85a3b225af0daa4cd66f09f743044ac41b7e75b01a8378951aceac7784078833facb4d42cefcfc3aa24
6
+ metadata.gz: 49ee985843ccb441d18b680a8e9aa3983f8f3ab37d0831462a71959c356d7cd993495bc5d4b777d3aa5ec58ace53d995d9b57aacda198d6ee95f2d11b97038cc
7
+ data.tar.gz: 9a6551d169ac4b2ee9211a7ee460ac6247cc5f9c00ef8fe1fced7139cd1836959c03110da020a7b37f23b735ca348070bb378da1bfc8083246a98718c0116d67
@@ -76,7 +76,6 @@ module Markbridge
76
76
  FENCED_CODE_BACKTICK = /\A`{3,}[^`]*$/
77
77
  FENCED_CODE_TILDE = /\A~{3,}/
78
78
  SETEXT_UNDERLINE_EQUALS = /\A=+[ \t]*$/
79
- SETEXT_UNDERLINE_DASH = /\A-+[ \t]*$/
80
79
  # Indented code: 4+ spaces, tab at start, or space+tab reaching column 4+
81
80
  INDENTED_CODE = /\A(?: {4}|\t| {1,3}\t)/
82
81
 
@@ -182,11 +181,11 @@ module Markbridge
182
181
  # skip the split and its Array + line-String allocations. A lone
183
182
  # `\r` without `\n` stays on the line either way — `/\r?\n/`
184
183
  # needs the `\n` — so `include?("\n")` alone decides correctly.
185
- return escape_line(text, false) unless text.include?("\n")
184
+ return escape_line(text) unless text.include?("\n")
186
185
 
187
186
  # On CRLF input, consume `\r` as part of the line terminator instead
188
187
  # of leaving it on the line. A trailing `\r` breaks line-end anchored
189
- # regexes (e.g. SETEXT_UNDERLINE_*) and the `ws_end >= line_length`
188
+ # regexes (e.g. SETEXT_UNDERLINE_EQUALS) and the `ws_end >= line_length`
190
189
  # early-out in escape_indented_code, leaking NBSPs onto
191
190
  # whitespace-only CRLF lines. The `include?` guard keeps the
192
191
  # LF-only fast path on a string split (regex split is ~20% slower
@@ -196,22 +195,19 @@ module Markbridge
196
195
  # Pre-allocate result buffer
197
196
  bytesize = text.bytesize
198
197
  result = String.new(capacity: bytesize + bytesize / 3, encoding: text.encoding)
199
- prev_was_paragraph = false
200
198
  first = true
201
199
 
202
200
  lines.each do |line|
203
201
  result << "\n" unless first
204
202
  first = false
205
203
 
206
- escaped = escape_line(line, prev_was_paragraph)
207
- result << escaped
208
- prev_was_paragraph = paragraph_line?(line)
204
+ result << escape_line(line)
209
205
  end
210
206
 
211
207
  result
212
208
  end
213
209
 
214
- def escape_line(line, prev_was_paragraph)
210
+ def escape_line(line)
215
211
  # No `line.empty?` early-return: it's redundant with the
216
212
  # `line.getbyte(indent_len).nil?` guard below, which catches both
217
213
  # empty and whitespace-only lines while also preserving object
@@ -229,7 +225,7 @@ module Markbridge
229
225
  has_indent = indent_len > 0
230
226
  content = has_indent ? line[indent_len..] : line
231
227
 
232
- escaped, skip_inline = escape_block_level(content, prev_was_paragraph)
228
+ escaped, skip_inline = escape_block_level(content)
233
229
  escaped = escape_inline(escaped) unless skip_inline
234
230
 
235
231
  if has_indent
@@ -276,7 +272,7 @@ module Markbridge
276
272
  "#{nbsp_indent}#{escape_inline(content)}"
277
273
  end
278
274
 
279
- def escape_block_level(content, prev_was_paragraph)
275
+ def escape_block_level(content)
280
276
  first_byte = content.getbyte(0)
281
277
 
282
278
  case first_byte
@@ -289,7 +285,7 @@ module Markbridge
289
285
  return pass_first_char_inline(content) if @allow.include?(:block_quote)
290
286
  return escape_first_char_inline(content, "\\>")
291
287
  when DASH
292
- return escape_block_dash(content, prev_was_paragraph)
288
+ return escape_block_dash(content)
293
289
  when PLUS
294
290
  if BULLET_LIST.match?(content)
295
291
  return pass_first_char_inline(content) if @allow.include?(:bullet_list)
@@ -302,7 +298,17 @@ module Markbridge
302
298
  return escape_all_chars(content, UNDERSCORE, "\\_"), true
303
299
  end
304
300
  when EQUALS
305
- if prev_was_paragraph && SETEXT_UNDERLINE_EQUALS.match?(content)
301
+ # A line of only `=` is a setext heading underline when a
302
+ # paragraph line comes before it. The escaper sees a single
303
+ # text fragment, and the renderer can put that fragment
304
+ # right after a paragraph line — after a line break, or
305
+ # after inline markup like `[b]Body[/b]\n===` — so the
306
+ # previous line is not visible here. The line is therefore
307
+ # escaped in every position, like every other block
308
+ # construct. Where no paragraph line comes before it,
309
+ # Discourse renders `\=` as a literal `=`, so the result
310
+ # looks the same.
311
+ if SETEXT_UNDERLINE_EQUALS.match?(content)
306
312
  return escape_all_chars(content, EQUALS, "\\="), true
307
313
  end
308
314
  when BACKTICK
@@ -327,11 +333,8 @@ module Markbridge
327
333
  ["#{escaped_char}#{escape_inline(content[1..])}", true]
328
334
  end
329
335
 
330
- def escape_block_dash(content, prev_was_paragraph)
331
- if THEMATIC_BREAK_DASH.match?(content) ||
332
- (prev_was_paragraph && SETEXT_UNDERLINE_DASH.match?(content))
333
- return escape_all_chars(content, DASH, "\\-"), true
334
- end
336
+ def escape_block_dash(content)
337
+ return escape_all_chars(content, DASH, "\\-"), true if THEMATIC_BREAK_DASH.match?(content)
335
338
  if BULLET_LIST.match?(content)
336
339
  return pass_first_char_inline(content) if @allow.include?(:bullet_list)
337
340
  return escape_first_char_inline(content, "\\-")
@@ -562,56 +565,6 @@ module Markbridge
562
565
  1
563
566
  end
564
567
  end
565
-
566
- def paragraph_line?(line)
567
- pos = 0
568
- line_len = line.bytesize
569
- pos += 1 while pos < line_len && line.getbyte(pos) == SPACE
570
- first_non_space = pos
571
-
572
- # Empty or whitespace-only lines: getbyte past the end returns nil.
573
- return false if line.getbyte(first_non_space).nil?
574
-
575
- # Indented code (4+ spaces or any leading \t) is not a paragraph.
576
- # INDENTED_CODE also catches lines where first_non_space > 3, so no
577
- # separate numeric boundary check is needed.
578
- return false if INDENTED_CODE.match?(line)
579
-
580
- content = first_non_space == 0 ? line : line[first_non_space..]
581
-
582
- # Lines starting with [ are paragraph content (the escaper rewrites [
583
- # to \[). block_construct? has no BRACKET_OPEN case arm, so such
584
- # lines naturally fall through and !block_construct?(content) == true.
585
- !block_construct?(content)
586
- end
587
-
588
- # Checks whether content starts with a block-level markdown construct.
589
- # Used by both escape_block_level (to decide what to escape) and
590
- # paragraph_line? (to decide if setext underlines can follow).
591
- def block_construct?(content)
592
- case content.getbyte(0)
593
- when HASH
594
- ATX_HEADING.match?(content)
595
- when GT
596
- true
597
- when DASH
598
- BULLET_LIST.match?(content) || THEMATIC_BREAK_DASH.match?(content)
599
- when STAR
600
- BULLET_LIST.match?(content) || THEMATIC_BREAK_STAR.match?(content)
601
- when PLUS
602
- BULLET_LIST.match?(content)
603
- when UNDERSCORE
604
- THEMATIC_BREAK_UNDERSCORE.match?(content)
605
- when BACKTICK
606
- FENCED_CODE_BACKTICK.match?(content)
607
- when TILDE
608
- FENCED_CODE_TILDE.match?(content)
609
- when DIGIT_0..DIGIT_9
610
- ORDERED_LIST.match?(content)
611
- else
612
- false
613
- end
614
- end
615
568
  end
616
569
  end
617
570
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Markbridge
4
- VERSION = "0.4.0"
4
+ VERSION = "0.4.1"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: markbridge
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Discourse Team