@docsector/docsector-reader 0.7.2 → 0.7.3
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.
- package/README.md +9 -2
- package/bin/docsector.js +1 -1
- package/package.json +1 -1
- package/src/components/DPageBar.vue +8 -1
- package/src/quasar.factory.js +30 -7
package/README.md
CHANGED
|
@@ -18,13 +18,19 @@ Transform Markdown content into beautiful, navigable documentation sites — wit
|
|
|
18
18
|
|
|
19
19
|
---
|
|
20
20
|
|
|
21
|
+
## 🤖 AI-Friendly Features
|
|
22
|
+
|
|
23
|
+
- 📋 **Copy Page** — One-click button copies the current page as raw Markdown, ready to paste into LLMs
|
|
24
|
+
- 📄 **View as Markdown** — Open any page as plain text by appending `.md` to the URL, with locale support (`?lang=`)
|
|
25
|
+
- 🕷️ **LLM Bot Detection** — Automatically serves raw Markdown to known AI crawlers (GPTBot, ClaudeBot, PerplexityBot, GrokBot, and others)
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
21
29
|
## ✨ Features
|
|
22
30
|
|
|
23
31
|
- 📝 **Markdown Rendering** — Write docs in Markdown, rendered with syntax highlighting (Prism.js)
|
|
24
32
|
- 🧩 **Mermaid Diagrams** — Native support for fenced ` ```mermaid ` blocks, with automatic dark/light theme switching
|
|
25
33
|
- 🚨 **GitHub-Style Alerts** — Native support for `[!NOTE]`, `[!TIP]`, `[!IMPORTANT]`, `[!WARNING]`, and `[!CAUTION]`
|
|
26
|
-
- 🤖 **AI-Friendly** — "Copy page" button copies raw Markdown for LLMs; "View as Markdown" opens any page as plain text via `.md` URL suffix
|
|
27
|
-
- 📅 **Last Updated Date** — Automatic per-page "last updated" date from git commit history, locale-formatted
|
|
28
34
|
- 🌍 **Internationalization (i18n)** — Multi-language support with HJSON locale files and per-page translations
|
|
29
35
|
- 🌗 **Dark/Light Mode** — Automatic theme switching with Quasar Dark Plugin
|
|
30
36
|
- 🔗 **Anchor Navigation** — Right-side Table of Contents tree with scroll tracking
|
|
@@ -32,6 +38,7 @@ Transform Markdown content into beautiful, navigable documentation sites — wit
|
|
|
32
38
|
- 📱 **Responsive** — Mobile-friendly with collapsible sidebar and drawers
|
|
33
39
|
- 🏷️ **Status Badges** — Mark pages as `done`, `draft`, or `empty` with visual indicators
|
|
34
40
|
- ✏️ **Edit on GitHub** — Direct links to edit pages on your repository
|
|
41
|
+
- 📅 **Last Updated Date** — Automatic per-page "last updated" date from git commit history, locale-formatted
|
|
35
42
|
- 📊 **Translation Progress** — Automatic translation percentage based on header coverage
|
|
36
43
|
- ⚙️ **Single Config File** — Customize branding, links, and languages via `docsector.config.js`
|
|
37
44
|
|
package/bin/docsector.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docsector/docsector-reader",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.3",
|
|
4
4
|
"description": "A documentation rendering engine built with Vue 3, Quasar v2 and Vite. Transform Markdown into beautiful, navigable documentation sites.",
|
|
5
5
|
"productName": "Docsector Reader",
|
|
6
6
|
"author": "Rodrigo de Araujo Vieira",
|
|
@@ -73,7 +73,7 @@ const viewAsMarkdown = () => {
|
|
|
73
73
|
<template>
|
|
74
74
|
<div class="d-page-bar">
|
|
75
75
|
<span v-if="formattedDate" class="d-page-bar__date">
|
|
76
|
-
{{ t('page.lastUpdated') }}: {{ formattedDate }}
|
|
76
|
+
{{ t('page.lastUpdated') }}: <br class="d-page-bar__date-break"> {{ formattedDate }}
|
|
77
77
|
</span>
|
|
78
78
|
<span v-else class="d-page-bar__date"></span>
|
|
79
79
|
|
|
@@ -126,10 +126,17 @@ const viewAsMarkdown = () => {
|
|
|
126
126
|
font-size: 0.8rem
|
|
127
127
|
opacity: 0.6
|
|
128
128
|
|
|
129
|
+
&__date-break
|
|
130
|
+
display: none
|
|
131
|
+
|
|
129
132
|
&__actions
|
|
130
133
|
font-size: 0.75rem
|
|
131
134
|
|
|
132
135
|
body.body--dark
|
|
133
136
|
.d-page-bar__date
|
|
134
137
|
color: rgba(255, 255, 255, 0.7)
|
|
138
|
+
|
|
139
|
+
@media (max-width: 376px)
|
|
140
|
+
.d-page-bar__date-break
|
|
141
|
+
display: block
|
|
135
142
|
</style>
|
package/src/quasar.factory.js
CHANGED
|
@@ -331,6 +331,9 @@ function createMarkdownEndpointPlugin (projectRoot) {
|
|
|
331
331
|
return null
|
|
332
332
|
}
|
|
333
333
|
|
|
334
|
+
// LLM bot user-agent patterns
|
|
335
|
+
const LLM_BOT_PATTERN = /GPTBot|ChatGPT-User|OAI-SearchBot|ClaudeBot|Claude-User|Claude-SearchBot|anthropic-ai|Google-Extended|Gemini-Deep-Research|PerplexityBot|Perplexity-User|Bytespider|CCBot|Meta-ExternalAgent|FacebookBot|Amazonbot|Applebot-Extended|cohere-ai|DuckAssistBot|GrokBot|AI2Bot|YouBot|PetalBot/i
|
|
336
|
+
|
|
334
337
|
return {
|
|
335
338
|
name: 'docsector-markdown-endpoint',
|
|
336
339
|
|
|
@@ -349,15 +352,35 @@ function createMarkdownEndpointPlugin (projectRoot) {
|
|
|
349
352
|
|
|
350
353
|
server.middlewares.use((req, res, next) => {
|
|
351
354
|
const url = new URL(req.url, 'http://localhost')
|
|
352
|
-
if (!url.pathname.endsWith('.md')) return next()
|
|
353
355
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
356
|
+
// Explicit .md request
|
|
357
|
+
if (url.pathname.endsWith('.md')) {
|
|
358
|
+
const lang = url.searchParams.get('lang') || defaultLang
|
|
359
|
+
const file = resolveMarkdownFile(url.pathname, lang)
|
|
360
|
+
if (!file) return next()
|
|
361
|
+
|
|
362
|
+
const content = readFileSync(file, 'utf-8')
|
|
363
|
+
res.setHeader('Content-Type', 'text/plain; charset=utf-8')
|
|
364
|
+
res.end(content)
|
|
365
|
+
return
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// Auto-serve markdown to LLM bot crawlers
|
|
369
|
+
const ua = req.headers['user-agent'] || ''
|
|
370
|
+
if (LLM_BOT_PATTERN.test(ua)) {
|
|
371
|
+
const lang = url.searchParams.get('lang') || defaultLang
|
|
372
|
+
// Try appending /overview as the default subpage
|
|
373
|
+
const mdPath = url.pathname.replace(/\/$/, '') + '/overview.md'
|
|
374
|
+
const file = resolveMarkdownFile(mdPath, lang)
|
|
375
|
+
if (file) {
|
|
376
|
+
const content = readFileSync(file, 'utf-8')
|
|
377
|
+
res.setHeader('Content-Type', 'text/plain; charset=utf-8')
|
|
378
|
+
res.end(content)
|
|
379
|
+
return
|
|
380
|
+
}
|
|
381
|
+
}
|
|
357
382
|
|
|
358
|
-
|
|
359
|
-
res.setHeader('Content-Type', 'text/plain; charset=utf-8')
|
|
360
|
-
res.end(content)
|
|
383
|
+
next()
|
|
361
384
|
})
|
|
362
385
|
},
|
|
363
386
|
|