|
|
|
@ -34,25 +34,40 @@ var __importStar = (this && this.__importStar) || (function () { |
|
|
|
})(); |
|
|
|
})(); |
|
|
|
Object.defineProperty(exports, "__esModule", { value: true }); |
|
|
|
Object.defineProperty(exports, "__esModule", { value: true }); |
|
|
|
const parser_1 = require("./src/parser"); |
|
|
|
const parser_1 = require("./src/parser"); |
|
|
|
|
|
|
|
const report_generator_1 = require("./src/utils/report-generator"); |
|
|
|
const fs = __importStar(require("fs")); |
|
|
|
const fs = __importStar(require("fs")); |
|
|
|
const path = __importStar(require("path")); |
|
|
|
const path = __importStar(require("path")); |
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Standalone script to generate HTML test report |
|
|
|
|
|
|
|
* Run with: npm run test:report |
|
|
|
|
|
|
|
*/ |
|
|
|
async function main() { |
|
|
|
async function main() { |
|
|
|
|
|
|
|
console.log('📝 Generating test report...\n'); |
|
|
|
|
|
|
|
// Initialize parser
|
|
|
|
const parser = new parser_1.Parser({ |
|
|
|
const parser = new parser_1.Parser({ |
|
|
|
linkBaseURL: 'https://example.com', |
|
|
|
linkBaseURL: 'https://example.com', |
|
|
|
wikilinkUrl: '/events?d={dtag}', |
|
|
|
wikilinkUrl: '/events?d={dtag}', |
|
|
|
hashtagUrl: '/notes?t={topic}', |
|
|
|
hashtagUrl: '/notes?t={topic}', |
|
|
|
}); |
|
|
|
}); |
|
|
|
console.log('Reading test documents...'); |
|
|
|
|
|
|
|
// Read test documents
|
|
|
|
// Read test documents
|
|
|
|
const markdownContent = fs.readFileSync(path.join(__dirname, 'markdown_testdoc.md'), 'utf-8'); |
|
|
|
const markdownPath = path.join(__dirname, 'markdown_testdoc.md'); |
|
|
|
const asciidocContent = fs.readFileSync(path.join(__dirname, 'asciidoc_testdoc.adoc'), 'utf-8'); |
|
|
|
const asciidocPath = path.join(__dirname, 'asciidoc_testdoc.adoc'); |
|
|
|
console.log('Parsing markdown document...'); |
|
|
|
if (!fs.existsSync(markdownPath)) { |
|
|
|
|
|
|
|
console.error(`❌ Error: ${markdownPath} not found`); |
|
|
|
|
|
|
|
process.exit(1); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (!fs.existsSync(asciidocPath)) { |
|
|
|
|
|
|
|
console.error(`❌ Error: ${asciidocPath} not found`); |
|
|
|
|
|
|
|
process.exit(1); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
const markdownContent = fs.readFileSync(markdownPath, 'utf-8'); |
|
|
|
|
|
|
|
const asciidocContent = fs.readFileSync(asciidocPath, 'utf-8'); |
|
|
|
|
|
|
|
console.log('📄 Parsing markdown document...'); |
|
|
|
const markdownResult = await parser.process(markdownContent); |
|
|
|
const markdownResult = await parser.process(markdownContent); |
|
|
|
console.log('Parsing asciidoc document...'); |
|
|
|
console.log('📄 Parsing asciidoc document...'); |
|
|
|
const asciidocResult = await parser.process(asciidocContent); |
|
|
|
const asciidocResult = await parser.process(asciidocContent); |
|
|
|
console.log('Generating HTML report...'); |
|
|
|
console.log('🎨 Generating HTML report...'); |
|
|
|
// Generate HTML report
|
|
|
|
const htmlReport = (0, report_generator_1.generateHTMLReport)({ |
|
|
|
const htmlReport = generateHTMLReport({ |
|
|
|
|
|
|
|
markdown: { |
|
|
|
markdown: { |
|
|
|
original: markdownContent, |
|
|
|
original: markdownContent, |
|
|
|
result: markdownResult, |
|
|
|
result: markdownResult, |
|
|
|
@ -62,581 +77,15 @@ async function main() { |
|
|
|
result: asciidocResult, |
|
|
|
result: asciidocResult, |
|
|
|
}, |
|
|
|
}, |
|
|
|
}); |
|
|
|
}); |
|
|
|
// Write HTML report to file (force fresh write)
|
|
|
|
// Write HTML report to file
|
|
|
|
const reportPath = path.join(__dirname, 'test-report.html'); |
|
|
|
const reportPath = path.join(__dirname, 'test-report.html'); |
|
|
|
// Delete old report if it exists to ensure fresh generation
|
|
|
|
|
|
|
|
if (fs.existsSync(reportPath)) { |
|
|
|
|
|
|
|
fs.unlinkSync(reportPath); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
fs.writeFileSync(reportPath, htmlReport, 'utf-8'); |
|
|
|
fs.writeFileSync(reportPath, htmlReport, 'utf-8'); |
|
|
|
const reportUrl = `file://${reportPath}`; |
|
|
|
console.log(`\n✅ Test report generated: ${reportPath}`); |
|
|
|
console.log(`\n✅ Test report generated successfully!`); |
|
|
|
|
|
|
|
console.log(` File: ${reportPath}`); |
|
|
|
|
|
|
|
console.log(` Size: ${(htmlReport.length / 1024).toFixed(2)} KB`); |
|
|
|
|
|
|
|
console.log(` Timestamp: ${new Date().toISOString()}`); |
|
|
|
|
|
|
|
console.log(` Open this file in your browser to view the results.\n`); |
|
|
|
console.log(` Open this file in your browser to view the results.\n`); |
|
|
|
} |
|
|
|
} |
|
|
|
function generateHTMLReport(data) { |
|
|
|
|
|
|
|
const { markdown, asciidoc } = data; |
|
|
|
|
|
|
|
return `<!DOCTYPE html>
|
|
|
|
|
|
|
|
<html lang="en"> |
|
|
|
|
|
|
|
<head> |
|
|
|
|
|
|
|
<meta charset="UTF-8"> |
|
|
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
|
|
|
|
|
|
<title>GC Parser Test Report</title> |
|
|
|
|
|
|
|
<style> |
|
|
|
|
|
|
|
* { |
|
|
|
|
|
|
|
margin: 0; |
|
|
|
|
|
|
|
padding: 0; |
|
|
|
|
|
|
|
box-sizing: border-box; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
body { |
|
|
|
|
|
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; |
|
|
|
|
|
|
|
line-height: 1.6; |
|
|
|
|
|
|
|
color: #333; |
|
|
|
|
|
|
|
background: #f5f5f5; |
|
|
|
|
|
|
|
padding: 20px; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.container { |
|
|
|
|
|
|
|
max-width: 1400px; |
|
|
|
|
|
|
|
margin: 0 auto; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
h1 { |
|
|
|
|
|
|
|
color: #2c3e50; |
|
|
|
|
|
|
|
margin-bottom: 10px; |
|
|
|
|
|
|
|
font-size: 2.5em; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.subtitle { |
|
|
|
|
|
|
|
color: #7f8c8d; |
|
|
|
|
|
|
|
margin-bottom: 30px; |
|
|
|
|
|
|
|
font-size: 1.1em; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.section { |
|
|
|
|
|
|
|
background: white; |
|
|
|
|
|
|
|
border-radius: 8px; |
|
|
|
|
|
|
|
padding: 30px; |
|
|
|
|
|
|
|
margin-bottom: 30px; |
|
|
|
|
|
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.section h2 { |
|
|
|
|
|
|
|
color: #34495e; |
|
|
|
|
|
|
|
margin-bottom: 20px; |
|
|
|
|
|
|
|
padding-bottom: 10px; |
|
|
|
|
|
|
|
border-bottom: 2px solid #3498db; |
|
|
|
|
|
|
|
font-size: 1.8em; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.section h3 { |
|
|
|
|
|
|
|
color: #2c3e50; |
|
|
|
|
|
|
|
margin-top: 25px; |
|
|
|
|
|
|
|
margin-bottom: 15px; |
|
|
|
|
|
|
|
font-size: 1.3em; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.tabs { |
|
|
|
|
|
|
|
display: flex; |
|
|
|
|
|
|
|
gap: 10px; |
|
|
|
|
|
|
|
margin-bottom: 20px; |
|
|
|
|
|
|
|
border-bottom: 2px solid #e0e0e0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.tab { |
|
|
|
|
|
|
|
padding: 12px 24px; |
|
|
|
|
|
|
|
background: #f8f9fa; |
|
|
|
|
|
|
|
border: none; |
|
|
|
|
|
|
|
border-top-left-radius: 6px; |
|
|
|
|
|
|
|
border-top-right-radius: 6px; |
|
|
|
|
|
|
|
cursor: pointer; |
|
|
|
|
|
|
|
font-size: 1em; |
|
|
|
|
|
|
|
font-weight: 500; |
|
|
|
|
|
|
|
color: #555; |
|
|
|
|
|
|
|
transition: all 0.2s; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.tab:hover { |
|
|
|
|
|
|
|
background: #e9ecef; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.tab.active { |
|
|
|
|
|
|
|
background: #3498db; |
|
|
|
|
|
|
|
color: white; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.tab-content { |
|
|
|
|
|
|
|
display: none; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.tab-content.active { |
|
|
|
|
|
|
|
display: block; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.metadata-grid { |
|
|
|
|
|
|
|
display: grid; |
|
|
|
|
|
|
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); |
|
|
|
|
|
|
|
gap: 15px; |
|
|
|
|
|
|
|
margin-top: 15px; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.metadata-item { |
|
|
|
|
|
|
|
background: #f8f9fa; |
|
|
|
|
|
|
|
padding: 12px; |
|
|
|
|
|
|
|
border-radius: 4px; |
|
|
|
|
|
|
|
border-left: 3px solid #3498db; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.metadata-item strong { |
|
|
|
|
|
|
|
color: #2c3e50; |
|
|
|
|
|
|
|
display: block; |
|
|
|
|
|
|
|
margin-bottom: 5px; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.metadata-item code { |
|
|
|
|
|
|
|
background: #e9ecef; |
|
|
|
|
|
|
|
padding: 2px 6px; |
|
|
|
|
|
|
|
border-radius: 3px; |
|
|
|
|
|
|
|
font-size: 0.9em; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.code-block { |
|
|
|
|
|
|
|
background: #2d2d2d; |
|
|
|
|
|
|
|
color: #f8f8f2; |
|
|
|
|
|
|
|
padding: 15px; |
|
|
|
|
|
|
|
border-radius: 6px; |
|
|
|
|
|
|
|
overflow-x: auto; |
|
|
|
|
|
|
|
font-family: 'Courier New', monospace; |
|
|
|
|
|
|
|
font-size: 0.9em; |
|
|
|
|
|
|
|
line-height: 1.5; |
|
|
|
|
|
|
|
margin: 15px 0; |
|
|
|
|
|
|
|
max-height: 400px; |
|
|
|
|
|
|
|
overflow-y: auto; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.code-block pre { |
|
|
|
|
|
|
|
margin: 0; |
|
|
|
|
|
|
|
white-space: pre-wrap; |
|
|
|
|
|
|
|
word-wrap: break-word; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.rendered-output { |
|
|
|
|
|
|
|
background: white; |
|
|
|
|
|
|
|
border: 1px solid #ddd; |
|
|
|
|
|
|
|
padding: 20px; |
|
|
|
|
|
|
|
border-radius: 6px; |
|
|
|
|
|
|
|
margin: 15px 0; |
|
|
|
|
|
|
|
min-height: 200px; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.rendered-output * { |
|
|
|
|
|
|
|
max-width: 100%; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.stats { |
|
|
|
|
|
|
|
display: grid; |
|
|
|
|
|
|
|
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); |
|
|
|
|
|
|
|
gap: 15px; |
|
|
|
|
|
|
|
margin-top: 20px; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.stat-card { |
|
|
|
|
|
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
|
|
|
|
|
|
|
color: white; |
|
|
|
|
|
|
|
padding: 20px; |
|
|
|
|
|
|
|
border-radius: 8px; |
|
|
|
|
|
|
|
text-align: center; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.stat-card .number { |
|
|
|
|
|
|
|
font-size: 2.5em; |
|
|
|
|
|
|
|
font-weight: bold; |
|
|
|
|
|
|
|
margin-bottom: 5px; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.stat-card .label { |
|
|
|
|
|
|
|
font-size: 0.9em; |
|
|
|
|
|
|
|
opacity: 0.9; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.list-item { |
|
|
|
|
|
|
|
background: #f8f9fa; |
|
|
|
|
|
|
|
padding: 8px 12px; |
|
|
|
|
|
|
|
margin: 5px 0; |
|
|
|
|
|
|
|
border-radius: 4px; |
|
|
|
|
|
|
|
border-left: 3px solid #95a5a6; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.list-item code { |
|
|
|
|
|
|
|
background: #e9ecef; |
|
|
|
|
|
|
|
padding: 2px 6px; |
|
|
|
|
|
|
|
border-radius: 3px; |
|
|
|
|
|
|
|
font-size: 0.85em; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.success-badge { |
|
|
|
|
|
|
|
display: inline-block; |
|
|
|
|
|
|
|
background: #27ae60; |
|
|
|
|
|
|
|
color: white; |
|
|
|
|
|
|
|
padding: 4px 12px; |
|
|
|
|
|
|
|
border-radius: 12px; |
|
|
|
|
|
|
|
font-size: 0.85em; |
|
|
|
|
|
|
|
font-weight: 500; |
|
|
|
|
|
|
|
margin-left: 10px; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.warning-badge { |
|
|
|
|
|
|
|
display: inline-block; |
|
|
|
|
|
|
|
background: #f39c12; |
|
|
|
|
|
|
|
color: white; |
|
|
|
|
|
|
|
padding: 4px 12px; |
|
|
|
|
|
|
|
border-radius: 12px; |
|
|
|
|
|
|
|
font-size: 0.85em; |
|
|
|
|
|
|
|
font-weight: 500; |
|
|
|
|
|
|
|
margin-left: 10px; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.comparison { |
|
|
|
|
|
|
|
display: grid; |
|
|
|
|
|
|
|
grid-template-columns: 1fr 1fr; |
|
|
|
|
|
|
|
gap: 20px; |
|
|
|
|
|
|
|
margin-top: 20px; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@media (max-width: 768px) { |
|
|
|
|
|
|
|
.comparison { |
|
|
|
|
|
|
|
grid-template-columns: 1fr; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.json-view { |
|
|
|
|
|
|
|
background: #f8f9fa; |
|
|
|
|
|
|
|
padding: 15px; |
|
|
|
|
|
|
|
border-radius: 6px; |
|
|
|
|
|
|
|
overflow-x: auto; |
|
|
|
|
|
|
|
font-family: 'Courier New', monospace; |
|
|
|
|
|
|
|
font-size: 0.85em; |
|
|
|
|
|
|
|
max-height: 300px; |
|
|
|
|
|
|
|
overflow-y: auto; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
</style> |
|
|
|
|
|
|
|
</head> |
|
|
|
|
|
|
|
<body> |
|
|
|
|
|
|
|
<div class="container"> |
|
|
|
|
|
|
|
<h1>GC Parser Test Report</h1> |
|
|
|
|
|
|
|
<p class="subtitle">Generated: ${new Date().toLocaleString()}</p> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Markdown Section --> |
|
|
|
|
|
|
|
<div class="section"> |
|
|
|
|
|
|
|
<h2>Markdown Document Test <span class="success-badge">✓ Parsed</span></h2> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="tabs"> |
|
|
|
|
|
|
|
<button class="tab active" onclick="showTab('md-overview')">Overview</button> |
|
|
|
|
|
|
|
<button class="tab" onclick="showTab('md-original')">Original Content</button> |
|
|
|
|
|
|
|
<button class="tab" onclick="showTab('md-rendered')">Rendered Output</button> |
|
|
|
|
|
|
|
<button class="tab" onclick="showTab('md-metadata')">Metadata</button> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div id="md-overview" class="tab-content active"> |
|
|
|
|
|
|
|
<div class="stats"> |
|
|
|
|
|
|
|
<div class="stat-card"> |
|
|
|
|
|
|
|
<div class="number">${markdown.result.nostrLinks.length}</div> |
|
|
|
|
|
|
|
<div class="label">Nostr Links</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="stat-card"> |
|
|
|
|
|
|
|
<div class="number">${markdown.result.wikilinks.length}</div> |
|
|
|
|
|
|
|
<div class="label">Wikilinks</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="stat-card"> |
|
|
|
|
|
|
|
<div class="number">${markdown.result.hashtags.length}</div> |
|
|
|
|
|
|
|
<div class="label">Hashtags</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="stat-card"> |
|
|
|
|
|
|
|
<div class="number">${markdown.result.links.length}</div> |
|
|
|
|
|
|
|
<div class="label">Links</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="stat-card"> |
|
|
|
|
|
|
|
<div class="number">${markdown.result.media.length}</div> |
|
|
|
|
|
|
|
<div class="label">Media URLs</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="stat-card"> |
|
|
|
|
|
|
|
<div class="number">${markdown.result.hasLaTeX ? 'Yes' : 'No'}</div> |
|
|
|
|
|
|
|
<div class="label">Has LaTeX</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="stat-card"> |
|
|
|
|
|
|
|
<div class="number">${markdown.result.hasMusicalNotation ? 'Yes' : 'No'}</div> |
|
|
|
|
|
|
|
<div class="label">Has Music</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h3>Frontmatter</h3> |
|
|
|
|
|
|
|
${markdown.result.frontmatter ? ` |
|
|
|
|
|
|
|
<div class="metadata-grid"> |
|
|
|
|
|
|
|
${Object.entries(markdown.result.frontmatter).map(([key, value]) => ` |
|
|
|
|
|
|
|
<div class="metadata-item"> |
|
|
|
|
|
|
|
<strong>${escapeHtml(key)}</strong> |
|
|
|
|
|
|
|
<code>${escapeHtml(JSON.stringify(value))}</code> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
`).join('')}
|
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
` : '<p><em>No frontmatter found</em></p>'}
|
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div id="md-original" class="tab-content"> |
|
|
|
|
|
|
|
<h3>Original Markdown Content</h3> |
|
|
|
|
|
|
|
<div class="code-block"> |
|
|
|
|
|
|
|
<pre>${escapeHtml(markdown.original)}</pre> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div id="md-rendered" class="tab-content"> |
|
|
|
|
|
|
|
<h3>Rendered HTML Output</h3> |
|
|
|
|
|
|
|
<div class="rendered-output"> |
|
|
|
|
|
|
|
${markdown.result.content} |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
<details style="margin-top: 15px;"> |
|
|
|
|
|
|
|
<summary style="cursor: pointer; color: #3498db; font-weight: 500;">View Raw HTML</summary> |
|
|
|
|
|
|
|
<div class="code-block" style="margin-top: 10px;"> |
|
|
|
|
|
|
|
<pre>${escapeHtml(markdown.result.content)}</pre> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</details> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div id="md-metadata" class="tab-content"> |
|
|
|
|
|
|
|
<h3>Extracted Metadata</h3> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
${markdown.result.nostrLinks.length > 0 ? ` |
|
|
|
|
|
|
|
<h4>Nostr Links (${markdown.result.nostrLinks.length})</h4> |
|
|
|
|
|
|
|
${markdown.result.nostrLinks.map((link) => ` |
|
|
|
|
|
|
|
<div class="list-item"> |
|
|
|
|
|
|
|
<strong>${escapeHtml(link.type)}</strong>: <code>${escapeHtml(link.bech32)}</code> |
|
|
|
|
|
|
|
${link.text ? ` - ${escapeHtml(link.text)}` : ''} |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
`).join('')}
|
|
|
|
|
|
|
|
` : ''}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
${markdown.result.wikilinks.length > 0 ? ` |
|
|
|
|
|
|
|
<h4>Wikilinks (${markdown.result.wikilinks.length})</h4> |
|
|
|
|
|
|
|
${markdown.result.wikilinks.map((wl) => ` |
|
|
|
|
|
|
|
<div class="list-item"> |
|
|
|
|
|
|
|
<code>${escapeHtml(wl.original)}</code> → dtag: <code>${escapeHtml(wl.dtag)}</code> |
|
|
|
|
|
|
|
${wl.display ? ` (display: ${escapeHtml(wl.display)})` : ''} |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
`).join('')}
|
|
|
|
|
|
|
|
` : ''}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
${markdown.result.hashtags.length > 0 ? ` |
|
|
|
|
|
|
|
<h4>Hashtags (${markdown.result.hashtags.length})</h4> |
|
|
|
|
|
|
|
${markdown.result.hashtags.map((tag) => ` |
|
|
|
|
|
|
|
<div class="list-item"> |
|
|
|
|
|
|
|
<code>#${escapeHtml(tag)}</code> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
`).join('')}
|
|
|
|
|
|
|
|
` : ''}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
${markdown.result.links.length > 0 ? ` |
|
|
|
|
|
|
|
<h4>Links (${markdown.result.links.length})</h4> |
|
|
|
|
|
|
|
${markdown.result.links.map((link) => ` |
|
|
|
|
|
|
|
<div class="list-item"> |
|
|
|
|
|
|
|
<a href="${escapeHtml(link.url)}" target="_blank">${escapeHtml(link.text || link.url)}</a> |
|
|
|
|
|
|
|
${link.isExternal ? '<span class="warning-badge">External</span>' : ''} |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
`).join('')}
|
|
|
|
|
|
|
|
` : ''}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
${markdown.result.media.length > 0 ? ` |
|
|
|
|
|
|
|
<h4>Media URLs (${markdown.result.media.length})</h4> |
|
|
|
|
|
|
|
${markdown.result.media.map((url) => ` |
|
|
|
|
|
|
|
<div class="list-item"> |
|
|
|
|
|
|
|
<a href="${escapeHtml(url)}" target="_blank">${escapeHtml(url)}</a> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
`).join('')}
|
|
|
|
|
|
|
|
` : ''}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
${markdown.result.tableOfContents ? ` |
|
|
|
|
|
|
|
<h4>Table of Contents</h4> |
|
|
|
|
|
|
|
<div class="rendered-output"> |
|
|
|
|
|
|
|
${markdown.result.tableOfContents} |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
` : ''}
|
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- AsciiDoc Section --> |
|
|
|
|
|
|
|
<div class="section"> |
|
|
|
|
|
|
|
<h2>AsciiDoc Document Test <span class="success-badge">✓ Parsed</span></h2> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="tabs"> |
|
|
|
|
|
|
|
<button class="tab active" onclick="showTab('ad-overview')">Overview</button> |
|
|
|
|
|
|
|
<button class="tab" onclick="showTab('ad-original')">Original Content</button> |
|
|
|
|
|
|
|
<button class="tab" onclick="showTab('ad-rendered')">Rendered Output</button> |
|
|
|
|
|
|
|
<button class="tab" onclick="showTab('ad-metadata')">Metadata</button> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div id="ad-overview" class="tab-content active"> |
|
|
|
|
|
|
|
<div class="stats"> |
|
|
|
|
|
|
|
<div class="stat-card"> |
|
|
|
|
|
|
|
<div class="number">${asciidoc.result.nostrLinks.length}</div> |
|
|
|
|
|
|
|
<div class="label">Nostr Links</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="stat-card"> |
|
|
|
|
|
|
|
<div class="number">${asciidoc.result.wikilinks.length}</div> |
|
|
|
|
|
|
|
<div class="label">Wikilinks</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="stat-card"> |
|
|
|
|
|
|
|
<div class="number">${asciidoc.result.hashtags.length}</div> |
|
|
|
|
|
|
|
<div class="label">Hashtags</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="stat-card"> |
|
|
|
|
|
|
|
<div class="number">${asciidoc.result.links.length}</div> |
|
|
|
|
|
|
|
<div class="label">Links</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="stat-card"> |
|
|
|
|
|
|
|
<div class="number">${asciidoc.result.media.length}</div> |
|
|
|
|
|
|
|
<div class="label">Media URLs</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="stat-card"> |
|
|
|
|
|
|
|
<div class="number">${asciidoc.result.hasLaTeX ? 'Yes' : 'No'}</div> |
|
|
|
|
|
|
|
<div class="label">Has LaTeX</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="stat-card"> |
|
|
|
|
|
|
|
<div class="number">${asciidoc.result.hasMusicalNotation ? 'Yes' : 'No'}</div> |
|
|
|
|
|
|
|
<div class="label">Has Music</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h3>Frontmatter</h3> |
|
|
|
|
|
|
|
${asciidoc.result.frontmatter ? ` |
|
|
|
|
|
|
|
<div class="metadata-grid"> |
|
|
|
|
|
|
|
${Object.entries(asciidoc.result.frontmatter).map(([key, value]) => ` |
|
|
|
|
|
|
|
<div class="metadata-item"> |
|
|
|
|
|
|
|
<strong>${escapeHtml(key)}</strong> |
|
|
|
|
|
|
|
<code>${escapeHtml(JSON.stringify(value))}</code> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
`).join('')}
|
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
` : '<p><em>No frontmatter found</em></p>'}
|
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div id="ad-original" class="tab-content"> |
|
|
|
|
|
|
|
<h3>Original AsciiDoc Content</h3> |
|
|
|
|
|
|
|
<div class="code-block"> |
|
|
|
|
|
|
|
<pre>${escapeHtml(asciidoc.original)}</pre> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div id="ad-rendered" class="tab-content"> |
|
|
|
|
|
|
|
<h3>Rendered HTML Output</h3> |
|
|
|
|
|
|
|
<div class="rendered-output"> |
|
|
|
|
|
|
|
${asciidoc.result.content} |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
<details style="margin-top: 15px;"> |
|
|
|
|
|
|
|
<summary style="cursor: pointer; color: #3498db; font-weight: 500;">View Raw HTML</summary> |
|
|
|
|
|
|
|
<div class="code-block" style="margin-top: 10px;"> |
|
|
|
|
|
|
|
<pre>${escapeHtml(asciidoc.result.content)}</pre> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</details> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div id="ad-metadata" class="tab-content"> |
|
|
|
|
|
|
|
<h3>Extracted Metadata</h3> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
${asciidoc.result.nostrLinks.length > 0 ? ` |
|
|
|
|
|
|
|
<h4>Nostr Links (${asciidoc.result.nostrLinks.length})</h4> |
|
|
|
|
|
|
|
${asciidoc.result.nostrLinks.map((link) => ` |
|
|
|
|
|
|
|
<div class="list-item"> |
|
|
|
|
|
|
|
<strong>${escapeHtml(link.type)}</strong>: <code>${escapeHtml(link.bech32)}</code> |
|
|
|
|
|
|
|
${link.text ? ` - ${escapeHtml(link.text)}` : ''} |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
`).join('')}
|
|
|
|
|
|
|
|
` : ''}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
${asciidoc.result.wikilinks.length > 0 ? ` |
|
|
|
|
|
|
|
<h4>Wikilinks (${asciidoc.result.wikilinks.length})</h4> |
|
|
|
|
|
|
|
${asciidoc.result.wikilinks.map((wl) => ` |
|
|
|
|
|
|
|
<div class="list-item"> |
|
|
|
|
|
|
|
<code>${escapeHtml(wl.original)}</code> → dtag: <code>${escapeHtml(wl.dtag)}</code> |
|
|
|
|
|
|
|
${wl.display ? ` (display: ${escapeHtml(wl.display)})` : ''} |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
`).join('')}
|
|
|
|
|
|
|
|
` : ''}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
${asciidoc.result.hashtags.length > 0 ? ` |
|
|
|
|
|
|
|
<h4>Hashtags (${asciidoc.result.hashtags.length})</h4> |
|
|
|
|
|
|
|
${asciidoc.result.hashtags.map((tag) => ` |
|
|
|
|
|
|
|
<div class="list-item"> |
|
|
|
|
|
|
|
<code>#${escapeHtml(tag)}</code> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
`).join('')}
|
|
|
|
|
|
|
|
` : ''}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
${asciidoc.result.links.length > 0 ? ` |
|
|
|
|
|
|
|
<h4>Links (${asciidoc.result.links.length})</h4> |
|
|
|
|
|
|
|
${asciidoc.result.links.map((link) => ` |
|
|
|
|
|
|
|
<div class="list-item"> |
|
|
|
|
|
|
|
<a href="${escapeHtml(link.url)}" target="_blank">${escapeHtml(link.text || link.url)}</a> |
|
|
|
|
|
|
|
${link.isExternal ? '<span class="warning-badge">External</span>' : ''} |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
`).join('')}
|
|
|
|
|
|
|
|
` : ''}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
${asciidoc.result.media.length > 0 ? ` |
|
|
|
|
|
|
|
<h4>Media URLs (${asciidoc.result.media.length})</h4> |
|
|
|
|
|
|
|
${asciidoc.result.media.map((url) => ` |
|
|
|
|
|
|
|
<div class="list-item"> |
|
|
|
|
|
|
|
<a href="${escapeHtml(url)}" target="_blank">${escapeHtml(url)}</a> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
`).join('')}
|
|
|
|
|
|
|
|
` : ''}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
${asciidoc.result.tableOfContents ? ` |
|
|
|
|
|
|
|
<h4>Table of Contents</h4> |
|
|
|
|
|
|
|
<div class="rendered-output"> |
|
|
|
|
|
|
|
${asciidoc.result.tableOfContents} |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
` : ''}
|
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<script> |
|
|
|
|
|
|
|
function showTab(tabId) { |
|
|
|
|
|
|
|
// Hide all tab contents
|
|
|
|
|
|
|
|
const allContents = document.querySelectorAll('.tab-content'); |
|
|
|
|
|
|
|
allContents.forEach(content => content.classList.remove('active')); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Remove active class from all tabs
|
|
|
|
|
|
|
|
const allTabs = document.querySelectorAll('.tab'); |
|
|
|
|
|
|
|
allTabs.forEach(tab => tab.classList.remove('active')); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Show selected tab content
|
|
|
|
|
|
|
|
const selectedContent = document.getElementById(tabId); |
|
|
|
|
|
|
|
if (selectedContent) { |
|
|
|
|
|
|
|
selectedContent.classList.add('active'); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Add active class to clicked tab
|
|
|
|
|
|
|
|
event.target.classList.add('active'); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
</script> |
|
|
|
|
|
|
|
</body> |
|
|
|
|
|
|
|
</html>`; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
function escapeHtml(text) { |
|
|
|
|
|
|
|
const map = { |
|
|
|
|
|
|
|
'&': '&', |
|
|
|
|
|
|
|
'<': '<', |
|
|
|
|
|
|
|
'>': '>', |
|
|
|
|
|
|
|
'"': '"', |
|
|
|
|
|
|
|
"'": ''', |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
return text.replace(/[&<>"']/g, (m) => map[m]); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// Run the script
|
|
|
|
// Run the script
|
|
|
|
main().catch((error) => { |
|
|
|
main().catch((error) => { |
|
|
|
console.error('Error generating test report:', error); |
|
|
|
console.error('❌ Error generating test report:', error); |
|
|
|
process.exit(1); |
|
|
|
process.exit(1); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
//# sourceMappingURL=generate-test-report.js.map
|