1
0
mirror of https://gitlab.com/Anson-Projects/projects.git synced 2025-09-14 09:35:04 +00:00

Add Quarto profiles for dual-output rendering

- Add ghost profile for iframe-optimized content
- Create ghost-iframe.css with minimal styling
- Update GitLab CI to build both main site and ghost-content versions
- Ghost profile removes navbar, uses minimal theme, article layout
This commit is contained in:
2025-08-21 23:23:27 -06:00
parent 51c03d9213
commit e233a96f55
4 changed files with 248 additions and 20 deletions

View File

@@ -14,8 +14,10 @@ staging:
stage: deploy stage: deploy
image: ${CI_REGISTRY_IMAGE}:${CI_COMMIT_BRANCH} image: ${CI_REGISTRY_IMAGE}:${CI_COMMIT_BRANCH}
script: script:
- echo "Building the project with Quarto..." - echo "Building the main website with Quarto..."
- quarto render --to html --output-dir public - quarto render --to html --output-dir public
- echo "Building Ghost-optimized version..."
- quarto render --profile ghost --to html --output-dir public/ghost-content
artifacts: artifacts:
paths: paths:
- public - public

80
AGENTS.md Normal file
View File

@@ -0,0 +1,80 @@
# Agent Instructions for Anson's Projects
This repository contains a multi-language technical blog with Rust automation tools, Julia data analysis notebooks, and Quarto documentation.
## Build/Lint/Test Commands
### Rust (ghost-upload/)
- **Build**: `cd ghost-upload && cargo build`
- **Run**: `cd ghost-upload && cargo run`
- **Test**: `cd ghost-upload && cargo test`
- **Lint**: `cd ghost-upload && cargo clippy`
- **Format**: `cd ghost-upload && cargo fmt`
- **Single test**: `cd ghost-upload && cargo test <test_name>`
### Julia (posts/*/ and root)
- **Run notebook**: `julia <filename>.jl`
- **Package management**: `julia -e "using Pkg; Pkg.instantiate()"`
- **Precompile**: `julia -e "using Pkg; Pkg.precompile()"`
### Quarto (Documentation)
- **Build site**: `quarto render --to html --output-dir public`
- **Preview**: `quarto preview`
- **Check**: `quarto check`
### Docker
- **Build**: `docker build -t projects .`
- **Run**: `docker run projects`
## Code Style Guidelines
### Rust
- **Formatting**: Use `cargo fmt` (4-space indentation, standard Rust style)
- **Linting**: Use `cargo clippy` and fix all warnings
- **Imports**: Group by standard library, external crates, then local modules
- **Error Handling**: Prefer `?` operator over `unwrap()`, use custom error types for complex cases
- **Naming**: snake_case for functions/variables, PascalCase for structs/enums
- **Documentation**: Use `///` for public APIs, `//` for implementation details
- **Async**: Use `async fn` for async functions, avoid blocking operations in async contexts
### Julia
- **Formatting**: 4-space indentation, spaces around operators
- **Imports**: Use `using` for packages, group at top of file
- **Naming**: snake_case for functions and variables
- **Types**: Use descriptive names, consider performance implications
- **Plotting**: Use Plots.jl with consistent themes (e.g., `theme(:ggplot2)`)
- **DataFrames**: Use pipe operators `|>` for data transformations
- **Error Handling**: Use try-catch blocks for expected errors
### Quarto (.qmd files)
- **YAML frontmatter**: Include title, date, and relevant metadata
- **Code chunks**: Use appropriate language engines (`{rust}`, `{julia}`, `{python}`)
- **Output**: Set `echo: false` for clean output, `warning: false` to suppress warnings
- **Figures**: Use descriptive captions and alt text
- **Citations**: Use `@citekey` format with bibliography files
### General
- **Git**: Write clear commit messages, use conventional commits when possible
- **Documentation**: Update README.md for significant changes
- **Dependencies**: Keep dependencies minimal and up-to-date
- **Security**: Never commit API keys or sensitive credentials
- **Performance**: Profile code before optimizing, focus on readability first
## Project Structure
- `ghost-upload/`: Rust automation for blog post publishing
- `posts/`: Individual blog posts (Quarto markdown + Julia/Python code)
- Root: Quarto website configuration and shared assets
## Environment Variables
- `kagi_api_key`: For Kagi API summarization (Rust)
- `admin_api_key`: For Ghost CMS API (Rust)
## Testing Strategy
- **Rust**: Unit tests for core functionality, integration tests for API interactions
- **Julia**: Visual validation of plots and data transformations
- **Quarto**: Manual review of rendered output and links
## Deployment
- Uses GitLab CI/CD with Docker
- Deploys to static hosting after Quarto build
- Rust component runs separately for content synchronization

View File

@@ -1,25 +1,42 @@
project: project:
type: website type: website
website: profiles:
title: "Anson's Projects" default:
site-url: https://projects.ansonbiggs.com website:
description: A Blog for Technical Topics title: "Anson's Projects"
navbar: site-url: https://projects.ansonbiggs.com
left: description: A Blog for Technical Topics
- text: "About" navbar:
href: about.html left:
right: - text: "About"
- icon: rss href: about.html
href: index.xml right:
# - icon: gitlab - icon: rss
# href: https://gitlab.com/MisterBiggs href: index.xml
open-graph: true # - icon: gitlab
format: # href: https://gitlab.com/MisterBiggs
html: open-graph: true
theme: zephyr format:
css: styles.css html:
# toc: true theme: zephyr
css: styles.css
# toc: true
ghost:
website:
title: "Anson's Projects"
site-url: https://projects.ansonbiggs.com
description: A Blog for Technical Topics
navbar: false
open-graph: true
format:
html:
theme: none
css: ghost-iframe.css
toc: false
page-layout: article
title-block-banner: false
execute: execute:
freeze: true freeze: true

129
ghost-iframe.css Normal file
View File

@@ -0,0 +1,129 @@
/* Ghost iframe optimized styles */
body {
font-family: system-ui, -apple-system, sans-serif;
line-height: 1.6;
color: #333;
max-width: 100%;
margin: 0;
padding: 20px;
background: white;
}
/* Remove any potential margins/padding */
html, body {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* Ensure content flows naturally */
#quarto-content {
max-width: none;
padding: 0;
margin: 0;
}
/* Style headings for Ghost */
h1, h2, h3, h4, h5, h6 {
margin-top: 1.5em;
margin-bottom: 0.5em;
font-weight: 600;
line-height: 1.3;
}
h1 { font-size: 2em; }
h2 { font-size: 1.5em; }
h3 { font-size: 1.25em; }
/* Code blocks */
pre {
background: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 6px;
padding: 1rem;
overflow-x: auto;
font-size: 0.875em;
}
code {
font-family: "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, "Courier New", monospace;
background: #f1f3f4;
padding: 0.2em 0.4em;
border-radius: 3px;
font-size: 0.875em;
}
pre code {
background: none;
padding: 0;
}
/* Images */
img {
max-width: 100%;
height: auto;
border-radius: 4px;
}
/* Tables */
table {
border-collapse: collapse;
width: 100%;
margin: 1em 0;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
font-weight: 600;
}
/* Links */
a {
color: #0066cc;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
/* Blockquotes */
blockquote {
border-left: 4px solid #ddd;
margin: 1em 0;
padding-left: 1em;
color: #666;
font-style: italic;
}
/* Lists */
ul, ol {
padding-left: 1.5em;
}
li {
margin-bottom: 0.25em;
}
/* Remove any navbar/footer elements that might leak through */
.navbar, .nav, footer, .sidebar, .toc, .page-footer {
display: none !important;
}
/* Ensure responsive behavior for iframe */
@media (max-width: 768px) {
body {
padding: 15px;
font-size: 16px;
}
h1 { font-size: 1.75em; }
h2 { font-size: 1.35em; }
h3 { font-size: 1.15em; }
}