@redpanda-data/docs-extensions-and-macros 5.37.0 → 5.37.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.
@@ -13,6 +13,8 @@
13
13
  *
14
14
  * A block closes only on a delimiter of the same length as the one that opened
15
15
  * it; a longer run, such as the row of dashes in a rendered table, is content.
16
+ * - indented literal paragraphs: an indented line that opens a block is
17
+ * rendered verbatim, so a URL on it is text and not a link
16
18
  * - line comments (//), which Asciidoctor drops entirely
17
19
  * - inline code spans (`...`)
18
20
  *
@@ -60,6 +62,23 @@ const ATTRIBUTE_REFERENCE_RX = /\{[a-zA-Z0-9_][a-zA-Z0-9_-]*\}/
60
62
  // prose cannot swallow the rest of the document.
61
63
  const MAX_WRAPPED_LABEL_LENGTH = 500
62
64
 
65
+ // An indented line that opens a block is a literal paragraph: Asciidoctor
66
+ // renders it verbatim, so any URL on it is text rather than a link. This is
67
+ // where connector descriptions put their shell examples, which is how the
68
+ // three comma-joined gcloud scope strings in google_drive_list_labels were
69
+ // read as one URL and reported broken.
70
+ const INDENTED_RX = /^[ \t]+\S/
71
+ // Indentation does not make a literal paragraph out of a list item, a table
72
+ // cell or a description list: Asciidoctor still parses those, so their links
73
+ // are real. Verified against @asciidoctor/core, marker by marker (-, *, **,
74
+ // ., .., 1., a., |, term::).
75
+ const INDENTED_PARSED_RX = /^[ \t]+(?:[*.-]+[ \t]|\d+\.[ \t]|[a-zA-Z]\.[ \t]|\||\S.*::(?:[ \t]|$))/
76
+ // Lines a block can start after, so an indented line that follows one opens a
77
+ // literal paragraph: a list continuation (+), a block attribute list
78
+ // ([source,yaml]) or a block title (.Title). A blank line and the close of a
79
+ // delimited block do the same and are handled in the scan loop.
80
+ const BLOCK_START_RX = /^(?:\+|\[.*\]|\.\S.*)$/
81
+
63
82
  // A delimiter run, plus the info string a fence may carry. Comment blocks
64
83
  // (////) come first in the alternation so a //// line is not mistaken for the
65
84
  // start of a line comment.
@@ -108,22 +127,48 @@ function closesBlock (delimiter, open) {
108
127
  return delimiter.char === open.char && delimiter.length === open.length && !delimiter.info
109
128
  }
110
129
 
130
+ /**
131
+ * True when an indented line at the start of a block opens a literal
132
+ * paragraph, rather than continuing a construct Asciidoctor still parses.
133
+ */
134
+ function opensLiteralParagraph (line) {
135
+ return INDENTED_RX.test(line) && !INDENTED_PARSED_RX.test(line)
136
+ }
137
+
111
138
  function scanContentUrls (content) {
112
139
  const matches = []
113
140
  const lines = content.split('\n')
114
141
  let offset = 0
115
142
  let openDelimiter = null
143
+ // A literal paragraph runs from the indented line that opened it to the next
144
+ // blank line, and takes any unindented lines in between with it.
145
+ let inLiteralParagraph = false
146
+ // A block can start at the top of the file, and again after every line that
147
+ // ended the last one.
148
+ let atBlockStart = true
116
149
  for (const rawLine of lines) {
117
150
  const line = rawLine.endsWith('\r') ? rawLine.slice(0, -1) : rawLine
118
151
  const delimiter = blockDelimiter(line)
119
152
  if (openDelimiter) {
120
153
  // Inside a block, only its own matching delimiter gets out. Anything
121
154
  // else on this line is content and is never scanned.
122
- if (delimiter && closesBlock(delimiter, openDelimiter)) openDelimiter = null
155
+ if (delimiter && closesBlock(delimiter, openDelimiter)) {
156
+ openDelimiter = null
157
+ atBlockStart = true
158
+ }
123
159
  } else if (delimiter) {
124
160
  openDelimiter = delimiter
125
- } else if (!LINE_COMMENT_RX.test(line)) {
126
- scanLine(line, offset, matches, content)
161
+ inLiteralParagraph = false
162
+ } else {
163
+ const blank = !line.trim()
164
+ if (inLiteralParagraph) {
165
+ if (blank) inLiteralParagraph = false
166
+ } else if (atBlockStart && opensLiteralParagraph(line)) {
167
+ inLiteralParagraph = true
168
+ } else if (!LINE_COMMENT_RX.test(line)) {
169
+ scanLine(line, offset, matches, content)
170
+ }
171
+ atBlockStart = blank || BLOCK_START_RX.test(line)
127
172
  }
128
173
  offset += rawLine.length + 1
129
174
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redpanda-data/docs-extensions-and-macros",
3
- "version": "5.37.0",
3
+ "version": "5.37.1",
4
4
  "description": "Antora extensions and macros developed for Redpanda documentation.",
5
5
  "keywords": [
6
6
  "antora",