Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:16:40 +08:00
commit f125e90b9f
370 changed files with 67769 additions and 0 deletions

View File

@@ -0,0 +1,105 @@
/**
* Diagram Capture Script
* Converts HTML diagrams to high-resolution PNGs using Playwright
*
* Usage:
* node capture-diagrams.js [html-file] [output-png]
* node capture-diagrams.js # Captures all diagrams in current directory
*
* Prerequisites:
* npm install playwright
* npx playwright install chromium
*/
const { chromium } = require('playwright');
const path = require('path');
const fs = require('fs');
// Configuration
const CONFIG = {
deviceScaleFactor: 2, // 2x for retina quality
selector: '.diagram-container', // Default container selector
};
/**
* Capture a single HTML file to PNG
*/
async function captureScreenshot(htmlPath, pngPath, selector = CONFIG.selector) {
const browser = await chromium.launch();
const context = await browser.newContext({
deviceScaleFactor: CONFIG.deviceScaleFactor,
});
const page = await context.newPage();
const absoluteHtmlPath = path.resolve(htmlPath);
console.log(`Capturing ${htmlPath}...`);
await page.goto(`file://${absoluteHtmlPath}`);
const element = await page.locator(selector);
await element.screenshot({
path: pngPath,
type: 'png',
});
console.log(` → Saved to ${pngPath}`);
await browser.close();
}
/**
* Capture all HTML diagrams in a directory
*/
async function captureAllDiagrams(directory = '.') {
const browser = await chromium.launch();
const context = await browser.newContext({
deviceScaleFactor: CONFIG.deviceScaleFactor,
});
const page = await context.newPage();
// Find all *_diagram*.html files
const files = fs.readdirSync(directory)
.filter(f => f.endsWith('.html') && f.includes('diagram'));
if (files.length === 0) {
console.log('No diagram HTML files found in directory');
await browser.close();
return;
}
for (const htmlFile of files) {
const htmlPath = path.join(directory, htmlFile);
const pngPath = htmlPath.replace('.html', '.png');
console.log(`Capturing ${htmlFile}...`);
await page.goto(`file://${path.resolve(htmlPath)}`);
try {
const element = await page.locator(CONFIG.selector);
await element.screenshot({ path: pngPath, type: 'png' });
console.log(` → Saved to ${path.basename(pngPath)}`);
} catch (error) {
console.log(` ✗ Failed: ${error.message}`);
}
}
await browser.close();
console.log('\nAll diagrams captured successfully!');
}
// Main execution
async function main() {
const args = process.argv.slice(2);
if (args.length === 2) {
// Single file mode: node capture-diagrams.js input.html output.png
await captureScreenshot(args[0], args[1]);
} else if (args.length === 1) {
// Directory mode: node capture-diagrams.js ./docs
await captureAllDiagrams(args[0]);
} else {
// Default: capture all diagrams in current directory
await captureAllDiagrams('.');
}
}
main().catch(console.error);

View File

@@ -0,0 +1,164 @@
/* Academic PDF Style Template
* For use with pandoc + weasyprint
* Based on: paralleLLM empathy-experiment-v1.0.pdf
*/
/* ==========================================================================
Base Typography
========================================================================== */
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
line-height: 1.6;
max-width: 800px;
margin: 0 auto;
padding: 2em;
}
h1, h2, h3, h4 {
margin-top: 1.5em;
margin-bottom: 0.5em;
}
h2 {
margin-top: 2em;
}
h3 {
margin-top: 1.5em;
}
/* ==========================================================================
Tables (Academic Style)
========================================================================== */
table {
width: 100%;
border-collapse: collapse;
margin: 1em 0;
page-break-inside: avoid;
}
table th, table td {
padding: 0.5em 0.75em;
text-align: left;
vertical-align: top;
}
/* Academic-style borders: top/bottom on header, bottom on last row */
table thead th {
border-top: 2px solid #000;
border-bottom: 2px solid #000;
font-weight: bold;
}
table tbody td {
border-bottom: 1px solid #ddd;
}
table tbody tr:last-child td {
border-bottom: 2px solid #000;
}
/* ==========================================================================
Block Elements
========================================================================== */
blockquote {
border-left: 4px solid #ddd;
margin: 1em 0;
padding-left: 1em;
color: #555;
page-break-inside: avoid;
}
code {
background: #f5f5f5;
padding: 0.2em 0.4em;
border-radius: 3px;
font-size: 0.9em;
}
pre {
background: #f5f5f5;
padding: 1em;
border-radius: 5px;
page-break-inside: avoid;
}
pre code {
background: none;
padding: 0;
}
hr {
border: none;
border-top: 1px solid #ddd;
margin: 2em 0;
}
/* ==========================================================================
Figures and Images
========================================================================== */
figure {
page-break-inside: avoid;
margin: 1.5em 0;
}
figure img {
max-width: 100%;
height: auto;
display: block;
}
figcaption {
text-align: center;
font-style: italic;
margin-top: 0.5em;
font-size: 0.9em;
}
/* ==========================================================================
Page Control (Print/PDF)
========================================================================== */
@page {
margin: 2cm;
}
/* Keep headings with following content */
h2, h3, h4 {
page-break-after: avoid;
}
/* Prevent orphan paragraphs */
p {
orphans: 3;
widows: 3;
}
/* Keep lists together when possible */
ul, ol {
page-break-inside: avoid;
}
/* ==========================================================================
Utility Classes
========================================================================== */
/* For centered figures in weasyprint */
.figure-centered {
margin: 2em auto;
text-align: center;
}
.figure-centered img {
display: inline-block;
max-width: 100%;
}
/* Small text for appendix tables */
.small-text {
font-size: 0.85em;
}