diff --git a/docs/content.md b/docs/content.md index b7afe21..17b093b 100644 --- a/docs/content.md +++ b/docs/content.md @@ -77,6 +77,24 @@ Markdown content here (include your own heading)... The markdown content is rendered as-is, so include your own `# Heading` if desired. +### Supported Markdown Features + +Pages are rendered with [Python-Markdown](https://python-markdown.github.io/) with the following extensions enabled: + +| Feature | Syntax | Notes | +|---------|--------|-------| +| Headings | `# H1` through `### H3` | Rendered with `.prose` styling | +| Bold / Italic | `**bold**`, `*italic*` | Standard Markdown | +| Links | `[text](url)` | Relative paths supported | +| Unordered lists | `- item` or `* item` | Nested lists supported (3 levels) | +| Ordered lists | `1. item` | Nested lists supported (3 levels) | +| Tables | Pipe-delimited (`\| Header \|`) | Auto-generated ``/`
` | +| Fenced code blocks | ` ``` ` with optional language | Syntax highlighting via `codehilite` extension | +| Inline code | `` `code` `` | Styled with monospace font | +| Blockquotes | `> quote` | Left border styling | +| Images | `` | Use absolute paths to `/media/` | +| Table of contents | `[TOC]` marker | Auto-generated from headings | + ## Docker Configuration With Docker, mount the content directory as a read-only volume. This is already configured in `docker-compose.yml`: diff --git a/docs/plans/20260506-1830-markdown-parsing/plan.md b/docs/plans/20260506-1830-markdown-parsing/plan.md new file mode 100644 index 0000000..431e0c6 --- /dev/null +++ b/docs/plans/20260506-1830-markdown-parsing/plan.md @@ -0,0 +1,145 @@ +# Plan: Markdown Nested Lists & Map Collapsible Filters + +Date: 2026-05-06 + +## Part A: Fix Markdown Prose Styling + +### Problem + +Two CSS issues in custom markdown pages: + +1. **Excessive top spacing** — The first element inside `.prose` (typically an `' + ((window.t && window.t('map.owner')) || 'Owner:') + ' ' + ownerDisplay + '
'; - } - - let roleHtml = ''; - if (node.role) { - roleHtml = '' + ((window.t && window.t('map.role')) || 'Role:') + ' ' + escapeHtml(node.role) + '
'; - } - const typeDisplay = getTypeDisplay(node); const nodeTypeEmoji = typeEmoji(node.adv_type); @@ -91,27 +78,39 @@ function createPopupContent(node, oidcEnabled) { infraIndicatorHtml = ' '; } - const lastSeenLabel = (window.t && window.t('common.last_seen_label')) || 'Last seen:'; - const lastSeenHtml = node.last_seen - ? '' + lastSeenLabel + ' ' + node.last_seen.substring(0, 19).replace('T', ' ') + '
' - : ''; - const typeLabel = (window.t && window.t('common.type')) || 'Type:'; const keyLabel = (window.t && window.t('common.key')) || 'Key:'; const locationLabel = (window.t && window.t('common.location')) || 'Location:'; + const lastSeenLabel = (window.t && window.t('common.last_seen_label')) || 'Last seen:'; const unknownLabel = (window.t && window.t('node_types.unknown')) || 'Unknown'; const viewDetailsLabel = (window.t && window.t('common.view_details')) || 'View Details'; + let rows = ''; + rows += '' + escapeHtml(node.public_key.substring(0, 16)) + '...' + typeLabel + ' ' + escapeHtml(typeDisplay) + '
' + - roleHtml + - ownerHtml + - '' + keyLabel + ' ' + escapeHtml(node.public_key.substring(0, 16)) + '...
' + locationLabel + ' ' + node.lat.toFixed(4) + ', ' + node.lon.toFixed(4) + '
' + - lastSeenHtml + - '" in pages[0].content_html
assert "def hello():" in pages[0].content_html
+ def test_markdown_nested_unordered_list(self) -> None:
+ """Test that nested unordered lists produce nested