仍然无法实现编译的功能。
1.目录结构
2.1
static-pygments.css
代码:
/* Pygments 代码高亮样式 */
.highlight {background: #f8f8f8;border-radius: 4px;padding: 10px;overflow: auto;
}.highlight pre {margin: 0;padding: 0;background: transparent;
}.highlight .lineno {color: #aaa;padding-right: 10px;border-right: 1px solid #ddd;margin-right: 10px;
}/* 语法高亮颜色 */
.highlight .c { color: #408080; font-style: italic } /* Comment */
.highlight .err { border: 1px solid #FF0000 } /* Error */
.highlight .k { color: #008000; font-weight: bold } /* Keyword */
.highlight .o { color: #666666 } /* Operator */
.highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */
.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #BC7A00 } /* Comment.Preproc */
.highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */
.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */
.highlight .cs { color: #408080; font-weight: bold; font-style: italic } /* Comment.Special */
.highlight .gd { color: #A00000 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #FF0000 } /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #00A000 } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.highlight .gt { color: #0044DD } /* Generic.Traceback */
.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008000 } /* Keyword.Pseudo */
.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #B00040 } /* Keyword.Type */
.highlight .m { color: #666666 } /* Literal.Number */
.highlight .s { color: #BA2121 } /* Literal.String */
.highlight .na { color: #7D9029 } /* Name.Attribute */
.highlight .nb { color: #008000 } /* Name.Builtin */
.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */
.highlight .no { color: #880000 } /* Name.Constant */
.highlight .nd { color: #AA22FF } /* Name.Decorator */
.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */
.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0000FF } /* Name.Function */
.highlight .nl { color: #A0A000 } /* Name.Label */
.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #19177C } /* Name.Variable */
.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #666666 } /* Literal.Number.Bin */
.highlight .mf { color: #666666 } /* Literal.Number.Float */
.highlight .mh { color: #666666 } /* Literal.Number.Hex */
.highlight .mi { color: #666666 } /* Literal.Number.Integer */
.highlight .mo { color: #666666 } /* Literal.Number.Oct */
.highlight .sa { color: #BA2121 } /* Literal.String.Affix */
.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
.highlight .sc { color: #BA2121 } /* Literal.String.Char */
.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */
.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
.highlight .s2 { color: #BA2121 } /* Literal.String.Double */
.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
.highlight .sx { color: #008000 } /* Literal.String.Other */
.highlight .sr { color: #BB6688 } /* Literal.String.Regex */
.highlight .s1 { color: #BA2121 } /* Literal.String.Single */
.highlight .ss { color: #19177C } /* Literal.String.Symbol */
.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0000FF } /* Name.Function.Magic */
.highlight .vc { color: #19177C } /* Name.Variable.Class */
.highlight .vg { color: #19177C } /* Name.Variable.Global */
.highlight .vi { color: #19177C } /* Name.Variable.Instance */
.highlight .vm { color: #19177C } /* Name.Variable.Magic */
.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
2.2 static-style.css
* {margin: 0;padding: 0;box-sizing: border-box;
}body {font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;line-height: 1.6;color: #333;background-color: #f5f5f5;padding: 20px;
}.container {max-width: 1200px;margin: 0 auto;background: white;padding: 30px;border-radius: 8px;box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}header {margin-bottom: 30px;display: flex;justify-content: space-between;align-items: center;border-bottom: 1px solid #eee;padding-bottom: 15px;
}header h1 {color: #2c3e50;
}.btn {display: inline-block;padding: 8px 16px;background: #ddd;color: #333;text-decoration: none;border-radius: 4px;border: none;cursor: pointer;font-size: 14px;transition: all 0.3s;
}.btn-primary {background: #3498db;color: white;
}.btn-secondary {background: #95a5a6;color: white;
}.btn-outline {background: transparent;border: 1px solid #3498db;color: #3498db;
}.btn:hover {opacity: 0.9;transform: translateY(-2px);
}.form-group {margin-bottom: 20px;
}label {display: block;margin-bottom: 5px;font-weight: bold;
}input[type="text"], input[type="password"], select, textarea {width: 100%;padding: 10px;border: 1px solid #ddd;border-radius: 4px;font-family: inherit;font-size: 14px;
}textarea {resize: vertical;font-family: monospace;
}.form-actions {margin-top: 20px;
}.snippet-info {background: #f8f9fa;padding: 15px;border-radius: 4px;margin-bottom: 20px;
}.snippet-info p {margin-bottom: 10px;
}.snippet-info input {background: white;padding: 5px;width: 100%;
}.code-container {border: 1px solid #ddd;border-radius: 4px;overflow: hidden;
}pre {margin: 0;padding: 15px;background: #f8f9fa;overflow-x: auto;
}code {font-family: 'Courier New', Courier, monospace;
}.features {margin-top: 30px;
}.features ul {list-style-type: none;padding-left: 0;
}.features li {padding: 5px 0;position: relative;padding-left: 20px;
}.features li:before {content: "✓";position: absolute;left: 0;color: #27ae60;
}footer {margin-top: 30px;text-align: center;color: #7f8c8d;font-size: 14px;
}.actions {display: flex;gap: 10px;
}/* 创建页面布局 */
.create-container {display: grid;grid-template-columns: 1fr 1fr;gap: 30px;
}.input-section, .preview-section {display: flex;flex-direction: column;
}.preview-section h3 {margin-bottom: 15px;color: #2c3e50;
}.preview-container {flex: 1;border: 1px solid #ddd;border-radius: 4px;padding: 15px;background: #f8f9fa;min-height: 400px;overflow: auto;
}.preview-placeholder {color: #7f8c8d;font-style: italic;text-align: center;margin-top: 50%;
}.preview-error {color: #e74c3c;text-align: center;
}/* 密码页面 */
.password-form {max-width: 400px;margin: 0 auto;text-align: center;
}.password-form h2 {margin-bottom: 15px;color: #2c3e50;
}.password-form p {margin-bottom: 30px;color: #7f8c8d;
}.error-message {color: #e74c3c;margin-bottom: 15px;padding: 10px;background: #ffeaea;border-radius: 4px;
}/* 响应式设计 */
@media (max-width: 768px) {.create-container {grid-template-columns: 1fr;}header {flex-direction: column;align-items: flex-start;gap: 15px;}.actions {flex-wrap: wrap;}
}
3.1 templates-create.html
创建代码片段 - 代码分享 创建代码片段
返回首页实时预览
代码高亮执行效果输入代码后,这里会显示语法高亮...
选择执行效果标签查看代码运行结果...
<script>document.addEventListener('DOMContentLoaded', function() {const codeTextarea = document.getElementById('code');const languageSelect = document.getElementById('language');const highlightResult = document.getElementById('highlight-result');const executionResult = document.getElementById('execution-result');const previewTabs = document.querySelectorAll('.preview-tab');const previewContents = document.querySelectorAll('.preview-content');let previewTimeout;// 选项卡切换previewTabs.forEach(tab => {tab.addEventListener('click', function() {const tabName = this.getAttribute('data-tab');// 更新活跃选项卡previewTabs.forEach(t => t.classList.remove('active'));this.classList.add('active');// 更新内容显示previewContents.forEach(content => content.classList.remove('active'));document.getElementById(`${tabName}-preview`).classList.add('active');// 如果是执行效果标签,更新预览if (tabName === 'execution') {updateExecutionPreview();}});});// 更新代码高亮预览function updateHighlightPreview() {const code = codeTextarea.value;const language = languageSelect.value;if (!code.trim()) {highlightResult.innerHTML = '输入代码后,这里会显示语法高亮...
';return;}fetch('/preview', {method: 'POST',headers: {'Content-Type': 'application/json',},body: JSON.stringify({code: code,language: language})}).then(response => response.json()).then(data => {if (data.success) {highlightResult.innerHTML = data.html;} else {highlightResult.innerHTML = '高亮生成失败
';}}).catch(error => {console.error('高亮预览错误:', error);highlightResult.innerHTML = '高亮生成失败
';});}// 更新执行效果预览function updateExecutionPreview() {const code = codeTextarea.value;const language = languageSelect.value;if (!code.trim()) {executionResult.innerHTML = '输入代码后,这里会显示执行效果...
';return;}// 根据语言类型执行不同的预览if (language === 'html' || (language === 'auto' && code.trim().startsWith('<'))) {previewHTML(code);} else if (language === 'css' || (language === 'auto' && code.includes('{'))) {previewCSS(code);} else if (language === 'javascript' || (language === 'auto' && (code.includes('function') || code.includes('=>')))) {previewJavaScript(code);} else {executionResult.innerHTML = '此语言类型不支持执行预览
';}}// HTML预览function previewHTML(htmlCode) {// 创建iframe来安全地预览HTMLconst iframe = document.createElement('iframe');iframe.className = 'html-preview-frame';iframe.srcdoc = htmlCode;executionResult.innerHTML = 'HTML渲染效果:
';executionResult.appendChild(iframe);}// CSS预览function previewCSS(cssCode) {executionResult.innerHTML = `CSS样式效果:
这是一个样式预览区域应用的CSS:${cssCode}
`;// 应用CSS样式try {const style = document.createElement('style');style.textContent = cssCode;document.head.appendChild(style);// 清理之前的样式setTimeout(() => {if (document.head.contains(style)) {document.head.removeChild(style);}}, 100);} catch (error) {console.error('CSS应用错误:', error);}}// JavaScript预览function previewJavaScript(jsCode) {executionResult.innerHTML = 'JavaScript执行结果:
';try {// 在安全环境中执行JavaScriptconst result = Function(`"use strict"; ${jsCode}`)();let output = '';if (result !== undefined) {output = typeof result === 'object' ?JSON.stringify(result, null, 2) :String(result);} else {output = '代码已执行,但没有返回值';}executionResult.innerHTML += `执行成功!${output}
`;} catch (error) {executionResult.innerHTML += `执行错误:${error.message}
`;}}// 防抖更新预览function debouncedUpdatePreview() {clearTimeout(previewTimeout);previewTimeout = setTimeout(() => {updateHighlightPreview();// 如果执行效果标签是活跃的,也更新它if (document.querySelector('.preview-tab[data-tab="execution"]').classList.contains('active')) {updateExecutionPreview();}}, 300);}// 事件监听codeTextarea.addEventListener('input', debouncedUpdatePreview);languageSelect.addEventListener('change', debouncedUpdatePreview);// 初始预览updateHighlightPreview();});</script>
3.2templates-index.html
简单代码分享 简单代码分享
快速分享你的代码片段
创建新代码片段功能特性
- 简单易用的代码粘贴
- 实时预览效果
- 自动过期机制(7天)
- 支持多种编程语言
- 原始代码查看
3.3templates-password.html
密码保护 - 代码分享 密码保护
返回首页此代码片段受密码保护
请输入密码查看 "{{ snippet.title }}"
3.4 templates-view.html
{{ snippet.title }} - 简单代码分享 <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script><script>hljs.highlightAll();</script>{{ snippet.title }}
返回首页创建新片段查看原始代码创建时间: {{ snippet.created_at[:16] }}
过期时间: {{ snippet.expires_at[:16] }}
分享链接:
{{ snippet.code }}
4.1 app.py
from flask import Flask, render_template, request, redirect, url_for, jsonify
import uuid
import datetime
import sqlite3
import markdown
import html
import pygments
from pygments import highlight
from pygments.lexers import get_lexer_by_name, guess_lexer
from pygments.formatters import HtmlFormatter
import re
import osapp = Flask(__name__)
app.secret_key = 'your-secret-key-here'# 初始化数据库(包含迁移逻辑)
def init_db():conn = sqlite3.connect('snippets.db')c = conn.cursor()# 创建表(如果不存在)c.execute('''CREATE TABLE IF NOT EXISTS snippets(id TEXT PRIMARY KEY, title TEXT, code TEXT, language TEXT,created_at TIMESTAMP,expires_at TIMESTAMP,password TEXT)''')# 检查并添加缺失的列c.execute("PRAGMA table_info(snippets)")columns = [column[1] for column in c.fetchall()]if 'password' not in columns:c.execute("ALTER TABLE snippets ADD COLUMN password TEXT")print("已添加 password 列到数据库")conn.commit()conn.close()print("数据库初始化完成")def get_db():conn = sqlite3.connect('snippets.db')conn.row_factory = sqlite3.Rowreturn conn# 代码高亮函数
def highlight_code(code, language):try:if language == 'auto':lexer = guess_lexer(code)else:lexer = get_lexer_by_name(language, stripall=True)formatter = HtmlFormatter(linenos=True, cssclass="highlight")result = highlight(code, lexer, formatter)return resultexcept:# 如果高亮失败,返回转义的HTMLreturn f'{html.escape(code)}
'# 主页
@app.route('/')
def index():return render_template('index.html')# 创建代码片段
@app.route('/create', methods=['GET', 'POST'])
def create_snippet():if request.method == 'POST':title = request.form.get('title', 'Untitled')code = request.form.get('code', '')language = request.form.get('language', 'text')password = request.form.get('password', '')snippet_id = str(uuid.uuid4())[:8]created_at = datetime.datetime.now()expires_at = created_at + datetime.timedelta(days=7)conn = get_db()c = conn.cursor()c.execute("INSERT INTO snippets VALUES (?, ?, ?, ?, ?, ?, ?)",(snippet_id, title, code, language, created_at, expires_at, password))conn.commit()conn.close()return redirect(url_for('view_snippet', snippet_id=snippet_id))return render_template('create.html')# 查看代码片段
@app.route('/view/', methods=['GET', 'POST'])
def view_snippet(snippet_id):conn = get_db()c = conn.cursor()c.execute("SELECT * FROM snippets WHERE id = ?", (snippet_id,))snippet = c.fetchone()conn.close()if snippet is None:return "代码片段不存在", 404expires_at = datetime.datetime.fromisoformat(snippet['expires_at'])if datetime.datetime.now() > expires_at:return "此代码片段已过期", 410# 检查密码保护if snippet['password']:if request.method == 'POST':if request.form.get('password') == snippet['password']:# 密码正确,显示代码highlighted_code = highlight_code(snippet['code'], snippet['language'])return render_template('view.html', snippet=snippet, highlighted_code=highlighted_code)else:error = "密码错误"return render_template('password.html', snippet=snippet, error=error)else:return render_template('password.html', snippet=snippet)highlighted_code = highlight_code(snippet['code'], snippet['language'])return render_template('view.html', snippet=snippet, highlighted_code=highlighted_code)# 实时预览API
# 实时预览API - 确保这个路由存在
@app.route('/preview', methods=['POST'])
def preview():try:code = request.json.get('code', '')language = request.json.get('language', 'text')highlighted_code = highlight_code(code, language)return jsonify({'success': True,'html': highlighted_code})except Exception as e:return jsonify({'success': False,'error': str(e)})# 原始代码
@app.route('/raw/')
def raw_snippet(snippet_id):conn = get_db()c = conn.cursor()c.execute("SELECT code FROM snippets WHERE id = ?", (snippet_id,))snippet = c.fetchone()conn.close()if snippet is None:return "代码片段不存在", 404return snippet['code'], 200, {'Content-Type': 'text/plain; charset=utf-8'}if __name__ == '__main__':init_db()app.run(debug=True)