Syncing With Upstream JSON Format Changes In Typst Documentation
Hey guys! Let's dive into the recent updates and changes in Typst's docs.json
format. This is a crucial update, especially if you're contributing to the documentation or working with Typst's internals. We’re going to break down the key changes, why they matter, and how you can adapt to them. So, buckle up and let's get started!
Understanding the docs.json
Format Change
The recent merge in https://github.com/typst/typst/pull/7011 brought about significant changes to the docs.json
format. The primary motivation behind these changes is to enhance the flexibility and structure of the documentation, making it more comprehensive and user-friendly. The two major updates revolve around the fields in FuncModel
and ParamModel
, as well as the structure of examples within the documentation. Understanding these changes is the first step in ensuring a smooth transition and maintaining the quality of Typst's documentation.
Combining details: Html
and example: Option<Html>
into details: Vec<DetailsBlock>
One of the most significant changes is the consolidation of the details: Html
and example: Option<Html>
fields within FuncModel
and ParamModel
. Previously, these fields were separate entities, leading to potential redundancy and a less structured approach to documentation. Now, they've been combined into a new field: details: Vec<DetailsBlock>
. This change allows for a more organized and versatile way to present detailed information and examples.
The DetailsBlock
enum is the heart of this update. It provides a structured way to represent different types of content within the documentation, whether it's plain HTML or an example. This is a big step towards making our documentation more maintainable and expressive. By using a vector of DetailsBlock
, we can include multiple types of content—HTML explanations, code examples, and more—in a single, coherent section. This new structure not only simplifies the data model but also enhances the readability and utility of the documentation. It gives us the flexibility to mix and match different content types, creating a richer and more engaging learning experience for users. Think of it as leveling up our documentation game from simple text blocks to a dynamic, multi-faceted presentation.
Introducing Optional Titles for Examples
The second major update is the introduction of optional titles for examples. Previously, examples were presented without a title, which sometimes made it challenging to understand the context or purpose of the example at a glance. Now, the Example
struct within DetailsBlock
can have an optional title, providing a concise description or context for the example. This seemingly small change can significantly improve the usability of the documentation, especially for complex functions or parameters.
Titles help users quickly grasp the intent of the example and how it applies to their specific use case. This addition is about making the documentation more accessible and user-friendly. A title can act as a quick guide, helping users decide whether a particular example is relevant to their needs. Imagine scanning through a list of examples and instantly knowing which ones are most likely to help you – that's the power of a well-crafted title. Moreover, this update allows documentation contributors to add context and clarity to examples, ensuring that users can easily understand and apply the provided code snippets. It’s a small enhancement, but one that speaks volumes about our commitment to creating top-notch documentation.
Diving Deep into the Rust Code: DetailsBlock
To truly grasp the changes, let's dive into the Rust code snippet provided. This code defines the DetailsBlock
enum, which is central to the updated docs.json
format. Understanding this code will give you a clearer picture of how the new structure works and how you can leverage it in your documentation efforts.
/// A block-level segment in a function's or parameters documentation.
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
#[serde(tag = "kind", content = "content")]
pub enum DetailsBlock {
/// A block of HTML.
Html(Html),
/// An example with an optional title.
Example { body: Html, title: Option<EcoString> },
}
Breakdown of the DetailsBlock
Enum
The DetailsBlock
enum is defined with two variants: Html
and Example
. The Html
variant represents a block of HTML content, allowing you to include formatted text, links, and other HTML elements in your documentation. The Example
variant, on the other hand, represents an example with an optional title. This variant contains two fields: body
, which is the HTML content of the example, and title
, which is an Option<EcoString>
representing the optional title. Let's break down each component to fully appreciate its role.
Html(Html)
The Html(Html)
variant is straightforward. It’s designed to hold HTML content, which means you can include anything from basic text formatting to complex layouts. The flexibility here is key. You can use HTML to create lists, tables, formatted paragraphs, and more. This ensures that your documentation can handle a wide range of presentation needs. Think of this as your canvas for explaining concepts in detail. You can embed links, use different text styles, and even include images if needed. The goal is to make the documentation as informative and engaging as possible.
Example { body: Html, title: Option<EcoString> }
This is where the magic happens. The Example
variant is a struct-like variant that holds the actual example code or demonstration (body
) and an optional title (title
). The body
is of type Html
, giving you the same flexibility as the Html
variant for formatting the example. The title
is an Option<EcoString>
, which means it can either contain a title or be None
. This optional title is a game-changer. It allows you to provide a brief, descriptive label for each example, making it easier for users to understand its purpose and relevance.
Serde Attributes
The DetailsBlock
enum also uses several Serde attributes, which are crucial for serialization and deserialization. These attributes tell Serde how to convert the Rust enum into a JSON representation and vice versa. Let's take a closer look at these attributes:
#[derive(Debug, Serialize)]
: This attribute tells Rust to automatically generate code for debugging and serialization. TheDebug
trait allows you to print the enum for debugging purposes, while theSerialize
trait allows you to convert the enum into a JSON string.#[serde(rename_all = "camelCase")]
: This attribute tells Serde to rename all the enum variants to camel case when serializing to JSON. For example, theHtml
variant will be serialized as"html"
, and theExample
variant will be serialized as"example"
. This ensures consistency with the JSON format used in Typst's documentation.#[serde(tag = "kind", content = "content")]
: This attribute is the most interesting one. It tells Serde to serialize the enum as a tagged enum. In a tagged enum, the enum variant is represented as a JSON object with two fields:kind
andcontent
. Thekind
field contains the name of the enum variant (e.g.,"html"
or"example"
), and thecontent
field contains the value of the variant. For theHtml
variant, thecontent
field will contain the HTML content. For theExample
variant, thecontent
field will be a JSON object containing thebody
andtitle
fields. This format is highly structured and makes it easy to parse and work with the JSON data.
Why These Changes Matter
So, why should you care about these changes? Well, these updates are all about making Typst's documentation better, more accessible, and easier to maintain. And that benefits everyone who uses Typst. Let's break down the key reasons why these changes are significant.
Enhanced Documentation Structure and Readability
The move to Vec<DetailsBlock>
provides a more structured and organized way to present documentation details. By combining HTML content and examples into a single vector, we can create a more cohesive and readable documentation experience. This means that related information stays together, making it easier for users to follow along and understand complex concepts. Think of it as decluttering your desk – when everything has its place, it's much easier to find what you need. This improved structure also allows us to mix different types of content seamlessly. We can interleave explanations with examples, providing a more engaging and effective learning experience.
Improved User Experience
Optional titles for examples are a game-changer when it comes to user experience. A clear, descriptive title can immediately tell users what an example is about, saving them time and effort. This is particularly useful for complex functions or parameters where multiple examples might be needed to cover different use cases. Imagine you're looking for a specific example, like how to format a date in Typst. If each example has a title like