Skip to content

Commit 80b3146

Browse files
committed
0.04
1 parent 6264a62 commit 80b3146

3 files changed

Lines changed: 146 additions & 0 deletions

File tree

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
(() => {
2+
function base64EncodeUtf8(text) {
3+
const bytes = new TextEncoder().encode(text);
4+
let binary = "";
5+
const chunkSize = 0x8000;
6+
for (let i = 0; i < bytes.length; i += chunkSize) {
7+
const chunk = bytes.subarray(i, i + chunkSize);
8+
binary += String.fromCharCode(...chunk);
9+
}
10+
return btoa(binary);
11+
}
12+
13+
function findCppCodeBlocks() {
14+
const selectors = [
15+
"pre > code.language-cpp",
16+
"pre > code.language-c\\+\\+",
17+
"pre > code.lang-cpp",
18+
"pre > code.lang-c\\+\\+",
19+
];
20+
return Array.from(document.querySelectorAll(selectors.join(",")));
21+
}
22+
23+
function codeBlockHasMain(code) {
24+
return /\bmain\s*\(/.test(code);
25+
}
26+
27+
function getPreElement(codeEl) {
28+
if (!codeEl) return null;
29+
const pre = codeEl.closest("pre");
30+
return pre instanceof HTMLElement ? pre : null;
31+
}
32+
33+
function getHighlightContainer(preEl) {
34+
const highlight = preEl.closest(".highlight");
35+
return (highlight instanceof HTMLElement ? highlight : preEl.parentElement) || preEl;
36+
}
37+
38+
function createButton(onClick) {
39+
const btn = document.createElement("button");
40+
btn.type = "button";
41+
btn.className = "md-clipboard online-compile-button";
42+
btn.title = "在线编译(打开 Compiler Explorer)";
43+
btn.setAttribute("aria-label", btn.title);
44+
btn.addEventListener("click", (e) => {
45+
e.preventDefault();
46+
e.stopPropagation();
47+
onClick();
48+
});
49+
btn.textContent = "在线编译";
50+
return btn;
51+
}
52+
53+
function buildCompilerExplorerUrl(source) {
54+
const clientState = {
55+
sessions: [
56+
{
57+
id: 1,
58+
language: "c++",
59+
source,
60+
compilers: [],
61+
executors: [
62+
{
63+
compiler: {
64+
id: "clang_trunk",
65+
libs: [],
66+
options: "-std=c++23 -O2",
67+
},
68+
},
69+
],
70+
},
71+
],
72+
};
73+
74+
const json = JSON.stringify(clientState);
75+
const b64 = base64EncodeUtf8(json);
76+
const encoded = encodeURIComponent(b64);
77+
return `https://godbolt.org/clientstate/${encoded}`;
78+
}
79+
80+
function addButtons() {
81+
const blocks = findCppCodeBlocks();
82+
for (const codeEl of blocks) {
83+
const preEl = getPreElement(codeEl);
84+
if (!preEl) continue;
85+
86+
const container = getHighlightContainer(preEl);
87+
if (container.querySelector(".online-compile-button")) continue;
88+
89+
const code = (codeEl.textContent || "").trim();
90+
if (!code) continue;
91+
92+
const btn = createButton(() => {
93+
const url = buildCompilerExplorerUrl(code);
94+
window.open(url, "_blank", "noopener,noreferrer");
95+
});
96+
97+
if (!codeBlockHasMain(code)) {
98+
btn.classList.add("online-compile-button--no-main");
99+
btn.title = "在线编译(片段可能需要补全 main)";
100+
btn.setAttribute("aria-label", btn.title);
101+
}
102+
103+
container.appendChild(btn);
104+
container.classList.add("online-compile-container");
105+
}
106+
}
107+
108+
function onReady(fn) {
109+
if (document.readyState === "loading") {
110+
document.addEventListener("DOMContentLoaded", fn, { once: true });
111+
} else {
112+
fn();
113+
}
114+
}
115+
116+
onReady(() => {
117+
addButtons();
118+
119+
const observer = new MutationObserver(() => addButtons());
120+
observer.observe(document.body, { childList: true, subtree: true });
121+
});
122+
})();
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
.online-compile-container {
2+
position: relative;
3+
}
4+
5+
.online-compile-button {
6+
position: absolute;
7+
top: 0.4rem;
8+
right: 3rem;
9+
z-index: 3;
10+
padding: 0.25rem 0.5rem;
11+
font-size: 0.7rem;
12+
line-height: 1.1;
13+
border-radius: 0.4rem;
14+
}
15+
16+
.online-compile-button--no-main {
17+
opacity: 0.85;
18+
}

mkdocs.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ markdown_extensions:
5353
- toc:
5454
permalink: true
5555

56+
extra_javascript:
57+
- assets/javascripts/online-compile.js
58+
59+
extra_css:
60+
- assets/stylesheets/online-compile.css
61+
5662
nav:
5763
- 首页: index.md
5864
- C++ 基础:

0 commit comments

Comments
 (0)