···2929/// Helps implement a struct as a Markdown content entry.
3030///
3131/// ## Example
3232-/// ```rs
3232+/// ```rust
3333/// use maudit::{coronate, content_sources, routes, BuildOptions, BuildOutput};
3434/// use maudit::content::{markdown_entry, glob_markdown};
3535///
···5151/// ```
5252///
5353/// ## Expand
5454-/// ```rs
5454+/// ```rust
5555/// use maudit::content::{markdown_entry};
5656///
5757/// #[markdown_entry]
···6161/// }
6262/// ```
6363/// expands to
6464-/// ```rs
6464+/// ```rust
6565/// #[derive(serde::Deserialize)]
6666/// pub struct Article {
6767/// pub title: String,
···8888///
8989/// Can only access content sources that have been defined in [`coronate()`](crate::coronate).
9090///
9191-/// ## Example
9191+/// # Example
9292/// In `main.rs`:
9393-/// ```rs
9393+/// ```rust
9494/// use maudit::{coronate, content_sources, routes, BuildOptions, BuildOutput};
9595/// use maudit::content::{markdown_entry, glob_markdown};
9696///
···112112/// ```
113113///
114114/// In a page:
115115-/// ```rs
115115+/// ```rust
116116/// use maudit::route::prelude::*;
117117/// # use maudit::content::markdown_entry;
118118/// #
···125125/// #[route("/articles/[article]")]
126126/// pub struct Article;
127127///
128128-/// #[derive(Params)]
128128+/// #[derive(Params, Clone)]
129129/// pub struct ArticleParams {
130130/// pub article: String,
131131/// }
···135135/// let params = ctx.params::<ArticleParams>();
136136/// let articles = ctx.content.get_source::<ArticleContent>("articles");
137137/// let article = articles.get_entry(¶ms.article);
138138-/// article.render(ctx).into()
138138+/// article.render(ctx)
139139/// }
140140///
141141-/// fn pages(&self, ctx: &mut DynamicRouteContext) -> Vec<ArticleParams> {
141141+/// fn pages(&self, ctx: &mut DynamicRouteContext) -> Pages<ArticleParams> {
142142/// let articles = ctx.content.get_source::<ArticleContent>("articles");
143143///
144144-/// articles.into_params(|entry| ArticleParams {
145145-/// article: entry.id.clone(),
146146-/// })
144144+/// articles.into_pages(|entry| Page::from_params(ArticleParams {
145145+/// article: entry.id.clone(),
146146+/// }))
147147/// }
148148/// }
149149/// ```
···204204/// A single entry of a [`ContentSource`].
205205///
206206/// ## Example
207207-/// ```rs
207207+/// ```rust
208208/// use maudit::route::prelude::*;
209209/// # use maudit::content::markdown_entry;
210210/// #
···226226/// fn render(&self, ctx: &mut PageContext) -> impl Into<RenderResult> {
227227/// let articles = ctx.content.get_source::<ArticleContent>("articles");
228228/// let article = articles.get_entry("my-article"); // returns a Entry<ArticleContent>
229229-/// article.render(ctx).into()
229229+///
230230+/// article.render(ctx)
230231/// }
231232/// }
232233/// ```
···335336/// Mostly seen as the return type of [`content_sources!`](crate::content_sources).
336337///
337338/// ## Example
338338-/// ```rs
339339+/// ```rust
339340/// use maudit::route::prelude::*;
340341/// use maudit::content::{glob_markdown, ContentSources};
341342/// use maudit::content_sources;
···350351/// pub fn content_sources() -> ContentSources {
351352/// content_sources!["docs" => glob_markdown::<ArticleContent>("content/docs/*.md")]
352353/// }
353353-pub struct ContentSources(pub(crate) Vec<Box<dyn ContentSourceInternal>>);
354354+pub struct ContentSources(pub Vec<Box<dyn ContentSourceInternal>>);
354355355356impl From<Vec<Box<dyn ContentSourceInternal>>> for ContentSources {
356357 fn from(content_sources: Vec<Box<dyn ContentSourceInternal>>) -> Self {
+1-1
crates/maudit/src/content/highlight.rs
···89899090impl HighlightOptions {
9191 /// Parse the value after the opening of a fenced Markdown code block
9292- /// e.g. for ```rs ins=0, you'd get lang: "rs", ins: "0"
9292+ /// e.g. for ```rust ins=0, you'd get lang: "rs", ins: "0"
9393 pub fn new_from_fence(fence: &str, theme_path: impl Into<String>) -> Self {
9494 // TODO: Write the parser for this, lol
9595 let language = fence.to_string();
+17-11
crates/maudit/src/content/markdown.rs
···2929/// Can be used to generate a table of contents.
3030///
3131/// ## Example
3232-/// ```rs
3232+/// ```rust
3333/// use maudit::route::prelude::*;
3434/// use maud::{html, Markup};
3535/// # use maudit::content::markdown_entry;
···114114/// Assumes that the Markdown content has no frontmatter.
115115///
116116/// ## Example
117117-/// ```rs
117117+/// ```rust
118118/// use maudit::{coronate, content_sources, routes, BuildOptions, BuildOutput};
119119/// use maudit::content::{glob_markdown, UntypedMarkdownContent};
120120///
···181181/// Typically used by [`content_sources!`](crate::content_sources) to define a Markdown content source in [`coronate()`](crate::coronate).
182182///
183183/// ## Example
184184-/// ```rs
184184+/// ```rust
185185/// use maudit::{coronate, content_sources, routes, BuildOptions, BuildOutput};
186186/// use maudit::content::{markdown_entry, glob_markdown_with_options, MarkdownOptions};
187187///
···195195/// coronate(
196196/// routes![],
197197/// content_sources![
198198-/// "articles" => glob_markdown_with_options::<ArticleContent>("content/articles/*.md", )
198198+/// "articles" => glob_markdown_with_options::<ArticleContent>("content/articles/*.md", MarkdownOptions {
199199+/// highlight_theme: "base16-ocean.dark".to_string(),
200200+/// ..Default::default()
201201+/// })
199202/// ],
200203/// BuildOptions::default(),
201204/// )
···255258/// To provide custom options for Markdown rendering, use [`glob_markdown_with_options`] instead.
256259///
257260/// ## Example
258258-/// ```rs
261261+/// ```rust
259262/// use maudit::{coronate, content_sources, routes, BuildOptions, BuildOutput};
260263/// use maudit::content::{markdown_entry, glob_markdown};
261264///
···321324322325/// Render Markdown content to HTML with optional custom components.
323326///
327327+/// To be able to resolve and include images, a path to the Markdown file and a mutable reference to the current [`PageContext`](crate::route::PageContext) must be provided.
328328+///
324329/// ## Example
325325-/// ```rs
330330+/// ```rust
326331/// use maudit::content::{render_markdown, MarkdownOptions, MarkdownComponents};
327332/// use maudit::content::components::HeadingComponent;
328333///
329334/// // Without components
330335/// let markdown = r#"# Hello, world!"#;
331331-/// let html = render_markdown(markdown, None);
336336+/// let html = render_markdown(markdown, None, None, None);
332337///
333338/// // With components
334339/// struct MyCustomHeading;
···350355///
351356/// let options = MarkdownOptions {
352357/// components: MarkdownComponents::new().heading(MyCustomHeading),
358358+/// ..Default::default()
353359/// };
354354-/// let html = render_markdown(markdown, Some(&options));
360360+/// let html = render_markdown(markdown, Some(&options), None, None);
355361/// ```
356362pub fn render_markdown(
357363 content: &str,
···817823/// and automatically populates the headings for table of contents generation.
818824///
819825/// ## Example
820820-/// ```rs
821821-/// use maudit::content::{parse_markdown_with_frontmatter, markdown_entry};
826826+/// ```rust
827827+/// use maudit::content::{parse_markdown_with_frontmatter, markdown_entry, MarkdownContent};
822828///
823829/// #[markdown_entry]
824830/// pub struct ArticleContent {
···831837/// description: "A great article"
832838/// ---
833839///
834834-/// # Introduction
840840+/// ## Introduction
835841///
836842/// This is the content.
837843/// "#;
+1-1
crates/maudit/src/content/markdown/components.rs
···483483#[cfg(test)]
484484mod tests {
485485 use super::*;
486486- use crate::content::{render_markdown, MarkdownOptions};
486486+ use crate::content::{MarkdownOptions, render_markdown};
487487488488 struct TestCustomHeading;
489489
+16-19
crates/maudit/src/lib.rs
···3030 //! Traits and methods for [Maud](https://maud.lambda.xyz), a macro for writing HTML templates.
3131 //!
3232 //! ## Example
3333- //! ```rs
3333+ //! ```rust
3434 //! use maudit::route::prelude::*;
3535 //! use maud::{html, Markup};
3636 //!
3737 //! #[route("/")]
3838 //! pub struct Index;
3939 //!
4040- //! impl Route<PageParams, (), Markup> for Index {
4141- //! fn render(&self, ctx: &mut PageContext) -> Markup {
4040+ //! impl Route for Index {
4141+ //! fn render(&self, ctx: &mut PageContext) -> impl Into<RenderResult> {
4242 //! html! {
4343 //! h1 { "Hello, world!" }
4444 //! }
···6363/// This can be useful to conditionally enable features or logging that should only be active during development.
6464/// Oftentimes, this is used to disable some expensive operations that would slow down build times during development.
6565pub fn is_dev() -> bool {
6666- if option_env!("MAUDIT_DEV") == Some("true") {
6767- return true;
6868- }
6969-7066 env::var("MAUDIT_DEV").map(|v| v == "true").unwrap_or(false)
7167}
7268···7470/// Helps to define every route that should be build by [`coronate()`].
7571///
7672/// ## Example
7777-/// ```rs
7373+/// ```rust
7874/// use maudit::{
7975/// content_sources, coronate, routes, BuildOptions, BuildOutput,
8076/// };
···8480/// #
8581/// # #[route("/")]
8682/// # pub struct Index;
8787-/// # impl Route<PageParams, (), String> for Index {
8888-/// # fn render(&self, _ctx: &mut PageContext) -> String {
8989-/// # "Hello, world!".to_string()
8383+/// # impl Route for Index {
8484+/// # fn render(&self, _ctx: &mut PageContext) -> impl Into<RenderResult> {
8585+/// # "Hello, world!"
9086/// # }
9187/// # }
8888+/// #
9289/// # #[route("/article")]
9390/// # pub struct Article;
9491/// #
9595-/// # impl Route<PageParams, (), String> for Article {
9696-/// # fn render(&self, _ctx: &mut PageContext) -> String {
9797-/// # "Hello, world!".to_string()
9292+/// # impl Route for Article {
9393+/// # fn render(&self, _ctx: &mut PageContext) -> impl Into<RenderResult> {
9494+/// # "Hello, world!"
9895/// # }
9996/// # }
10097/// # }
···117114/// Helps to define all sources of content that should be loaded by [`coronate()`].
118115///
119116/// ## Example
120120-/// ```rs
117117+/// ```rust
121118/// use maudit::{
122119/// content_sources, coronate, routes, BuildOptions, BuildOutput,
123120/// };
···141138/// ```
142139///
143140/// ## Expand
144144-/// ```rs
141141+/// ```rust
145142/// # use maudit::{content_sources};
146143/// # use maudit::content::{glob_markdown, markdown_entry};
147144/// # #[markdown_entry]
···155152/// ];
156153/// ```
157154/// expands to
158158-/// ```rs
155155+/// ```rust
159156/// # use maudit::content::{glob_markdown, markdown_entry};
160157/// # #[markdown_entry]
161158/// # pub struct ArticleContent {
···177174/// Can be used to create a generator tag in the output HTML.
178175///
179176/// ## Example
180180-/// ```rs
177177+/// ```rust
181178/// use maudit::GENERATOR;
182179///
183180/// format!("<meta name=\"generator\" content=\"{}\">", GENERATOR);
···188185///
189186/// ## Example
190187/// Should be called from the main function of the binary crate.
191191-/// ```rs
188188+/// ```rust
192189/// use maudit::{
193190/// content_sources, coronate, routes, BuildOptions, BuildOutput,
194191/// };
+15-14
crates/maudit/src/route.rs
···1919/// End users should rarely need to interact with this enum directly.
2020///
2121/// ## Example
2222-/// ```rs
2222+/// ```rust
2323/// use maudit::route::prelude::*;
2424///
2525/// #[route("/")]
···173173/// Helper function to create paginated routes from any iterator
174174///
175175/// Example:
176176-/// ```rs
176176+/// ```rust
177177/// use maudit::route::prelude::*;
178178///
179179/// #[route("/tags/[page]")]
···235235/// Allows to access various data and assets in a [`Route`] implementation.
236236///
237237/// ## Example
238238-/// ```rs
238238+/// ```rust
239239/// use maudit::route::prelude::*;
240240/// use maud::html;
241241/// # use maudit::content::markdown_entry;
···253253/// fn render(&self, ctx: &mut PageContext) -> impl Into<RenderResult> {
254254/// let logo = ctx.assets.add_image("logo.png");
255255/// let last_entries = &ctx.content.get_source::<ArticleContent>("articles").entries;
256256+///
256257/// html! {
257258/// main {
258259/// (logo)
···262263/// }
263264/// }
264265/// }
265265-/// }.into()
266266+/// }
266267/// }
267268/// }
268269pub struct PageContext<'a> {
···347348/// Allows to access the content source in the [`Page::pages`] method.
348349///
349350/// ## Example
350350-/// ```rs
351351+/// ```rust
351352/// use maudit::route::prelude::*;
352353/// # use maudit::content::markdown_entry;
353354/// #
···360361/// #[route("/articles/[article]")]
361362/// pub struct Article;
362363///
363363-/// #[derive(Params)]
364364+/// #[derive(Params, Clone)]
364365/// pub struct ArticleParams {
365366/// pub article: String,
366367/// }
···370371/// let params = ctx.params::<ArticleParams>();
371372/// let articles = ctx.content.get_source::<ArticleContent>("articles");
372373/// let article = articles.get_entry(¶ms.article);
373373-/// article.render().into()
374374+/// article.render(ctx)
374375/// }
375376///
376376-/// fn pages(&self, ctx: &mut DynamicRouteContext) -> Vec<ArticleParams> {
377377+/// fn pages(&self, ctx: &mut DynamicRouteContext) -> Pages<ArticleParams> {
377378/// let articles = ctx.content.get_source::<ArticleContent>("articles");
378379///
379379-/// articles.into_params(|entry| ArticleParams {
380380-/// article: entry.id.clone(),
381381-/// })
380380+/// articles.into_pages(|entry| Page::from_params(ArticleParams {
381381+/// article: entry.id.clone(),
382382+/// }))
382383/// }
383384/// }
384385/// ```
···392393/// The page struct implementing this trait can be passed to [`coronate()`](crate::coronate), through the [`routes!`](crate::routes) macro, to be built.
393394///
394395/// ## Example
395395-/// ```rs
396396+/// ```rust
396397/// use maudit::route::prelude::*;
397398///
398399/// #[route("/")]
···400401///
401402/// impl Route for Index {
402403/// fn render(&self, ctx: &mut PageContext) -> impl Into<RenderResult> {
403403-/// "<h1>Hello, world!</h1>".into()
404404+/// "<h1>Hello, world!</h1>"
404405/// }
405406/// }
406407/// ```
···729730 //! This module is meant to be glob imported in your routes files.
730731 //!
731732 //! ## Example
732732- //! ```rs
733733+ //! ```rust
733734 //! use maudit::route::prelude::*;
734735 //! ```
735736 pub use super::{