Scrivener → Squarto

Screenshot update | 2025-01-20

For anybody interested, here is how Squarto is set up to facilitate creation of a Quarto Book project. All writing takes place in Scrivener, using all the normal tools (like the binder, styles, etc.). The Squarto template for Scrivener gives a good starting point for structure of the binder.

Zooming in on the binder, there are sections for Quarto files, the book itself (including front matter, parts/chapters, and appendices), and figures.

Building the Quarto Book is initiated through Scrivener’s Compile command. The Squarto template for Scrivener has built-in section layouts to auto-assign the structure of the binder.

The Squarto compile format includes a processing step that will pass important arguments, such as where the COMPILED_BY_SCRIVENER.md output file is located, what you want to name the root directory for the Quarto book (in this case, squarto_output), and where your references .bib file is located (which will be included in the project as a copy or as an alias).


Of course, most of the processing itself is done via the embedded bash script.

There are some pretty cool features in the bash script, such as redirecting STDOUT and STDERR to a log file, pasting the path to the .scriv project file (since Scrivener doesn’t have a native way to pass this path to the Compile step, as detailed in this thread), prepending key parameters into the COMPILED_BY_SCRIVENER.md document for later reference, and finally, executing squarto build at the command line. The script is executed in a virtual environment (in my case, using conda).

The post-processed COMPILED_BY_SCRIVENER.md looks something like this:


The top section contains prepended metadata that will be used by Squarto later. Each item from the binder is separated by a delimiter (that Scrivener adds via the Section Type and Section Layout functionality). Squarto uses this later to parse the sections of the compiled text and save the content into separate files, ordered hierarchically within the Quarto Book project, as was visually laid out within the binder.

The Quarto Book project is created on the filesystem as a hierarchy of folders and files. Text documents within the Scrivener ‘DraftFolder’ were parsed from the COMPILED_BY_SCRIVENER.md file and then stored in the appropriate location. (Quarto uses the .qmd extension for Quarto Markdown format.) Other files (e.g., _quarto.yml, fonts and scripts, and images) are copied from the deep internal recesses of the .scriv project package into the proper location. You might notice that the filenames for the text documents are “slugified” versions of the titles in the binder. Emojis are removed :frowning: lol.

A Quarto Book requires a properly formatted _quarto.yml configuration file to tell Quarto what to do. This file is dynamically created by Squarto to show the correct paths to all the parts, chapters, and appendices. You don’t have to edit this portion of _quarto.yml yourself – all you do is rearrange/rename things in the Binder, and the YAML is auto-generated at Compile/post-process time!

With the Quarto Book project properly saved in all its bits-n-pieces, it is now ready for rendering using quarto render into whatever format you want (e.g., PDF), or quarto preview for a preview in the browser.

Of course, there are tons more details about the internals of the project. I continue to refactor it to make it more robust against edge cases. And I continue to work on the Squarto Scrivener project template itself, in which all the styles and compile settings are defined. Squarto is quite modular and extensible now, so I can continue to develop pipeline steps that are relatively easy to add – for example, pre-processing steps that I want to run on the COMPILED_BY_SCRIVENER.md file before parsing and saving the content to files. For example, this is how I correct image tag attributes.

I’m now at the point where I can use Squarto in “real life” (with “real projects”); that said, it’s still beta software, and I continue to improve it. Let me know what questions/suggestions you have about it!

Many thanks to @nontroppo, @AmberV, @kewms, @KB, and others for the great tips along the way.

2 Likes

Wow, looks awesome!!! Does your bash script have any other dependencies other than Quarto?

It pastes from the clipboard, so it requires POSIX (possibly macOS).

The last line in the script is squarto build, so that uses Python — mainly standard library, but I opted to add dependency on typer for CLI and loguru for logging. All this is available in the virtual environment selected by the bash script.

I actually don’t run Quarto via the bash script. The script ends with Squarto.

The workflow that I’ve gravitated toward is:

  • Compile and squarto build (via the bash script) the first time.
  • In Terminal, I manually run quarto preview once — which opens a browser window with a preview of the Quarto Book, so I get a nice view of what I’m working on.
  • Then, I continue writing in Scrivener.
  • When I want to refresh the preview (for example, to check how some math equations look, or to check if a Python or R figure is rendered correctly from code), I trigger the re-compile, Squarto re-builds again, and the preview automatically refreshes.
  • Once I’m finally done working, I would manually run quarto render to get the final products.

Perhaps I’ll add options for triggering Quarto into Squarto’s CLI or add a TUI using textual. For right now keeping the Quarto preview/rendering separate from the Squarto build is working pretty nicely.

Cookiecutter for Scrivener+Quarto projects

I am considering adding cookiecutter functionality into Squarto.

For people who have never used it, Cookiecutter is a command-line program that will create a new project based on a project template. For example, to create a new research project, one could copy the Cookiecutter template that contains hierarchically nested folders and files. What makes Cookiecutter special, though, is that it will customize placeholder fields throughout the project – such as naming folders, naming files, and even inserting content within files – based on your answers to any prompts that were set up in the Cookiecutter template. So instead of getting the generic, blank template, it might start out partially customized to the specifics of the new project.

cookiecutter is a very popular choice for instantiating new projects based on a template. Brett Terpstra created his own program called planter, and we discussed some of the similarities and differences between Planter and Cookiecutter on his forum. The new kid on the block is copier. It seems to have some nice features. The docs provide a handy comparison table to see similarities and differences relative to Cookiecutter.

I am considering integrating some Cookiecutter-like functionality within Squarto so that it would facilitate creating a new Scrivener project using a template and filling in basic details like project name, author name, metadata, etc. From a user’s perspective, one would simply type

squarto new myproject.scriv

to use the internal default template, or

squarto new myproject.scriv --template=/path/to/mytemplate.scriv --bibliography=/path/to/myreferences.bib

and any other arguments that are desirable.

From an implementation perspective, this will require deciding where {{placeholders}} appear inside the .scriv project and its contents (.scrivx file, etc.). Since Scrivener itself creates UUIDs for various elements, the squarto new command would generate UUIDs dynamically as well.

Has anybody ever tried something like this?

It goes without saying that this will be an unorthodox method for creating a new Scrivener project, likely to face technical limits and problems, so this remains a research-oriented side project that will not be applied to “real work”.

1 Like

Oh, and just to clarify the workflow better…

I would create a new project with
squarto new myproject.scriv. This would create my Scrivener project file using the Squarto template that is designed to eventually produce the Quarto book. Internally, all the metadata would have been set up appropriately for the new project according to the prompts.

From that point forward, all writing occurs in Scrivener in the usual way.

When done, the project is compiled, and the post-compilation script will run squarto build to create the Quarto book folder/file hierarchy.

Finally, run quarto render to produce the Quarto book PDF or web site.

It seems like quite a bit of work for what amounts to only a minimal gain? For my own work, editing my Pandoc metadata in a new template takes a few minutes, and tweaking my compile output choices using the GUI a minute or so. Answering questions wouldn’t be much faster than editing my metadata, the main benefit would be possibly less errors (as YAML can be fussy)?

1 Like

Oh, you are certainly right… but you (of all people!) can surely sympathize with the DIY urge to tinker. It is the age long quest: can it be done?

Besides, the main benefit of automation is to my future-self. I tend to work on one or two “big” projects for a while. If some time passes before starting a new project, my future-self will have to re-discover what my past-self had done to get the last project off the ground. With a cookiecutter approach, I will be able to simply type squarto new, and start working in my new Scrivener project without any fuss.

2 Likes

I can only wholeheartedly agree with this of course :laughing:

1 Like

I haven’t updated this thread in a while, and I need to do so soon. But here is a sneak peak at the progress that Squarto has made… It now has an integrated TUI (text user interface, courtesy of the magnificent Textual project). My Scrivener project’s binder is replicated on the left side. All the content files are read from within the .scriv package and converted from RTF to Markdown, and a preview of that is presented in the center content pane. In the upper right is a metadata inspector, and the bottom right panel shows the synopsis and the notes.

I was fooling around with adding a Markdown editor also, but there’s really no point, as I prefer to keep the editing in Scrivener itself.

This TUI will be the interface to an alternate compiler, so I can process the RTF file in various ways (e.g., extract embedded graphics and save to the /Figures/ directory; implement styles properly; clean up whitespace or stylistic preferences for Markdown; all sorts of things). The main goal is to export everything as separate files in the correct hierarchical structure for Quarto to then work its magic. I will also see if I can enable plain Pandoc and newer Typst workflows via the Squarto compiler.

I know this isn’t much of an update, but I will see if I can give more thorough explanation sometime.

3 Likes