@redpanda-data/docs-extensions-and-macros 4.15.3 → 4.15.5
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.
|
@@ -5,27 +5,65 @@
|
|
|
5
5
|
*
|
|
6
6
|
* USAGE:
|
|
7
7
|
* :page-faq-1-question: How do I install Redpanda?
|
|
8
|
-
* :page-faq-1-answer: Download from redpanda.com and run the installer.
|
|
8
|
+
* :page-faq-1-answer: Download from redpanda.com and run the installer. See our xref:get-started:intro.adoc[quickstart guide] for details.
|
|
9
9
|
* :page-faq-1-anchor: #installation (optional - links to section)
|
|
10
10
|
*
|
|
11
11
|
* :page-faq-2-question: What are the system requirements?
|
|
12
|
-
* :page-faq-2-answer: You need at least 2GB RAM and 2 CPU cores.
|
|
12
|
+
* :page-faq-2-answer: You need at least 2GB RAM and 2 CPU cores for production. For development, xref:deploy:docker-compose.adoc[use Docker Compose].
|
|
13
13
|
* :page-faq-2-anchor: #requirements
|
|
14
14
|
*
|
|
15
15
|
* The extension:
|
|
16
16
|
* - Generates schema.org FAQPage JSON-LD in <head>
|
|
17
17
|
* - Supports multiple FAQs numbered sequentially (1, 2, 3...)
|
|
18
18
|
* - Anchor is optional and adds URL to the FAQ question
|
|
19
|
-
* - Writers can
|
|
19
|
+
* - Writers can use AsciiDoc xrefs in answers - they're resolved to full URLs
|
|
20
|
+
* - Xrefs are converted to "link text (URL)" format in JSON-LD
|
|
20
21
|
*/
|
|
21
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Resolve xrefs in text to full URLs
|
|
25
|
+
* @param {string} text - Text containing xref macros
|
|
26
|
+
* @param {Object} currentPage - Current page context
|
|
27
|
+
* @param {Object} contentCatalog - Antora content catalog
|
|
28
|
+
* @param {string} siteUrl - Base site URL
|
|
29
|
+
* @param {Object} logger - Logger instance
|
|
30
|
+
* @returns {string} Text with xrefs resolved to plain text + URLs
|
|
31
|
+
*/
|
|
32
|
+
function resolveXrefs(text, currentPage, contentCatalog, siteUrl, logger) {
|
|
33
|
+
// Match xref:target[link text] pattern
|
|
34
|
+
const xrefPattern = /xref:([^\[]+)\[([^\]]+)\]/g
|
|
35
|
+
|
|
36
|
+
return text.replace(xrefPattern, (match, target, linkText) => {
|
|
37
|
+
try {
|
|
38
|
+
// Resolve the resource using Antora's content catalog
|
|
39
|
+
// This uses Antora's standard API for resolving page references
|
|
40
|
+
const resource = contentCatalog.resolveResource(target, currentPage.src, 'page')
|
|
41
|
+
|
|
42
|
+
if (resource && resource.pub && resource.pub.url) {
|
|
43
|
+
const fullUrl = siteUrl ? `${siteUrl}${resource.pub.url}` : `https://docs.redpanda.com${resource.pub.url}`
|
|
44
|
+
return `${linkText} (${fullUrl})`
|
|
45
|
+
} else {
|
|
46
|
+
// Xref couldn't be resolved (page doesn't exist or isn't loaded yet)
|
|
47
|
+
// Fall back to just the link text - this is expected for cross-component refs in local builds
|
|
48
|
+
return linkText
|
|
49
|
+
}
|
|
50
|
+
} catch (error) {
|
|
51
|
+
logger.warn(`FAQ xref resolution error for ${target}: ${error.message}`)
|
|
52
|
+
return linkText // Fallback to just the link text
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
}
|
|
56
|
+
|
|
22
57
|
/**
|
|
23
58
|
* Extract FAQ entries from page attributes
|
|
24
59
|
* @param {Object} attributes - Page attributes object
|
|
60
|
+
* @param {Object} page - Current page object
|
|
61
|
+
* @param {Object} contentCatalog - Antora content catalog
|
|
62
|
+
* @param {string} siteUrl - Base site URL
|
|
25
63
|
* @param {Object} logger - Logger instance
|
|
26
64
|
* @returns {Array<{question: string, answer: string, anchor?: string}>}
|
|
27
65
|
*/
|
|
28
|
-
function extractFaqs(attributes, logger) {
|
|
66
|
+
function extractFaqs(attributes, page, contentCatalog, siteUrl, logger) {
|
|
29
67
|
const faqs = []
|
|
30
68
|
const faqNumbers = new Set()
|
|
31
69
|
|
|
@@ -58,9 +96,12 @@ function extractFaqs(attributes, logger) {
|
|
|
58
96
|
return
|
|
59
97
|
}
|
|
60
98
|
|
|
99
|
+
// Resolve any xrefs in the answer text
|
|
100
|
+
const resolvedAnswer = resolveXrefs(answer.trim(), page, contentCatalog, siteUrl, logger)
|
|
101
|
+
|
|
61
102
|
const faq = {
|
|
62
103
|
question: question.trim(),
|
|
63
|
-
answer:
|
|
104
|
+
answer: resolvedAnswer
|
|
64
105
|
}
|
|
65
106
|
|
|
66
107
|
if (anchor) {
|
|
@@ -115,35 +156,26 @@ module.exports.register = function () {
|
|
|
115
156
|
|
|
116
157
|
this.on('documentsConverted', ({ contentCatalog }) => {
|
|
117
158
|
const pages = contentCatalog.getPages()
|
|
159
|
+
const siteUrl = playbook?.site?.url || ''
|
|
118
160
|
let processedCount = 0
|
|
119
161
|
let totalFaqs = 0
|
|
120
|
-
const siteUrl = playbook?.site?.url || 'https://docs.redpanda.com'
|
|
121
162
|
|
|
122
163
|
pages.forEach(page => {
|
|
123
164
|
const attributes = page.asciidoc?.attributes
|
|
124
165
|
if (!attributes) return
|
|
125
166
|
|
|
126
|
-
// Extract FAQs from attributes
|
|
127
|
-
const faqs = extractFaqs(attributes, logger)
|
|
167
|
+
// Extract FAQs from attributes and resolve any xrefs
|
|
168
|
+
const faqs = extractFaqs(attributes, page, contentCatalog, siteUrl, logger)
|
|
128
169
|
|
|
129
170
|
if (faqs.length === 0) return
|
|
130
171
|
|
|
131
|
-
//
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// Generate FAQPage JSON-LD
|
|
138
|
-
const faqJsonLd = generateFaqJsonLd(faqs, baseUrl)
|
|
139
|
-
|
|
140
|
-
// Store as JSON string in page attribute for UI template
|
|
141
|
-
attributes['page-faq-json-ld'] = JSON.stringify(faqJsonLd, null, 2)
|
|
172
|
+
// Store structured FAQ data as JSON for UI template to format
|
|
173
|
+
// Template will generate the JSON-LD structure using page.url
|
|
174
|
+
attributes['page-has-faqs'] = 'true'
|
|
175
|
+
attributes['page-faqs'] = JSON.stringify(faqs)
|
|
142
176
|
|
|
143
177
|
processedCount++
|
|
144
178
|
totalFaqs += faqs.length
|
|
145
|
-
|
|
146
|
-
logger.debug(`Added ${faqs.length} FAQs to ${page.src.relative}`)
|
|
147
179
|
})
|
|
148
180
|
|
|
149
181
|
if (processedCount > 0) {
|
|
@@ -80,11 +80,18 @@ module.exports.register = function () {
|
|
|
80
80
|
// The markdown converter applies smart typography that turns -- into — (em dash)
|
|
81
81
|
// and inserts zero-width spaces (U+200B) and other invisible Unicode characters
|
|
82
82
|
// This breaks URLs like deploy-preview-159--redpanda-documentation.netlify.app
|
|
83
|
+
// Fix URLs in parentheses (actual hrefs)
|
|
83
84
|
content = content.replace(/\(https?:\/\/[^)]*[—\u200B-\u200D\uFEFF][^)]*\)/g, (match) => {
|
|
84
85
|
return match
|
|
85
86
|
.replace(/—/g, '--')
|
|
86
87
|
.replace(/[\u200B-\u200D\uFEFF]/g, '');
|
|
87
88
|
});
|
|
89
|
+
// Fix URLs in square brackets (link text)
|
|
90
|
+
content = content.replace(/\[https?:\/\/[^\]]*[—\u200B-\u200D\uFEFF][^\]]*\]/g, (match) => {
|
|
91
|
+
return match
|
|
92
|
+
.replace(/—/g, '--')
|
|
93
|
+
.replace(/[\u200B-\u200D\uFEFF]/g, '');
|
|
94
|
+
});
|
|
88
95
|
logger.debug('Fixed em dashes and invisible characters in URLs');
|
|
89
96
|
|
|
90
97
|
// Unpublish the HTML page FIRST (following unpublish-pages pattern)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redpanda-data/docs-extensions-and-macros",
|
|
3
|
-
"version": "4.15.
|
|
3
|
+
"version": "4.15.5",
|
|
4
4
|
"description": "Antora extensions and macros developed for Redpanda documentation.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"antora",
|
|
@@ -59,6 +59,7 @@
|
|
|
59
59
|
"./extensions/generate-index-data": "./extensions/generate-index-data.js",
|
|
60
60
|
"./extensions/generate-rp-connect-info": "./extensions/generate-rp-connect-info.js",
|
|
61
61
|
"./extensions/add-global-attributes": "./extensions/add-global-attributes.js",
|
|
62
|
+
"./extensions/git-full-clone": "./extensions/git-full-clone.js",
|
|
62
63
|
"./extensions/add-git-dates": "./extensions/add-git-dates.js",
|
|
63
64
|
"./extensions/add-faq-structured-data": "./extensions/add-faq-structured-data.js",
|
|
64
65
|
"./extensions/version-fetcher/set-latest-version": "./extensions/version-fetcher/set-latest-version.js",
|