Symark is a program that converts structured notes from the SiYuan note-taking application into HTML pages, creating an interconnected web of documents. It's designed specifically for transforming SiYuan notebooks into a static website, preserving all the rich formatting and interconnections from the original notes.
Symark is organized as a Rust project with the following structure:
symark/
├── src/ # Source code
│ └── main.rs # Main Rust implementation file
├── input/ # Directory for SiYuan notes
│ ├── .siyuan/ # SiYuan metadata
│ └── [note-id].sy # SiYuan note files (JSON format)
├── themes/ # Directory containing themes
│ ├── default/ # Default theme (used as fallback)
│ │ ├── page.html # HTML template for generated pages
│ │ ├── styles.css # CSS styles for the website
│ │ └── graph.html # Graph visualization template
│ └── [theme-name]/ # Additional themes
├── output/ # Generated website (created by Symark)
├── Cargo.toml # Rust project configuration
└── Cargo.lock # Rust dependency lock file
The main workflow involves:
- Reading SiYuan notes from the
input/directory - Processing them using the code in
src/main.rs - Applying templates from the selected theme in the
themes/[theme-name]/directory - Generating the final website in the
output/directory
Symark is built specifically to work with SiYuan, an open-source personal knowledge management system. SiYuan stores notes as .sy files in JSON format, which Symark processes to generate HTML.
Key SiYuan features that Symark preserves:
- Bidirectional links between notes
- Block references and transclusion
- Hierarchical document structure
- Rich formatting and markdown extensions
- Custom styling for blocks and notes
- Tagging system
The data structures in Symark directly map to SiYuan's internal representation of notes, ensuring faithful reproduction of content.
The Note structure represents a complete note document:
- ID: Unique identifier for the note
- Spec: Specification version
- Type: Type of the note
- Properties: Metadata about the note (title, tags, etc.)
- Children: The content blocks that make up the note
The Properties structure contains metadata about a note:
- id: Unique identifier
- title: Title of the note
- title_img: Optional image for the note header
- tags: List of tags associated with the note
- note_type: Type of note
- updated: Last updated timestamp
- created: Creation timestamp
- style: Custom style information
- parent_style: Style inherited from parent
The Block structure represents a content element within a note, directly mapping to SiYuan's block-based document model:
- ID: Unique identifier for the block (SiYuan uses a timestamp-based ID system)
- Type: The block type (heading, paragraph, list, etc.)
- Data: Content data
- Properties: Block-specific properties
- Children: Nested blocks
- Various specialized fields for different block types:
- HeadingLevel: For heading blocks (h1-h6)
- ListData: For ordered and unordered lists
- TableAligns: For table column alignment
- TextMarkType: For inline formatting
- TextMarkAHref: For hyperlinks
- TextMarkBlockRefID: For block references (a key SiYuan feature)
- CodeBlockInfo: For syntax highlighting in code blocks
- TaskListItemChecked: For task lists with checkboxes
The TocItem structure is used to build a table of contents:
- id: ID of the heading block
- text: Text content of the heading
- level: Heading level (1-6)
- Main Function: Orchestrates the entire process, from finding notes to generating HTML
- Finding Notes:
find_sy_filesdiscovers all note files in the source directory - Asset Management:
find_and_copy_assetsandcopy_directoryhandle static assets
- Note Rendering:
generate_html_for_noteconverts a single note to HTML - Block Rendering:
render_blocksprocesses blocks and their children recursivelyrender_blocks_with_idsprocesses blocks with specific IDs (for cross-referencing)render_blockdispatches rendering to appropriate handler based on block typerender_text_markhandles inline formatting, links, and referencesfind_block_by_idandfind_content_by_idsupport cross-referencing between blocks
-
Index Pages:
generate_index_pagecreates the main landing pagegenerate_custom_index_pagecreates customized index pagesgenerate_all_notes_pagecreates a page listing all notesgenerate_tag_pagecreates pages for browsing notes by tag
-
Table of Contents:
extract_toc_itemsidentifies headings within a notegenerate_toc_htmlcreates a navigable table of contents
- Template Management:
read_templateloads HTML templates - Date Formatting:
naturalize_dateconverts timestamps to human-readable format - HTML Helpers:
escape_htmlprevents HTML injectionremove_zero_width_spacescleans up textget_style_classdetermines styling for elements
-
The program starts by finding all
.syfiles (SiYuan's JSON note format) in a specified directory usingfind_sy_files -
For each note file:
- Parse the note structure into the
Notedata structure - Extract headings to build a table of contents using
extract_toc_items - Generate HTML representation of the note content via
generate_html_for_note- The note's blocks are rendered recursively through
render_blocks - Different block types (paragraphs, headings, lists, code blocks, etc.) are handled with specialized logic
- Text marks (formatting, links, references) are processed by
render_text_mark
- The note's blocks are rendered recursively through
- Create navigation elements (table of contents, links to related notes)
- Apply styling and formatting based on note properties
- Parse the note structure into the
-
Generate index pages:
- Main index page via
generate_index_page - Custom index pages via
generate_custom_index_page - Tag-based index pages via
generate_tag_page - Complete note listing via
generate_all_notes_page
- Main index page via
-
Copy any associated assets (images, CSS, etc.) using
find_and_copy_assetsandcopy_directory
This system appears designed for:
- Converting private notes into a publishable format
- Creating a knowledge base or documentation site
- Building a personal wiki from structured notes
The flexibility in the block rendering system suggests it can handle a variety of content types, including text, lists, tables, code blocks, and embedded media.
Symark features a robust tagging system that creates connections between related notes:
- Tag Storage: Tags are stored in the
Properties.tagsfield of each note - Tag Page Generation: The
generate_tag_pagefunction creates dedicated pages for each tag - Tag Filtering:
filter_index_taghelps process and organize tags - Tag-Based Navigation: Notes with matching tags are linked together, creating a web of related content
The tag system enables:
- Categorization of notes by topic or purpose
- Discovery of related content
- Creation of custom collections based on tag combinations
- Improved navigation between thematically connected notes
The heart of Symark is its block rendering system. Here's how it works:
-
Block Type Identification: The
render_blocksfunction processes each block based on itsTypefield:- Paragraphs
- Headings (with levels 1-6)
- Lists (ordered, unordered, and task lists)
- Code blocks (with syntax highlighting support)
- Tables
- Blockquotes
- HTML blocks
- And more specialized types
-
Text Formatting: Within text blocks,
render_text_markhandles:- Basic formatting (bold, italic, underline, strikethrough)
- Links (external URLs and internal references)
- Code spans
- Superscript and subscript
- Highlighting
- Block references (linking to other blocks by ID)
- Inline memos
-
Cross-References: The system supports references between notes:
find_block_by_idlocates blocks by their unique identifiersfind_content_by_idextracts content from referenced blocksNodeBlockQueryEmbedhandles transclusions within other notes- This enables a wiki-like navigation experience between notes
-
HTML Safety and SiYuan Compatibility: Several safeguards ensure the generated HTML is safe and valid:
escape_htmlprevents HTML injection in user contentremove_zero_width_spacescleans up text to improve rendering (SiYuan uses zero-width spaces in certain contexts)get_style_classtranslates SiYuan's custom styling variables into appropriate HTML/CSS classes- Careful handling of nested structures (lists within lists, etc.)
-
Navigation Generation: For each note, the system:
- Extracts headings to build a table of contents via
extract_toc_items - Generates a hierarchical TOC via
generate_toc_html - Adds a back navigation link (defined in
BACK_NAVIGATION_HTML) - Creates links to related notes based on tags
- Extracts headings to build a table of contents via
This sophisticated rendering pipeline transforms structured note data into a rich, interconnected HTML document collection that preserves the relationships and formatting of the original notes.
Symark uses a themeable templating system to generate consistent HTML pages:
-
HTML Template: The
themes/[theme-name]/page.htmlfile provides the structure for each generated page, with placeholders for:- Page title
- Content
- Navigation elements
- Metadata
-
CSS Styling: The
themes/[theme-name]/styles.cssfile contains all styling for the generated website, including:- Basic typography and layout
- Special formatting for different block types
- Responsive design elements
- Navigation styling
-
Graph Template: The
themes/[theme-name]/graph.htmlfile provides the structure for the interactive graph visualization page.
The themeable templating system allows for consistent presentation across all generated pages while injecting the specific content and structure of each note. Multiple themes can be created and selected at generation time, with the default theme serving as a fallback when selected themes are missing files.
Symark includes a sophisticated date handling system through the naturalize_date function, which converts SiYuan's timestamp format (YYYYMMDD) into human-readable dates. This function:
- Recognizes SiYuan's date format patterns
- Converts numeric dates to natural language formats
- Handles relative dates (yesterday, last week, etc.)
- Supports both date-only and datetime formats
Symark is a powerful tool specifically designed for converting SiYuan notes into an interconnected web of HTML documents. Its key strengths include:
- SiYuan Compatibility: Deep integration with SiYuan's note format and features
- Flexible Content Rendering: Support for all SiYuan content types and formatting
- Relationship Preservation: Maintains connections between notes through references and tags
- Navigation Enhancement: Generates tables of contents, tag pages, and index pages
- Asset Management: Handles images and other resources required by the notes
The system allows knowledge captured in SiYuan to be transformed into a publishable format while preserving the rich structure and interconnections that make personal knowledge management systems valuable. By generating static HTML, the resulting site can be easily hosted and shared without requiring specialized server infrastructure.
Symark bridges the gap between personal note-taking in SiYuan and public knowledge sharing, making it easier to transform private notes into documentation, wikis, or knowledge bases that can be shared with others. It's an excellent example of extending a personal knowledge management system with publishing capabilities.
As a Rust project, Symark can be built using standard Cargo commands:
cargo build --release
Basic usage involves:
- Placing SiYuan notes in the
input/directory - Running the Symark executable with an optional theme name:
# Use default theme cargo run # Use a specific theme (falls back to default theme if files are missing) cargo run my-theme - Accessing the generated website from the
output/directory
The system is designed to be simple to use while providing powerful conversion capabilities.