182 lines
5.8 KiB
HTML
182 lines
5.8 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh-cn">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>CMarkdown Editor and Preview</title>
|
|
<!-- 引入 MathJax 支持公式渲染 -->
|
|
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
|
|
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
|
|
<!-- 引入 marked 库用于解析 Markdown -->
|
|
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
|
<!-- 引入 jsPDF 库用于导出 PDF -->
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
|
|
<style>
|
|
body {
|
|
font-family: Arial, sans-serif;
|
|
display: flex;
|
|
flex-direction: column;
|
|
height: 100vh;
|
|
margin: 0;
|
|
}
|
|
|
|
#button-container {
|
|
padding: 10px;
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
#editor-preview-container {
|
|
display: flex;
|
|
flex: 1;
|
|
}
|
|
|
|
#editor {
|
|
width: 50%;
|
|
height: 100%;
|
|
padding: 10px;
|
|
box-sizing: border-box;
|
|
resize: none;
|
|
}
|
|
|
|
#preview {
|
|
width: 50%;
|
|
height: 100%;
|
|
padding: 10px;
|
|
box-sizing: border-box;
|
|
overflow-y: auto;
|
|
border-left: 1px solid #ccc;
|
|
}
|
|
|
|
.dropdown {
|
|
position: relative;
|
|
display: inline-block;
|
|
}
|
|
|
|
.dropdown-content {
|
|
display: none;
|
|
position: absolute;
|
|
background-color: #f9f9f9;
|
|
min-width: 160px;
|
|
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
|
|
z-index: 1;
|
|
}
|
|
|
|
.dropdown-content a {
|
|
color: black;
|
|
padding: 12px 16px;
|
|
text-decoration: none;
|
|
display: block;
|
|
}
|
|
|
|
.dropdown-content a:hover {
|
|
background-color: #f1f1f1;
|
|
}
|
|
|
|
.dropdown:hover .dropdown-content {
|
|
display: block;
|
|
}
|
|
</style>
|
|
<script>
|
|
MathJax = {
|
|
tex: {
|
|
inlineMath: [['\\(', '\\)'], ['\\{', '\\}']],
|
|
displayMath: [['\\[', '\\]']],
|
|
processEscapes: true,
|
|
packages: { '[+]': ['ams', 'boldsymbol', 'color', 'cases'] }
|
|
},
|
|
loader: {
|
|
load: ['[tex]/ams', '[tex]/boldsymbol', '[tex]/color', '[tex]/cases']
|
|
}
|
|
};
|
|
</script>
|
|
</head>
|
|
|
|
<body>
|
|
<div id="button-container">
|
|
<button id="toggle-editor">隐藏/显示编辑区</button>
|
|
<div class="dropdown">
|
|
<button class="dropbtn">导出</button>
|
|
<div class="dropdown-content">
|
|
<a href="#" id="export-txt">导出 TXT</a>
|
|
<a href="#" id="export-html">导出 HTML</a>
|
|
<a href="#" id="export-md">导出 Markdown</a>
|
|
<a href="#" id="export-pdf">导出 PDF</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="editor-preview-container">
|
|
<textarea id="editor"></textarea>
|
|
<div id="preview"></div>
|
|
</div>
|
|
<script>
|
|
const editor = document.getElementById('editor');
|
|
const preview = document.getElementById('preview');
|
|
const toggleButton = document.getElementById('toggle-editor');
|
|
const exportTxt = document.getElementById('export-txt');
|
|
const exportHtml = document.getElementById('export-html');
|
|
const exportMd = document.getElementById('export-md');
|
|
const exportPdf = document.getElementById('export-pdf');
|
|
|
|
function updatePreview() {
|
|
const markdown = editor.value;
|
|
const html = marked.parse(markdown);
|
|
preview.innerHTML = html;
|
|
MathJax.typesetPromise([preview]);
|
|
}
|
|
|
|
function toggleEditor() {
|
|
if (editor.style.display === 'none') {
|
|
editor.style.display = 'block';
|
|
preview.style.width = '50%';
|
|
} else {
|
|
editor.style.display = 'none';
|
|
preview.style.width = '100%';
|
|
}
|
|
}
|
|
|
|
function exportFile(content, filename, type) {
|
|
const blob = new Blob([content], { type: type });
|
|
const url = URL.createObjectURL(blob);
|
|
const a = document.createElement('a');
|
|
a.href = url;
|
|
a.download = filename;
|
|
a.click();
|
|
URL.revokeObjectURL(url);
|
|
}
|
|
|
|
exportTxt.addEventListener('click', () => {
|
|
const content = editor.value;
|
|
exportFile(content, 'document.txt', 'text/plain');
|
|
});
|
|
|
|
exportHtml.addEventListener('click', () => {
|
|
const markdown = editor.value;
|
|
const html = marked.parse(markdown);
|
|
const fullHtml = `<!DOCTYPE html><html lang="zh-cn"><head><meta charset="UTF-8"></head><body>${html}</body></html>`;
|
|
exportFile(fullHtml, 'document.html', 'text/html');
|
|
});
|
|
|
|
exportMd.addEventListener('click', () => {
|
|
const content = editor.value;
|
|
exportFile(content, 'document.md', 'text/markdown');
|
|
});
|
|
|
|
exportPdf.addEventListener('click', () => {
|
|
const { jsPDF } = window.jspdf;
|
|
const doc = new jsPDF();
|
|
doc.addFont('msyh.ttf', 'MicrosoftYaHei', 'normal');
|
|
doc.setFont('MicrosoftYaHei');
|
|
const content = editor.value;
|
|
doc.text(content, 10, 10);
|
|
doc.save('document.pdf');
|
|
});
|
|
|
|
editor.addEventListener('input', updatePreview);
|
|
toggleButton.addEventListener('click', toggleEditor);
|
|
updatePreview();
|
|
</script>
|
|
</body>
|
|
|
|
</html> |