# How qsgen3 Works ## Table of Contents 1. [Philosophy and Design Principles](#philosophy-and-design-principles) 2. [Project Structure](#project-structure) 3. [Configuration System](#configuration-system) 4. [Theme System](#theme-system) 5. [Creating New Themes](#creating-new-themes) 6. [Content Processing Pipeline](#content-processing-pipeline) 7. [Static File Handling](#static-file-handling) 8. [Template System](#template-system) 9. [Output Generation](#output-generation) 10. [Command Line Interface](#command-line-interface) 11. [Dependencies and Requirements](#dependencies-and-requirements) 12. [Detailed Workflow](#detailed-workflow) 13. [Troubleshooting and Debugging](#troubleshooting-and-debugging) ## Philosophy and Design Principles ### Core Philosophy qsgen3 is designed to be **100% design-agnostic**. It does not impose any specific CSS frameworks, JavaScript libraries, or HTML structures on users. The generator's role is strictly to: 1. Process Markdown content into HTML 2. Combine content with user-chosen templates and styling 3. Generate a complete static site structure ### Key Principles - **Minimal Dependencies**: Only requires Pandoc for content processing - **In-Memory Operations**: All content manipulation occurs in memory to improve performance and reduce storage wear - **Flexible Theme System**: Supports easy switching between themes via configuration - **Template Agnostic**: Works with any Pandoc-compatible HTML templates - **No Forced Assets**: Only automatically links the main theme CSS; all other asset inclusion is explicit ## Project Structure A typical qsgen3 project follows this structure: ``` project-root/ ├── bin/ │ └── qsgen3 # Main generator script ├── site.conf # Main configuration file ├── content/ # Markdown content │ ├── posts/ # Blog posts │ │ └── hello-world.md │ └── pages/ # Static pages ├── layouts/ # Pandoc HTML templates │ ├── index.html # Homepage template │ ├── post.html # Blog post template │ └── rss.xml # RSS feed template ├── static/ # Static assets (CSS, images, etc.) │ ├── css/ │ └── images/ ├── themes/ # Theme directory │ └── theme-name/ # Individual theme │ ├── layouts/ # Theme-specific templates (optional) │ ├── static/ # Theme static assets (optional) │ └── css/ # Alternative theme asset location └── output/ # Generated site (created by qsgen3) ├── index.html ├── rss.xml ├── posts/ └── static/ ``` ## Configuration System ### Primary Configuration: `site.conf` The `site.conf` file uses a simple key-value format: ```bash # Site Metadata site_name="My Awesome Site" site_tagline="A brief description of my site" site_url="http://localhost:8000" # Theme Configuration site_theme="minimal" site_theme_css_file="css/style.css" # Directory Paths paths_content_dir="content" paths_output_dir="output" paths_layouts_dir="layouts" paths_static_dir="static" # Build Options build_options_generate_rss=true build_options_generate_sitemap=true build_options_process_drafts=false ``` ### Configuration Loading Process 1. **File Location**: Defaults to `$PROJECT_ROOT/site.conf` 2. **Override**: Can be specified with `-c ` or `--config ` 3. **Parsing**: Simple line-by-line parsing of `key="value"` pairs 4. **Storage**: Values stored in `QSG_CONFIG` associative array 5. **Validation**: Basic validation for required keys and file existence ### Key Configuration Variables - **`site_theme`**: Name of the active theme (directory name in `themes/`) - **`site_theme_css_file`**: Path to main CSS file relative to theme's static assets - **`site_url`**: Base URL for the site (used in RSS and absolute links) - **`paths_*`**: Directory paths (can be relative or absolute) - **`build_options_*`**: Boolean flags for optional features ## Theme System ### Theme Architecture Themes in qsgen3 provide two main components: 1. **Templates**: Pandoc HTML templates for different page types 2. **Static Assets**: CSS, JavaScript, images, and other resources ### Theme Directory Structure ``` themes/theme-name/ ├── layouts/ # Optional: Override default templates │ ├── index.html # Homepage template │ ├── post.html # Post template │ └── rss.xml # RSS template ├── static/ # Preferred: Standard static assets location │ ├── css/ │ ├── js/ │ └── images/ └── css/ # Alternative: Direct CSS location └── style.css ``` ### Theme Resolution Logic 1. **Theme Selection**: Based on `site_theme` in `site.conf` 2. **Layout Override**: If `themes/theme-name/layouts/` exists, it overrides `paths_layouts_dir` 3. **Static Asset Source**: - First checks for `themes/theme-name/static/` - Falls back to `themes/theme-name/` (for themes with assets at root level) 4. **CSS File Location**: Determined by `site_theme_css_file` relative to theme's static source ### Theme Switching Switching themes is accomplished by: 1. Changing `site_theme` in `site.conf` 2. Updating `site_theme_css_file` to match the new theme's CSS structure 3. Running qsgen3 to regenerate the site ## Creating New Themes ### Theme Development Overview Creating a new theme for qsgen3 involves designing templates and static assets that work together to provide a cohesive visual and functional experience. Themes can range from minimal CSS-only styling to complex designs with custom layouts and interactive elements. ### Step-by-Step Theme Creation #### 1. Create Theme Directory Structure Start by creating a new directory in the `themes/` folder: ```bash mkdir -p themes/my-theme cd themes/my-theme ``` Choose one of these organizational approaches: **Option A: Standard Structure (Recommended)** ``` themes/my-theme/ ├── layouts/ # Custom templates (optional) │ ├── index.html # Homepage template │ ├── post.html # Blog post template │ └── rss.xml # RSS feed template └── static/ # Static assets ├── css/ │ └── style.css # Main stylesheet ├── js/ # JavaScript files (optional) │ └── theme.js └── images/ # Theme images (optional) └── logo.png ``` **Option B: CSS-Only Structure** ``` themes/my-theme/ └── css/ └── style.css # Main stylesheet only ``` #### 2. Create the Main Stylesheet Create your theme's primary CSS file. This is the only asset that qsgen3 will automatically link: ```css /* themes/my-theme/static/css/style.css */ /* Reset and base styles */ * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; background-color: #fff; } /* Header styles */ header { background: #2c3e50; color: white; padding: 1rem 0; margin-bottom: 2rem; } header h1 { max-width: 800px; margin: 0 auto; padding: 0 1rem; } /* Main content */ main { max-width: 800px; margin: 0 auto; padding: 0 1rem; } /* Post styles */ article { margin-bottom: 3rem; padding-bottom: 2rem; border-bottom: 1px solid #eee; } article h1, article h2 { color: #2c3e50; margin-bottom: 0.5rem; } article .meta { color: #666; font-size: 0.9rem; margin-bottom: 1rem; } /* Navigation and links */ nav ul { list-style: none; display: flex; gap: 1rem; } nav a { color: #3498db; text-decoration: none; } nav a:hover { text-decoration: underline; } /* Responsive design */ @media (max-width: 768px) { main { padding: 0 0.5rem; } nav ul { flex-direction: column; gap: 0.5rem; } } ``` #### 3. Create Custom Templates (Optional) If you want to override the default templates, create custom Pandoc templates: **Homepage Template (`layouts/index.html`)** ```html $site_name$ $if(css)$$endif$

$site_name$

$if(site_tagline)$

$site_tagline$

$endif$

Recent Posts

$if(posts)$
    $for(posts)$
  • $it.post_title$

    $if(it.post_date)$$endif$ $if(it.post_author)$ by $it.post_author$$endif$
    $if(it.post_description)$

    $it.post_description$

    $endif$
  • $endfor$
$else$

No posts available.

$endif$

© 2024 $site_name$. Generated with qsgen3.

``` **Post Template (`layouts/post.html`)** ```html $title$ - $site_name$ $if(css)$$endif$ $if(description)$$endif$

$site_name$

$if(site_tagline)$

$site_tagline$

$endif$

$title$

$if(date)$$endif$ $if(author)$ by $author$$endif$
$body$

© 2024 $site_name$. Generated with qsgen3.

``` #### 4. Add JavaScript (Optional) If your theme requires JavaScript functionality, add it to the static assets: ```javascript // themes/my-theme/static/js/theme.js document.addEventListener('DOMContentLoaded', function() { // Add smooth scrolling document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { e.preventDefault(); const target = document.querySelector(this.getAttribute('href')); if (target) { target.scrollIntoView({ behavior: 'smooth' }); } }); }); // Add copy code button functionality document.querySelectorAll('pre code').forEach(block => { const button = document.createElement('button'); button.textContent = 'Copy'; button.className = 'copy-button'; button.addEventListener('click', () => { navigator.clipboard.writeText(block.textContent); button.textContent = 'Copied!'; setTimeout(() => button.textContent = 'Copy', 2000); }); block.parentNode.appendChild(button); }); }); ``` **Important**: Remember that qsgen3 will not automatically include JavaScript files. You must add ` ``` #### 5. Configure Theme Usage Update your `site.conf` to use the new theme: ```bash # Theme Configuration site_theme="my-theme" site_theme_css_file="css/style.css" # Path relative to theme's static source ``` For CSS-only themes using the alternative structure: ```bash site_theme="my-theme" site_theme_css_file="style.css" # Direct path if CSS is at theme root ``` #### 6. Test Your Theme Generate your site to test the theme: ```bash ./bin/qsgen3 ``` Check the output: - Verify CSS is applied correctly - Test responsive design on different screen sizes - Validate HTML structure - Check that all assets are copied correctly ### Theme Development Best Practices #### CSS Guidelines 1. **Use Relative Units**: Prefer `rem`, `em`, and percentages over fixed pixels 2. **Mobile-First Design**: Start with mobile styles, then add desktop enhancements 3. **Semantic Selectors**: Use class names that describe content, not appearance 4. **CSS Custom Properties**: Use CSS variables for consistent theming ```css :root { --primary-color: #2c3e50; --secondary-color: #3498db; --text-color: #333; --background-color: #fff; --border-color: #eee; --font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; } body { color: var(--text-color); background-color: var(--background-color); font-family: var(--font-family); } ``` #### Template Guidelines 1. **Conditional Content**: Use Pandoc's conditional syntax for optional elements 2. **Semantic HTML**: Use appropriate HTML5 semantic elements 3. **Accessibility**: Include proper ARIA labels and alt text 4. **Meta Tags**: Include essential meta tags for SEO and social sharing ```html $if(description)$$endif$ $if(author)$$endif$

$title$

$body$
``` #### Asset Organization 1. **Logical Structure**: Group related assets in appropriate directories 2. **Naming Conventions**: Use consistent, descriptive file names 3. **Optimization**: Optimize images and minimize CSS/JS when possible 4. **Dependencies**: Document any external dependencies clearly ### Advanced Theme Features #### Dark Mode Support Add CSS custom properties and media queries for dark mode: ```css :root { --bg-color: #fff; --text-color: #333; --border-color: #eee; } @media (prefers-color-scheme: dark) { :root { --bg-color: #1a1a1a; --text-color: #e0e0e0; --border-color: #333; } } body { background-color: var(--bg-color); color: var(--text-color); transition: background-color 0.3s ease, color 0.3s ease; } ``` #### Print Styles Include print-specific styles: ```css @media print { header, footer, nav { display: none; } body { font-size: 12pt; line-height: 1.4; } a[href]:after { content: " (" attr(href) ")"; } } ``` #### Custom Fonts If using custom fonts, include them properly: ```css /* Load fonts */ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap'); /* Or use local fonts */ @font-face { font-family: 'CustomFont'; src: url('/static/fonts/custom-font.woff2') format('woff2'), url('/static/fonts/custom-font.woff') format('woff'); font-display: swap; } ``` ### Theme Distribution #### Documentation Create a `README.md` for your theme: ```markdown # My Theme A clean, minimal theme for qsgen3. ## Features - Responsive design - Dark mode support - Clean typography - Fast loading ## Installation 1. Copy theme to `themes/my-theme/` 2. Update `site.conf`: ``` site_theme="my-theme" site_theme_css_file="css/style.css" ``` 3. Run `./bin/qsgen3` ## Customization - Edit CSS custom properties in `style.css` - Modify templates in `layouts/` directory - Add custom JavaScript in `static/js/` ## Browser Support - Modern browsers (Chrome 90+, Firefox 88+, Safari 14+) - Graceful degradation for older browsers ``` #### Version Control If sharing your theme: 1. Use semantic versioning 2. Tag releases appropriately 3. Include a changelog 4. Provide example configurations ### Troubleshooting Theme Development #### Common Issues 1. **CSS Not Loading**: Check `site_theme_css_file` path matches actual file location 2. **Templates Not Found**: Ensure template files are in `layouts/` directory 3. **Assets Missing**: Verify static files are in correct directory structure 4. **JavaScript Errors**: Remember to include `