wip
This commit is contained in:
parent
7ce4914ea1
commit
94ededdf69
9 changed files with 2894 additions and 44 deletions
|
@ -37,8 +37,12 @@ def create_app(config_name="development"):
|
|||
|
||||
# Register template filters
|
||||
from app.core.template_filters import bp as filters_bp
|
||||
from app.core.template_filters import markdown_filter
|
||||
|
||||
app.register_blueprint(filters_bp)
|
||||
|
||||
# Register the markdown filter directly
|
||||
app.jinja_env.filters['markdown'] = markdown_filter
|
||||
|
||||
# Create database tables without seeding any data
|
||||
with app.app_context():
|
||||
|
|
|
@ -7,35 +7,75 @@ bp = Blueprint("filters", __name__)
|
|||
|
||||
|
||||
def github_style_admonition(text):
|
||||
"""Transform GitHub-style alerts (> [!NOTE], etc.) to custom HTML"""
|
||||
patterns = {
|
||||
r"> \[!NOTE\](.*?)(?:\n\n|\Z)": '<div class="markdown-alert markdown-alert-note"><p class="markdown-alert-title">Note</p>\\1</div>',
|
||||
r"> \[!TIP\](.*?)(?:\n\n|\Z)": '<div class="markdown-alert markdown-alert-tip"><p class="markdown-alert-title">Tip</p>\\1</div>',
|
||||
r"> \[!IMPORTANT\](.*?)(?:\n\n|\Z)": '<div class="markdown-alert markdown-alert-important"><p class="markdown-alert-title">Important</p>\\1</div>',
|
||||
r"> \[!WARNING\](.*?)(?:\n\n|\Z)": '<div class="markdown-alert markdown-alert-warning"><p class="markdown-alert-title">Warning</p>\\1</div>',
|
||||
r"> \[!CAUTION\](.*?)(?:\n\n|\Z)": '<div class="markdown-alert markdown-alert-caution"><p class="markdown-alert-title">Caution</p>\\1</div>',
|
||||
}
|
||||
|
||||
for pattern, replacement in patterns.items():
|
||||
text = re.sub(pattern, replacement, text, flags=re.DOTALL)
|
||||
|
||||
return text
|
||||
"""Transform GitHub-style alerts (> [!NOTE], etc.) to custom HTML with GitHub styling"""
|
||||
# Process the text line by line for better control
|
||||
lines = text.split('\n')
|
||||
result_lines = []
|
||||
i = 0
|
||||
|
||||
while i < len(lines):
|
||||
line = lines[i]
|
||||
|
||||
# Check if this line starts a GitHub-style alert
|
||||
alert_match = re.match(r'>\s*\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\]\s*(.*)', line)
|
||||
|
||||
if alert_match:
|
||||
# Found an alert start
|
||||
alert_type = alert_match.group(1).lower()
|
||||
first_line_content = alert_match.group(2).strip()
|
||||
|
||||
# Collect all continuation lines (those starting with >)
|
||||
alert_content = [first_line_content] if first_line_content else []
|
||||
j = i + 1
|
||||
|
||||
while j < len(lines) and lines[j].strip().startswith('>'):
|
||||
# Remove the > and one optional space after it
|
||||
content = re.sub(r'^>\s?', '', lines[j].strip())
|
||||
alert_content.append(content)
|
||||
j += 1
|
||||
|
||||
# Create the HTML for the alert with proper styling
|
||||
alert_html = f'<div class="markdown-alert markdown-alert-{alert_type}">\n'
|
||||
alert_html += f'<p class="markdown-alert-title">{alert_type.capitalize()}</p>\n'
|
||||
|
||||
# Join the content with line breaks
|
||||
if alert_content:
|
||||
alert_html += '\n'.join(alert_content)
|
||||
|
||||
alert_html += '\n</div>'
|
||||
|
||||
# Add the processed alert HTML
|
||||
result_lines.append(alert_html)
|
||||
|
||||
# Move past all the lines we've processed
|
||||
i = j
|
||||
else:
|
||||
# Not an alert line, add it unchanged
|
||||
result_lines.append(line)
|
||||
i += 1
|
||||
|
||||
return '\n'.join(result_lines)
|
||||
|
||||
|
||||
@bp.app_template_filter("markdown")
|
||||
def markdown_filter(text):
|
||||
"""Convert markdown text to HTML with support for GitHub-style features"""
|
||||
if text:
|
||||
# Pre-process GitHub-style alerts
|
||||
text = github_style_admonition(text)
|
||||
|
||||
# Convert to HTML with regular markdown
|
||||
html = md_package.markdown(
|
||||
text, extensions=["tables", "fenced_code", "codehilite", "nl2br"]
|
||||
)
|
||||
|
||||
return html
|
||||
return ""
|
||||
"""Convert markdown text to HTML with proper GitHub styling for all elements"""
|
||||
if not text:
|
||||
return ""
|
||||
|
||||
# First process GitHub-style alerts
|
||||
processed_text = github_style_admonition(text)
|
||||
|
||||
# Convert to HTML with standard markdown
|
||||
html = md_package.markdown(
|
||||
processed_text,
|
||||
extensions=["tables", "fenced_code", "codehilite", "nl2br", "sane_lists", "smarty"]
|
||||
)
|
||||
|
||||
# Wrap in GitHub's markdown reading view class for consistent styling
|
||||
html = f'<div class="markdown-reading-view">{html}</div>'
|
||||
|
||||
return html
|
||||
|
||||
|
||||
@bp.app_template_filter("ip_network")
|
||||
|
|
|
@ -173,4 +173,299 @@
|
|||
|
||||
[data-bs-theme="light"] .documentation-wrapper {
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* Markdown admonition styling */
|
||||
.markdown-content .admonition {
|
||||
padding: 1rem;
|
||||
margin: 1.5rem 0;
|
||||
border-radius: 0.375rem;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.markdown-content .admonition-title {
|
||||
font-weight: 600;
|
||||
margin: -1rem -1rem 0.8rem -1rem;
|
||||
padding: 0.5rem 1rem;
|
||||
border-top-left-radius: 0.375rem;
|
||||
border-top-right-radius: 0.375rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.markdown-content .admonition-title::before {
|
||||
margin-right: 0.5rem;
|
||||
font-family: "tabler-icons";
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
/* Note styling */
|
||||
.markdown-content .admonition.note {
|
||||
background-color: rgba(66, 153, 225, 0.1);
|
||||
border-left: 4px solid #4299e1;
|
||||
}
|
||||
|
||||
.markdown-content .admonition.note .admonition-title {
|
||||
background-color: rgba(66, 153, 225, 0.15);
|
||||
color: #2b6cb0;
|
||||
}
|
||||
|
||||
.markdown-content .admonition.note .admonition-title::before {
|
||||
content: "\ea67";
|
||||
/* ti-info-circle */
|
||||
}
|
||||
|
||||
/* Tip styling */
|
||||
.markdown-content .admonition.tip {
|
||||
background-color: rgba(72, 187, 120, 0.1);
|
||||
border-left: 4px solid #48bb78;
|
||||
}
|
||||
|
||||
.markdown-content .admonition.tip .admonition-title {
|
||||
background-color: rgba(72, 187, 120, 0.15);
|
||||
color: #2f855a;
|
||||
}
|
||||
|
||||
.markdown-content .admonition.tip .admonition-title::before {
|
||||
content: "\ea4a";
|
||||
/* ti-bulb */
|
||||
}
|
||||
|
||||
/* Important styling */
|
||||
.markdown-content .admonition.important {
|
||||
background-color: rgba(118, 106, 240, 0.1);
|
||||
border-left: 4px solid #766af0;
|
||||
}
|
||||
|
||||
.markdown-content .admonition.important .admonition-title {
|
||||
background-color: rgba(118, 106, 240, 0.15);
|
||||
color: #5046e4;
|
||||
}
|
||||
|
||||
.markdown-content .admonition.important .admonition-title::before {
|
||||
content: "\eaca";
|
||||
/* ti-star */
|
||||
}
|
||||
|
||||
/* Warning styling */
|
||||
.markdown-content .admonition.warning {
|
||||
background-color: rgba(246, 173, 85, 0.1);
|
||||
border-left: 4px solid #f6ad55;
|
||||
}
|
||||
|
||||
.markdown-content .admonition.warning .admonition-title {
|
||||
background-color: rgba(246, 173, 85, 0.15);
|
||||
color: #c05621;
|
||||
}
|
||||
|
||||
.markdown-content .admonition.warning .admonition-title::before {
|
||||
content: "\eb4f";
|
||||
/* ti-alert-triangle */
|
||||
}
|
||||
|
||||
/* Danger/Caution styling */
|
||||
.markdown-content .admonition.danger {
|
||||
background-color: rgba(245, 101, 101, 0.1);
|
||||
border-left: 4px solid #f56565;
|
||||
}
|
||||
|
||||
.markdown-content .admonition.danger .admonition-title {
|
||||
background-color: rgba(245, 101, 101, 0.15);
|
||||
color: #c53030;
|
||||
}
|
||||
|
||||
.markdown-content .admonition.danger .admonition-title::before {
|
||||
content: "\eb50";
|
||||
/* ti-alert-octagon */
|
||||
}
|
||||
|
||||
/* Dark mode adjustments */
|
||||
[data-bs-theme="dark"] .markdown-content .admonition.note {
|
||||
background-color: rgba(56, 127, 187, 0.15);
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .markdown-content .admonition.tip {
|
||||
background-color: rgba(56, 161, 105, 0.15);
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .markdown-content .admonition.important {
|
||||
background-color: rgba(102, 92, 209, 0.15);
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .markdown-content .admonition.warning {
|
||||
background-color: rgba(221, 155, 76, 0.15);
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .markdown-content .admonition.danger {
|
||||
background-color: rgba(224, 92, 92, 0.15);
|
||||
}
|
||||
|
||||
/* Make sure the markdown content text color is visible */
|
||||
.markdown-content {
|
||||
color: var(--tblr-body-color);
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .markdown-content {
|
||||
color: #e1e3e6;
|
||||
}
|
||||
|
||||
/* Fix the app name in the expanded accordion */
|
||||
.app-card-header .app-link {
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* GitHub-style markdown alerts */
|
||||
.markdown-alert {
|
||||
padding: 0.85rem 1rem;
|
||||
margin: 1rem 0;
|
||||
border-radius: 0.375rem;
|
||||
border-left-width: 4px;
|
||||
border-left-style: solid;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.markdown-alert-title {
|
||||
font-weight: 600;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
font-size: 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.markdown-alert-title::before {
|
||||
margin-right: 0.5rem;
|
||||
font-family: "tabler-icons";
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
/* Individual alert types */
|
||||
/* Note styling */
|
||||
.markdown-alert-note {
|
||||
background-color: rgba(66, 153, 225, 0.1);
|
||||
border-left-color: #4299e1;
|
||||
}
|
||||
|
||||
.markdown-alert-note .markdown-alert-title {
|
||||
color: #2b6cb0;
|
||||
}
|
||||
|
||||
.markdown-alert-note .markdown-alert-title::before {
|
||||
content: "\ea67";
|
||||
/* ti-info-circle */
|
||||
}
|
||||
|
||||
/* Tip styling */
|
||||
.markdown-alert-tip {
|
||||
background-color: rgba(72, 187, 120, 0.1);
|
||||
border-left-color: #48bb78;
|
||||
}
|
||||
|
||||
.markdown-alert-tip .markdown-alert-title {
|
||||
color: #2f855a;
|
||||
}
|
||||
|
||||
.markdown-alert-tip .markdown-alert-title::before {
|
||||
content: "\ea4a";
|
||||
/* ti-bulb */
|
||||
}
|
||||
|
||||
/* Important styling */
|
||||
.markdown-alert-important {
|
||||
background-color: rgba(118, 106, 240, 0.1);
|
||||
border-left-color: #766af0;
|
||||
}
|
||||
|
||||
.markdown-alert-important .markdown-alert-title {
|
||||
color: #5046e4;
|
||||
}
|
||||
|
||||
.markdown-alert-important .markdown-alert-title::before {
|
||||
content: "\eaca";
|
||||
/* ti-star */
|
||||
}
|
||||
|
||||
/* Warning styling */
|
||||
.markdown-alert-warning {
|
||||
background-color: rgba(246, 173, 85, 0.1);
|
||||
border-left-color: #f6ad55;
|
||||
}
|
||||
|
||||
.markdown-alert-warning .markdown-alert-title {
|
||||
color: #c05621;
|
||||
}
|
||||
|
||||
.markdown-alert-warning .markdown-alert-title::before {
|
||||
content: "\eb4f";
|
||||
/* ti-alert-triangle */
|
||||
}
|
||||
|
||||
/* Caution styling */
|
||||
.markdown-alert-caution {
|
||||
background-color: rgba(245, 101, 101, 0.1);
|
||||
border-left-color: #f56565;
|
||||
}
|
||||
|
||||
.markdown-alert-caution .markdown-alert-title {
|
||||
color: #c53030;
|
||||
}
|
||||
|
||||
.markdown-alert-caution .markdown-alert-title::before {
|
||||
content: "\eb50";
|
||||
/* ti-alert-octagon */
|
||||
}
|
||||
|
||||
/* Dark mode adjustments */
|
||||
[data-bs-theme="dark"] .markdown-alert-note {
|
||||
background-color: rgba(56, 127, 187, 0.15);
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .markdown-alert-tip {
|
||||
background-color: rgba(56, 161, 105, 0.15);
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .markdown-alert-important {
|
||||
background-color: rgba(102, 92, 209, 0.15);
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .markdown-alert-warning {
|
||||
background-color: rgba(221, 155, 76, 0.15);
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .markdown-alert-caution {
|
||||
background-color: rgba(224, 92, 92, 0.15);
|
||||
}
|
||||
|
||||
/* Fix content inside alerts */
|
||||
.markdown-alert p {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.markdown-alert p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* Ensure proper spacing for code in alerts */
|
||||
.markdown-alert code {
|
||||
background-color: rgba(0, 0, 0, 0.07);
|
||||
border-radius: 3px;
|
||||
padding: 0.2em 0.4em;
|
||||
font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, monospace;
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .markdown-alert code {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
/* Fix port display in accordion headers */
|
||||
.accordion-button .badge {
|
||||
font-size: 0.7rem;
|
||||
padding: 0.25em 0.5em;
|
||||
margin-right: 0.25rem;
|
||||
}
|
||||
|
||||
/* Add compatibility classes for GitHub markdown */
|
||||
.markdown-content .markdown-reading-view {
|
||||
width: 100%;
|
||||
}
|
1258
app/static/css/github-markdown-reading-view.css
Normal file
1258
app/static/css/github-markdown-reading-view.css
Normal file
File diff suppressed because it is too large
Load diff
1258
app/static/css/github-markdown-source-view.css
Normal file
1258
app/static/css/github-markdown-source-view.css
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,14 +0,0 @@
|
|||
/* GitHub Markdown CSS (simplified version) */
|
||||
.markdown-body {
|
||||
box-sizing: border-box;
|
||||
min-width: 200px;
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
padding: 45px;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.markdown-body {
|
||||
padding: 15px;
|
||||
}
|
||||
}
|
|
@ -145,8 +145,15 @@
|
|||
placeholder="Enter documentation in Markdown format">{{ app.documentation if app else '' }}</textarea>
|
||||
<small class="form-hint">
|
||||
Use <a href="https://www.markdownguide.org/basic-syntax/" target="_blank">Markdown syntax</a>
|
||||
to format your documentation. The content will be rendered when viewing the application.
|
||||
to format your documentation. You can use GitHub-style alerts:
|
||||
</small>
|
||||
<div class="mt-2 d-flex gap-2 flex-wrap">
|
||||
<code>> [!NOTE] This is a note</code>
|
||||
<code>> [!TIP] This is a tip</code>
|
||||
<code>> [!IMPORTANT] Important info</code>
|
||||
<code>> [!WARNING] Warning message</code>
|
||||
<code>> [!CAUTION] Critical caution</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-footer">
|
||||
|
|
|
@ -138,7 +138,8 @@
|
|||
aria-controls="app-collapse-{{ app.id }}">
|
||||
<span class="me-2">{{ app.name }}</span>
|
||||
{% for port in app.ports %}
|
||||
<span class="badge bg-primary mx-1">{{ port.number }}/{{ port.protocol }}</span>
|
||||
<span class="badge bg-primary">{% if port.port_number %}{{ port.port_number }}{% elif port.number %}{{
|
||||
port.number }}{% endif %}/{{ port.protocol }}</span>
|
||||
{% endfor %}
|
||||
</button>
|
||||
</h2>
|
||||
|
@ -171,7 +172,7 @@
|
|||
|
||||
<!-- Documentation section with improved styling -->
|
||||
<div class="documentation-wrapper p-3">
|
||||
<div class="markdown-content theme-styled">
|
||||
<div class="markdown-content">
|
||||
{% if app.documentation %}
|
||||
{{ app.documentation|markdown|safe }}
|
||||
{% else %}
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
<link rel="stylesheet" href="{{ url_for('static', filename='libs/tabler-icons/tabler-icons.min.css') }}"
|
||||
onerror="this.onerror=null;this.href='https://cdn.jsdelivr.net/npm/@tabler/icons@latest/iconfont/tabler-icons.min.css';">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/custom.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/markdown.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/github-markdown-reading-view.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/github-markdown-source-view.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/theme.css') }}">
|
||||
<!-- Favicon -->
|
||||
<link rel="icon" type="image/png" href="{{ url_for('static', filename='img/favicon.png') }}">
|
||||
|
@ -604,4 +605,4 @@
|
|||
{% block scripts %}{% endblock %}
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue