mirror of
https://github.com/litruv/Docs-Viewer.git
synced 2026-07-24 02:36:07 +10:00
Enhance documentation viewer with code highlighting and update metadata handling
This commit is contained in:
3
docs/.obsidian/core-plugins.json
vendored
3
docs/.obsidian/core-plugins.json
vendored
@@ -26,5 +26,6 @@
|
|||||||
"workspaces": false,
|
"workspaces": false,
|
||||||
"file-recovery": true,
|
"file-recovery": true,
|
||||||
"publish": false,
|
"publish": false,
|
||||||
"sync": false
|
"sync": false,
|
||||||
|
"webviewer": false
|
||||||
}
|
}
|
||||||
20
docs/.obsidian/workspace.json
vendored
20
docs/.obsidian/workspace.json
vendored
@@ -20,8 +20,21 @@
|
|||||||
"icon": "lucide-file",
|
"icon": "lucide-file",
|
||||||
"title": "DeepImpact"
|
"title": "DeepImpact"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "7899dc85e8880db2",
|
||||||
|
"type": "leaf",
|
||||||
|
"state": {
|
||||||
|
"type": "release-notes",
|
||||||
|
"state": {
|
||||||
|
"currentVersion": "1.8.4"
|
||||||
|
},
|
||||||
|
"icon": "lucide-book-up",
|
||||||
|
"title": "Release Notes 1.8.4"
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
|
],
|
||||||
|
"currentTab": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"direction": "vertical"
|
"direction": "vertical"
|
||||||
@@ -40,7 +53,8 @@
|
|||||||
"state": {
|
"state": {
|
||||||
"type": "file-explorer",
|
"type": "file-explorer",
|
||||||
"state": {
|
"state": {
|
||||||
"sortOrder": "alphabetical"
|
"sortOrder": "alphabetical",
|
||||||
|
"autoReveal": false
|
||||||
},
|
},
|
||||||
"icon": "lucide-folder-closed",
|
"icon": "lucide-folder-closed",
|
||||||
"title": "Files"
|
"title": "Files"
|
||||||
@@ -162,7 +176,7 @@
|
|||||||
"command-palette:Open command palette": false
|
"command-palette:Open command palette": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"active": "1eda716d35acafe8",
|
"active": "7899dc85e8880db2",
|
||||||
"lastOpenFiles": [
|
"lastOpenFiles": [
|
||||||
"index.md",
|
"index.md",
|
||||||
"DeepImpact.md",
|
"DeepImpact.md",
|
||||||
|
|||||||
BIN
docs/Nullframe Discord.pdf
Normal file
BIN
docs/Nullframe Discord.pdf
Normal file
Binary file not shown.
@@ -12,3 +12,6 @@ Here you'll find documentation for various tools and projects I've created. Sele
|
|||||||
If you need help or have questions:
|
If you need help or have questions:
|
||||||
- Open an issue on [GitHub](https://github.com/Litruv)
|
- Open an issue on [GitHub](https://github.com/Litruv)
|
||||||
- Join the discussion on [Discord](https://discord.gg/b8ctQBaaax)
|
- Join the discussion on [Discord](https://discord.gg/b8ctQBaaax)
|
||||||
|
|
||||||
|
|
||||||
|
asdfds
|
||||||
49
index.html
49
index.html
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
|
||||||
<title>Documentation Viewer</title>
|
<title>Litruv</title>
|
||||||
|
|
||||||
<meta name="description" content="Documentation for Litruv's tools and projects">
|
<meta name="description" content="Documentation for Litruv's tools and projects">
|
||||||
<meta property="og:type" content="article">
|
<meta property="og:type" content="article">
|
||||||
@@ -12,44 +12,10 @@
|
|||||||
<meta name="twitter:card" content="summary">
|
<meta name="twitter:card" content="summary">
|
||||||
<meta name="twitter:description" content="Documentation for Litruv's tools and projects">
|
<meta name="twitter:description" content="Documentation for Litruv's tools and projects">
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/themes/prism-tomorrow.min.css">
|
|
||||||
<link rel="stylesheet" href="styles.css">
|
<link rel="stylesheet" href="styles.css">
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.1/css/all.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.1/css/all.min.css">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/github-dark.min.css">
|
||||||
|
|
||||||
<script>
|
|
||||||
function getRandomString(length) {
|
|
||||||
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
||||||
let result = '';
|
|
||||||
for (let i = 0; i < length; i++) {
|
|
||||||
result += characters.charAt(Math.floor(Math.random() * characters.length));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function addRandomMetaTags() {
|
|
||||||
const ogTitle = document.createElement('meta');
|
|
||||||
ogTitle.setAttribute('property', 'og:title');
|
|
||||||
ogTitle.content = getRandomString(10);
|
|
||||||
document.head.appendChild(ogTitle);
|
|
||||||
|
|
||||||
const ogImage = document.createElement('meta');
|
|
||||||
ogImage.setAttribute('property', 'og:image');
|
|
||||||
ogImage.content = `https://example.com/${getRandomString(10)}.jpg`;
|
|
||||||
document.head.appendChild(ogImage);
|
|
||||||
|
|
||||||
const twitterTitle = document.createElement('meta');
|
|
||||||
twitterTitle.setAttribute('name', 'twitter:title');
|
|
||||||
twitterTitle.content = getRandomString(10);
|
|
||||||
document.head.appendChild(twitterTitle);
|
|
||||||
|
|
||||||
const twitterImage = document.createElement('meta');
|
|
||||||
twitterImage.setAttribute('name', 'twitter:image');
|
|
||||||
twitterImage.content = `https://example.com/${getRandomString(10)}.jpg`;
|
|
||||||
document.head.appendChild(twitterImage);
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', addRandomMetaTags);
|
|
||||||
</script>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
@@ -103,17 +69,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/marked@4.3.0/marked.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/marked@4.3.0/marked.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
window.addEventListener('error', function(e) {
|
hljs.highlightAll();
|
||||||
if (e.target.src && e.target.src.includes('marked.min.js')) {
|
|
||||||
const script = document.createElement('script');
|
|
||||||
script.src = 'https://cdnjs.cloudflare.com/ajax/libs/marked/4.3.0/marked.min.js';
|
|
||||||
document.body.appendChild(script);
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
</script>
|
</script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/components/prism-core.min.js"></script>
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/plugins/autoloader/prism-autoloader.min.js"></script>
|
|
||||||
<script src="index.js"></script>
|
<script src="index.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
39
index.js
39
index.js
@@ -1,3 +1,5 @@
|
|||||||
|
let originalDocTitle = document.title;
|
||||||
|
|
||||||
let markedPromise = new Promise((resolve) => {
|
let markedPromise = new Promise((resolve) => {
|
||||||
if (typeof marked !== 'undefined') {
|
if (typeof marked !== 'undefined') {
|
||||||
resolve(marked);
|
resolve(marked);
|
||||||
@@ -12,6 +14,18 @@ async function initializeMarked() {
|
|||||||
const renderer = new marked.Renderer();
|
const renderer = new marked.Renderer();
|
||||||
const originalLink = renderer.link.bind(renderer);
|
const originalLink = renderer.link.bind(renderer);
|
||||||
|
|
||||||
|
renderer.code = (code, language) => {
|
||||||
|
let highlighted;
|
||||||
|
if (language && hljs.getLanguage(language)) {
|
||||||
|
highlighted = hljs.highlight(code, { language }).value;
|
||||||
|
language = language;
|
||||||
|
} else {
|
||||||
|
highlighted = hljs.highlightAuto(code).value;
|
||||||
|
language = '';
|
||||||
|
}
|
||||||
|
return `<pre class="hljs ${language ? "language-" + language : ""}"><code>${highlighted}</code></pre>`;
|
||||||
|
};
|
||||||
|
|
||||||
renderer.link = (href, title, text) => {
|
renderer.link = (href, title, text) => {
|
||||||
const isExternal = href.startsWith('http') || href.startsWith('https');
|
const isExternal = href.startsWith('http') || href.startsWith('https');
|
||||||
const attrs = isExternal ? ' target="_blank" rel="noopener noreferrer"' : '';
|
const attrs = isExternal ? ' target="_blank" rel="noopener noreferrer"' : '';
|
||||||
@@ -23,12 +37,6 @@ async function initializeMarked() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
marked.setOptions({
|
marked.setOptions({
|
||||||
highlight: function(code, lang) {
|
|
||||||
if (Prism.languages[lang]) {
|
|
||||||
return Prism.highlight(code, Prism.languages[lang], lang);
|
|
||||||
}
|
|
||||||
return code;
|
|
||||||
},
|
|
||||||
breaks: true,
|
breaks: true,
|
||||||
gfm: true,
|
gfm: true,
|
||||||
renderer: renderer
|
renderer: renderer
|
||||||
@@ -250,6 +258,9 @@ async function loadDocument(path) {
|
|||||||
|
|
||||||
const titleContent = metadata.title || (docEntry && docEntry.title) || path.split('/').pop().replace('.md', '');
|
const titleContent = metadata.title || (docEntry && docEntry.title) || path.split('/').pop().replace('.md', '');
|
||||||
|
|
||||||
|
document.title = `${originalDocTitle} / ${titleContent}`;
|
||||||
|
document.querySelector('.title-text .page-title').textContent = titleContent;
|
||||||
|
|
||||||
let processedContent = content.replace(/\[\[(.*?)\]\]/g, (match, linkText) => {
|
let processedContent = content.replace(/\[\[(.*?)\]\]/g, (match, linkText) => {
|
||||||
if (linkText.match(/\.(png|jpg|jpeg|gif|mp4|webm)$/i)) {
|
if (linkText.match(/\.(png|jpg|jpeg|gif|mp4|webm)$/i)) {
|
||||||
return match;
|
return match;
|
||||||
@@ -277,25 +288,11 @@ async function loadDocument(path) {
|
|||||||
return `\n\n\n`;
|
return `\n\n\n`;
|
||||||
});
|
});
|
||||||
|
|
||||||
document.title = `Litruv / ${titleContent}`;
|
|
||||||
document.querySelector('.title-text .page-title').textContent = titleContent;
|
document.querySelector('.title-text .page-title').textContent = titleContent;
|
||||||
|
|
||||||
// Update Twitter meta tags dynamically
|
|
||||||
document.querySelector('meta[name="twitter:title"]').setAttribute('content', titleContent);
|
|
||||||
document.querySelector('meta[name="twitter:description"]').setAttribute('content', metadata.description || `Documentation for ${titleContent}`);
|
|
||||||
if (metadata.image) {
|
|
||||||
const imageUrl = `${window.location.origin}${window.location.pathname}${basePath}/images/${metadata.image}`;
|
|
||||||
let twitterImageMeta = document.querySelector('meta[name="twitter:image"]');
|
|
||||||
if (!twitterImageMeta) {
|
|
||||||
twitterImageMeta = document.createElement('meta');
|
|
||||||
twitterImageMeta.setAttribute('name', 'twitter:image');
|
|
||||||
document.head.appendChild(twitterImageMeta);
|
|
||||||
}
|
|
||||||
twitterImageMeta.setAttribute('content', imageUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
documentContent.className = 'markdown-content';
|
documentContent.className = 'markdown-content';
|
||||||
documentContent.innerHTML = marked.parse(finalContent);
|
documentContent.innerHTML = marked.parse(finalContent);
|
||||||
|
hljs.highlightAll();
|
||||||
|
|
||||||
documentOutline.innerHTML = '';
|
documentOutline.innerHTML = '';
|
||||||
const headings = documentContent.querySelectorAll('h1, h2, h3, h4, h5, h6');
|
const headings = documentContent.querySelectorAll('h1, h2, h3, h4, h5, h6');
|
||||||
|
|||||||
106
styles.css
106
styles.css
@@ -421,6 +421,112 @@ social-links a:hover {
|
|||||||
border-bottom: 1px solid var(--ifm-border-color);
|
border-bottom: 1px solid var(--ifm-border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.markdown-content pre {
|
||||||
|
background-color: var(--ifm-background-surface-color);
|
||||||
|
border: 1px solid var(--ifm-border-color);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 1rem;
|
||||||
|
margin: 1rem 0;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown-content pre code {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
padding: 0;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Override Prism styles to match theme */
|
||||||
|
pre[class*="language-"] {
|
||||||
|
background: var(--ifm-background-surface-color) !important;
|
||||||
|
margin: 1rem 0 !important;
|
||||||
|
padding: 1rem !important;
|
||||||
|
border-radius: 8px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
code[class*="language-"] {
|
||||||
|
background: none !important;
|
||||||
|
text-shadow: none !important;
|
||||||
|
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Code block styles */
|
||||||
|
.markdown-content pre[class*="language-"] {
|
||||||
|
background: var(--ifm-background-surface-color) !important;
|
||||||
|
border: 1px solid var(--ifm-border-color);
|
||||||
|
margin: 1.5rem 0;
|
||||||
|
padding: 1rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown-content code[class*="language-"] {
|
||||||
|
background: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
||||||
|
font-size: 0.9em;
|
||||||
|
line-height: 1.5;
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Discord-like code block styles */
|
||||||
|
pre[class*="language-"] {
|
||||||
|
background-color: #2f3136 !important;
|
||||||
|
color: #b9bbbe !important;
|
||||||
|
border: none;
|
||||||
|
padding: 1rem !important;
|
||||||
|
border-radius: 5px !important;
|
||||||
|
overflow-x: auto;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
code[class*="language-"] {
|
||||||
|
background: none !important;
|
||||||
|
color: inherit !important;
|
||||||
|
font-family: 'Roboto Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Optionally, if you use Prism's toolbar, adjust its colors similar to Discord */
|
||||||
|
div.code-toolbar > .toolbar > .toolbar-item > button {
|
||||||
|
background: #2f3136;
|
||||||
|
color: #b9bbbe;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
div.code-toolbar > .toolbar > .toolbar-item > button:hover {
|
||||||
|
background: #40444b;
|
||||||
|
color: #dcddde;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Toolbar styles */
|
||||||
|
div.code-toolbar > .toolbar {
|
||||||
|
opacity: 0;
|
||||||
|
top: 0.5em;
|
||||||
|
right: 0.5em;
|
||||||
|
transition: opacity 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.code-toolbar:hover > .toolbar {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.code-toolbar > .toolbar > .toolbar-item > button {
|
||||||
|
background: var(--ifm-background-surface-color);
|
||||||
|
color: var(--ifm-color-content);
|
||||||
|
border: 1px solid var(--ifm-border-color);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 0.4em 0.8em;
|
||||||
|
font-size: 0.8em;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.code-toolbar > .toolbar > .toolbar-item > button:hover {
|
||||||
|
background: var(--ifm-color-primary);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
.error {
|
.error {
|
||||||
color: #ff6b6b;
|
color: #ff6b6b;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
|
|||||||
Reference in New Issue
Block a user