Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 63 additions & 87 deletions assets/highlight.css
Original file line number Diff line number Diff line change
@@ -1,103 +1,79 @@
:root {
--code-fg: #BD976A;
--keyword: #4D9375;
--variable: #BD976A;
--comment: #758575DD;
--operator: #666666;
--string: #C98A7D;
--number: #4C9A91;
--function: #CB7676;
--bracket: #93aa9e;
/* Light Mode Syntax Tokens (GitHub Light inspired) */
--hl-fg: #24292f;
--hl-keyword: #cf222e; /* Red */
--hl-variable: #953800; /* Orange */
--hl-comment: #6e7781; /* Gray */
--hl-operator: #24292f; /* Dark Gray */
--hl-string: #0a3069; /* Dark Blue */
--hl-number: #0550ae; /* Blue */
--hl-function: #8250df; /* Purple */
--hl-bracket: #24292f;
--hl-constant: #0550ae;
}

@media (prefers-color-scheme: dark) {
:root {
/* Dark Mode Syntax Tokens (GitHub Dark inspired) */
--hl-fg: #c9d1d9;
--hl-keyword: #ff7b72; /* Coral */
--hl-variable: #ffa657; /* Orange */
--hl-comment: #8b949e; /* Gray */
--hl-operator: #c9d1d9; /* Light Gray */
--hl-string: #a5d6ff; /* Light Blue */
--hl-number: #79c0ff; /* Blue */
--hl-function: #d2a8ff; /* Purple */
--hl-bracket: #c9d1d9;
--hl-constant: #79c0ff;
}
}

code {
color: var(--code-fg);
color: var(--hl-fg);
}

code.zig, code.javascript, code.c, code.cpp, code.zon, code.go{
color: var(--code-fg);
.keyword, .keyword_modifier, .type_builtin, .keyword_type, .keyword_return, .keyword_conditional, .keyword_repeat, .keyword_operator, .constant_builtin, .keyword_exception, .type{
color: var(--keyword);
}
.variable, .function_builtin{
color: var(--variable);
}
.comment{
color: var(--comment);
}
.operator, .punctuation{
color: var(--operator);
}
.string, .character{
color: var(--string);
}
.number{
color: var(--number);
}
.keyword_function, .punctuation_delimiter, .function{
color: var(--function);
}
.punctuation_bracket{
color: var(--bracket);
}
/* General Syntax Highlighting */
.keyword, .keyword_modifier, .type_builtin, .keyword_type, .keyword_return, .keyword_conditional, .keyword_repeat, .keyword_operator, .keyword_exception, .type, .storage, .tag {
color: var(--hl-keyword);
}

code.conf{
color: var(--code-fg);
.function{
color: var(--function);
}
.punctuation_bracket{
color: var(--bracket);
}
.variable, .function_builtin, .attr-name {
color: var(--hl-variable);
}

code.diff{
color: var(--code-fg);
.addition, .string{
color: #4D9375;
}
.deletion, .keyword{
color: #CB7676;
}
.comment, .prolog, .doctype, .cdata {
color: var(--hl-comment);
font-style: italic;
}

/* TODO 分词器太烂了 */
code.bash {
color: var(--code-fg);
.comment {
color: var(--comment);
font-style: italic;
}
span.operator {
color: var(--operator);
}
.constant {
color: var(--number);
}
.string {
color: var(--string);
}
.function {
color: var(--function);
}
.operator, .punctuation, .punctuation_delimiter {
color: var(--hl-operator);
}

code.json{
color: var(--code-fg);
.constant_builtin{
color: var(--keyword);
}
span.string_special_key{
color: var(--string)
}
.string{
color: var(--function)
}
.string, .character, .attr-value {
color: var(--hl-string);
}

@media (prefers-color-scheme: light) {
code{
filter: brightness(0.8) contrast(1.5);
}
}
.number, .constant_builtin, .constant, .boolean {
color: var(--hl-number);
}

.function, .keyword_function, .method {
color: var(--hl-function);
}

.punctuation_bracket, .bracket {
color: var(--hl-bracket);
}

/* Language Specific Overrides if needed */
code.diff .addition { color: #1a7f37; } /* Green */
code.diff .deletion { color: #cf222e; } /* Red */

@media (prefers-color-scheme: dark) {
code.diff .addition { color: #3fb950; }
code.diff .deletion { color: #ff7b72; }
}

/* Bash specific adjustments */
code.bash .constant { color: var(--hl-variable); }
4 changes: 4 additions & 0 deletions assets/icons/search.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 0 additions & 5 deletions assets/index.css

This file was deleted.

47 changes: 47 additions & 0 deletions assets/js/code-block.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
document.addEventListener('DOMContentLoaded', () => {
const codeBlocks = document.querySelectorAll('pre code');

codeBlocks.forEach((code) => {
const preElement = code.parentNode;
if (preElement.tagName !== 'PRE') return;

const codeContainer = document.createElement('div');
codeContainer.className = 'code-block-container';
preElement.parentNode.insertBefore(codeContainer, preElement);
codeContainer.appendChild(preElement);

const copyButton = document.createElement('button');
copyButton.className = 'copy-code-btn';
copyButton.setAttribute('aria-label', 'Copy code to clipboard');
copyButton.setAttribute('title', 'Copy code');
copyButton.innerHTML = '<svg viewBox="0 0 24 24" width="16" height="16" stroke="currentColor" stroke-width="2" fill="none"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>';
codeContainer.appendChild(copyButton);

copyButton.addEventListener('click', () => {
const codeText = code.textContent;
navigator.clipboard.writeText(codeText).then(() => {
copyButton.classList.add('copied');
setTimeout(() => { copyButton.classList.remove('copied'); }, 2000);
}).catch(err => {
console.error('无法复制到剪贴板:', err);
});
});

const codeLines = code.textContent.split(/\r?\n/);
const hasTrailingEmptyLine = codeLines.length > 0 && codeLines[codeLines.length - 1].trim() === '';
if (hasTrailingEmptyLine) {
codeLines.pop();
}

if (codeLines.length > 0) {
const lineNumbersContainer = document.createElement('div');
lineNumbersContainer.className = 'line-numbers';
for (let i = 1; i <= codeLines.length; i++) {
const lineNumber = document.createElement('span');
lineNumber.innerText = i;
lineNumbersContainer.appendChild(lineNumber);
}
preElement.insertBefore(lineNumbersContainer, code);
}
});
});
60 changes: 60 additions & 0 deletions assets/js/toc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
document.addEventListener('DOMContentLoaded', () => {
const tocLinks = document.querySelectorAll('.toc-sticky a');

// Find all headings within main-content
// We query all headings first, then filter/map to find the actual anchor ID
const rawHeadings = document.querySelectorAll('.main-content h1, .main-content h2, .main-content h3, .main-content h4, .main-content h5, .main-content h6');

const headings = Array.from(rawHeadings)
.map(h => ({
element: h,
id: h.id || h.parentElement?.id || h.querySelector('[id]')?.id,
}))
.filter(h => h.id);

if (tocLinks.length === 0 || headings.length === 0) return;

const onScroll = () => {
let currentId = null;
const scrollPosition = window.scrollY + 120; // Offset for header + padding

// Find the last heading that is above the current scroll position
for (const h of headings) {
if (h.element.offsetTop <= scrollPosition) {
currentId = h.id;
} else {
break; // Since headings are in order, we can stop
}
}

if (currentId) {
tocLinks.forEach(link => {
link.classList.remove('active');
const href = link.getAttribute('href');
if (href === `#${currentId}`) {
link.classList.add('active');
}
});
} else {
// If no header is "current" (e.g. at very top), highlight the first one
if (window.scrollY < 100 && tocLinks.length > 0) {
tocLinks.forEach(link => link.classList.remove('active'));
tocLinks[0].classList.add('active');
}
}
};

// Throttle scroll event slightly for performance
let ticking = false;
window.addEventListener('scroll', () => {
if (!ticking) {
window.requestAnimationFrame(() => {
onScroll();
ticking = false;
});
ticking = true;
}
}, { passive: true });

onScroll(); // Initial check
});
Loading