Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
[![release](https://github.com/axodotdev/oranda/actions/workflows/release.yml/badge.svg)](https://github.com/axodotdev/oranda/actions/workflows/release.yml)
[![web](https://github.com/axodotdev/oranda/actions/workflows/web.yml/badge.svg?branch=main)](https://github.com/axodotdev/oranda/actions/workflows/web.yml)

See [security](./SECURITY.md)

`oranda` is an opinionated static-site generator that is designed for developers
who are publishing projects and would like a website but don't want to build
Expand Down
5 changes: 4 additions & 1 deletion oranda.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"build": {
"path_prefix": "oranda"
"path_prefix": "oranda",
"additional_pages": {
"security": "SECURITY.md"
}
},
"styles": {
"theme": "axodark",
Expand Down
8 changes: 6 additions & 2 deletions src/data/funding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ pub enum FundingContent {

impl Funding {
/// Creates a new Funding struct by attempting to read from the FUNDING.yml, and the docs file.
pub fn new(funding_cfg: &FundingConfig, style_cfg: &StyleConfig) -> Result<Self> {
pub fn new(
path_prefix: &Option<String>,
funding_cfg: &FundingConfig,
style_cfg: &StyleConfig,
) -> Result<Self> {
let mut funding = if let Some(yml_path) = &funding_cfg.yml_path {
match LocalAsset::load_string(yml_path) {
Ok(res) => {
Expand All @@ -66,7 +70,7 @@ impl Funding {

if let Some(md_path) = &funding_cfg.md_path {
let res = LocalAsset::load_string(md_path)?;
let html = to_html(&res, &style_cfg.syntax_theme)?;
let html = to_html(&res, &style_cfg.syntax_theme, path_prefix)?;
funding.docs_content = Some(html);
}

Expand Down
6 changes: 5 additions & 1 deletion src/site/changelog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,11 @@ fn build_release_body(release: &Release, config: &Config) -> Result<String> {
release.source.body().unwrap_or_default().to_owned()
};

markdown::to_html(&contents, &config.styles.syntax_theme)
markdown::to_html(
&contents,
&config.styles.syntax_theme,
&config.build.path_prefix,
)
}

fn build_prerelease_toggle(has_prereleases: bool) -> Option<Box<div<String>>> {
Expand Down
31 changes: 28 additions & 3 deletions src/site/markdown/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::collections::HashMap;
use std::io::BufWriter;

mod syntax_highlight;
pub use syntax_highlight::syntax_themes::SyntaxTheme;
Expand All @@ -8,7 +9,7 @@ use crate::errors::*;

use ammonia::Builder;
use comrak::adapters::SyntaxHighlighterAdapter;
use comrak::{self, ComrakOptions, ComrakPlugins};
use comrak::{self, Arena, ComrakOptions, ComrakPlugins};

pub struct Adapters<'a> {
syntax_theme: &'a SyntaxTheme,
Expand Down Expand Up @@ -47,14 +48,38 @@ fn initialize_comrak_options() -> ComrakOptions {
options
}

pub fn to_html(markdown: &str, syntax_theme: &SyntaxTheme) -> Result<String> {
pub fn to_html(
markdown: &str,
syntax_theme: &SyntaxTheme,
path_prefix: &Option<String>,
) -> Result<String> {
let options = initialize_comrak_options();

let mut plugins = ComrakPlugins::default();
let adapter = Adapters { syntax_theme };
plugins.render.codefence_syntax_highlighter = Some(&adapter);

let unsafe_html = comrak::markdown_to_html_with_plugins(markdown, &options, &plugins);
// Build the markdown AST
let arena = Arena::new();
let root: &comrak::arena_tree::Node<'_, std::cell::RefCell<comrak::nodes::Ast>> =
comrak::parse_document(&arena, markdown, &options);

// Edit links in the markdown AST
for node in root.descendants() {
let mut node = node.data.borrow_mut();
if let comrak::nodes::NodeValue::Link(link) = &mut node.value {
if link.url.contains("./SECURITY.md") {
link.url = crate::site::link::generate(path_prefix, "SECURITY/");
}
}
}

// Render the markdown AST to HTML
let mut bw = BufWriter::new(Vec::new());
comrak::format_html_with_plugins(root, &options, &mut bw, &plugins).unwrap();
let unsafe_html = String::from_utf8(bw.into_inner().unwrap()).unwrap();

// Sanitize the html
let safe_html = Builder::new()
.add_generic_attributes(&["style", "class", "id"])
.clean(&unsafe_html)
Expand Down
2 changes: 1 addition & 1 deletion src/site/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ impl Site {
pages.append(&mut changelog_pages);
}
if let Some(funding_cfg) = &config.components.funding {
let funding = Funding::new(funding_cfg, &config.styles)?;
let funding = Funding::new(&config.build.path_prefix, funding_cfg, &config.styles)?;
let body = funding::page(config, &funding)?;
let page = Page::new_from_contents(body, "funding.html", &layout_template, config);
pages.push(page);
Expand Down
22 changes: 18 additions & 4 deletions src/site/page/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ impl Page {
let readme = Self::load_and_render_contents(
&config.project.readme_path,
&config.styles.syntax_theme,
&config.build.path_prefix,
)?;
body.push_str(&readme);
let os_script = javascript::build_os_script(&config.build.path_prefix);
Expand All @@ -43,6 +44,7 @@ impl Page {
let body = Self::load_and_render_contents(
&config.project.readme_path,
&config.styles.syntax_theme,
&config.build.path_prefix,
)?;
let contents = layout.render(body, None);
Ok(Page {
Expand All @@ -52,7 +54,11 @@ impl Page {
}

pub fn new_from_file(source: &str, layout: &Layout, config: &Config) -> Result<Self> {
let body = Self::load_and_render_contents(source, &config.styles.syntax_theme)?;
let body = Self::load_and_render_contents(
source,
&config.styles.syntax_theme,
&config.build.path_prefix,
)?;
let contents = layout.render(body, None);
Ok(Page {
contents,
Expand All @@ -61,7 +67,11 @@ impl Page {
}

pub fn new_from_file_with_dir(source: &str, layout: &Layout, config: &Config) -> Result<Self> {
let body = Self::load_and_render_contents(source, &config.styles.syntax_theme)?;
let body = Self::load_and_render_contents(
source,
&config.styles.syntax_theme,
&config.build.path_prefix,
)?;
let contents = layout.render(body, None);
// Try diffing with the execution directory in case the user has provided an absolute-ish
// path, in order to obtain the relative-to-dir path segment
Expand Down Expand Up @@ -90,10 +100,14 @@ impl Page {
}
}

fn load_and_render_contents(source: &str, syntax_theme: &SyntaxTheme) -> Result<String> {
fn load_and_render_contents(
source: &str,
syntax_theme: &SyntaxTheme,
path_prefix: &Option<String>,
) -> Result<String> {
let source = SourceFile::load_local(source)?;
let contents = source.contents();
markdown::to_html(contents, syntax_theme).map(|html| {
markdown::to_html(contents, syntax_theme, path_prefix).map(|html| {
let html: Box<div<String>> = html!(
<div class="rendered-markdown">
{unsafe_text!(html)}
Expand Down
14 changes: 12 additions & 2 deletions tests/build/fixtures/page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@ fn reset(dist_dir: &str) {

pub fn index(config: &Config, layout: &Layout) -> Page {
reset(&config.build.dist_dir);
let body = markdown::to_html(readme(), &config.styles.syntax_theme).unwrap();
let body = markdown::to_html(
readme(),
&config.styles.syntax_theme,
&config.build.path_prefix,
)
.unwrap();
Page::new_from_contents(body, "index.html", layout, config)
}

Expand All @@ -60,7 +65,12 @@ pub fn index_with_artifacts(config: &Config, layout: &Layout) -> Page {

pub fn index_with_warning(config: &Config, layout: &Layout) -> Page {
reset(&config.build.dist_dir);
let body = markdown::to_html(readme_invalid_annotation(), &config.styles.syntax_theme).unwrap();
let body = markdown::to_html(
readme_invalid_annotation(),
&config.styles.syntax_theme,
&config.build.path_prefix,
)
.unwrap();
Page::new_from_contents(body, "index.html", layout, config)
}

Expand Down