Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Content formatting, 2nd iteration #240

Closed
traut opened this issue Sep 8, 2024 · 3 comments
Closed

Content formatting, 2nd iteration #240

traut opened this issue Sep 8, 2024 · 3 comments

Comments

@traut
Copy link
Member

traut commented Sep 8, 2024

Background

Currently, Fabric produces documents in Markdown, HTML, and PDF formats. The formatting feature's first iteration covers the basics but does not allow customizations and is difficult to extend.

Our goal is to provide best-in-class formatting capabilities in HTML and PDF. We achieve this by:

  • using TailwindCSS and the ability to customize content to create outstanding HTML pages
  • providing a selection of Latex templates to work with our Latex formatter for beautiful PDF documents.

Design

The 2nd iteration should cover these core features:

  • build an extendable internal representation of the content
  • implement AST node formatters
  • implement document formatters

Together with the publishers, the execution flow would look something like this:

  • data blocks are executed
  • dynamic blocks are unpacked (not implemented, Dynamic blocks #142)
  • content blocks are evaluated, and AST tree is built
  • a publisher is executed (print to stdout publisher by default)
  • the publisher selects a format (a default one or specified by the author) and requests formatting of the AST (or select pass-through-formatter that returns a raw AST)
  • AST nodes are formatted with node formatters, formatted-content tree structure is created
  • document formatter collapses the tree into a document
  • the publisher delivers the formatted document to the destination

Our requirements for the formatters force us to redefine the internal content representation and build up custom AST support in Fabric (#159). This separates content generation from content formatting and allows us to evolve formatters separately from content providers.

AST node formatters convert AST nodes (a list, a table, a paragraph) into format-specific blocks (Markdown / HTML / Latex list, Markwodn / HTML / Latex table, etc). They might match a specific content block or represent a smaller content structure.

In additional, there is a need for AST-for-formatted-blocks -- the blocks will carry the metadata that needs to be preserved for a document formatter to use. This formatted-content AST tree might be different from the content AST tree.

Document formatted collapses the AST of formatted blocks into the final document, adding necessary metadata around the content (HTML document tags, Latex preamble, etc)

Configuration

Formatters require configuration, both on the document and the block level.

Document formatting config

Document-level formatting is configured with config format_doc construct:

document "test" {

    title = "Document title"

    config format_doc html {
        title = "HTML title tag value"
        description = "HTML description tag value"
        js_sources = ["https://buttons.github.io/buttons.js", "/static/local.js"]
        css_sources = ["/static/main.css", "https://localhost.localhost/some.css"]

        html_css_classes = "dark:text-white"
        body_css_classes = "mb-5 overflow-hidden"
    } 
}

Here the HTML-document formatting is defined. See #117 as the previous iteration of the HTML

Block formatting config

document "test" {

    title = "Document title"

    section {
        title = "Section title"

        config format_block html {
            tag = "div" 
            tag_css_classes = "text-blue"
        }
    }
}

Here, the section is represented in the HTML document by a div tag with the text-blue CSS class on it.

References

@traut traut added the publisher label Sep 8, 2024
@traut traut added this to the v0.5 milestone Sep 8, 2024
@Andrew-Morozko
Copy link
Contributor

Andrew-Morozko commented Sep 9, 2024

I had an idea... What if the execution goes like this:

  • ... -> AST
  • Publisher(AST, publisherConfig)
    • Formatter

Instead of

  • ... -> AST
  • Formatter
  • Publisher(formatterAST, publisherConfig)

This avoids creating a second formatter-specific AST, allows publishers to modify AST pre-formatting or pass it onto the formatter as-is.

Formatter-specific settings would be stored in the AST, within plugin metadata nodes.

This way formatters are a kind of standard library of functions for publishers to use as they wish

@traut
Copy link
Member Author

traut commented Sep 9, 2024

sure, it might be a simpler approach!

@traut
Copy link
Member Author

traut commented Nov 14, 2024

surpassed by #262

@traut traut closed this as completed Nov 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants