Prototype single files for web and slides - #7
Conversation
|
Summary: I adapted the Lua filter and tried it on the draft module on "browser() and reprex()", and it seems to work fine. My main concern is that it makes I'm curious to see how this will work in practice in the long run, but it's true there's a risk of drift between the written content and the slides, so it is nice to have everything in a single file. I thought theming and options would be an issue but it's easy to have format-specific options in the YAML. What I'd do:
Workflow complexityThe workflow seems pretty complicated to me. In particular, I don't understand the purpose of the R script: is this here only to convert qmd files that weren't made with this workflow and therefore need the It just seems to me that steps 2-7 in the workflow you detailed could be replaced by:
This would also require a single Either way, this increases the complexity for people who are not familiar with Quarto, which I think is unavoidable but we should ensure that we have screenshots / screen captures to clearly show how this is supposed to be used. ReadabilityI usually include custom text in slides (bullet points most of the time). I (locally) adapted the Lua filter to have a Example of revamped `index.qmd` in module on browser() and reprex()Small papercut to fix in the current implementation IMO: contiguous becomes It would be nice to have this instead: OtherNot an actionable comment, but I just wanted to point out that Quarto v2 will be welcome here to give good error messages for syntax errors, e.g. when some fenced divs are not closed (currently it warns only). Re:
We could have this: and have a script that copies the Lua script from |
|
Just some clarifying responses:
Just once per module (perhaps this is made confusing by the existence of the original file, which is only here for demonstration purposes). Once it's run on someone's original file, the script should ideally never be used again and the user should just edit the new (or now edited) file.
Ah, yes, based on Lewis's prompting, I designed the script for people who made ONLY the long-form content first. If you make both in parallel, doing it as you describe is likely easier.
See above
Agreed. My thought is that we could have a module that walks people through this process (or just a document). |
|
Changes:
Other notes:
|
etiennebacher
left a comment
There was a problem hiding this comment.
Thank you and sorry for the delay to review this, I have some comments to clarify the two workflows.
Importantly, I think we also wanted to give the user the possibility to have one qmd for the long format and one qmd for the slides, but this is not mentioned here.
| Rscript web_and_slides.r <input.qmd> [output.qmd] | ||
| [--filter=<path/to/filter.lua>] [--no-inject] [--no-settings] |
There was a problem hiding this comment.
Are there cases where we need to provide the filter and other arguments? Could this be simplified to:
Rscript web_and_slides.r <input.qmd> <output.qmd>Also, this needs to run in the terminal and everyone is not familiar with that, is there a way to run it with source()?
There was a problem hiding this comment.
This was developed as a CLI tool, source() is not currently an option. Don't the WIP contribution docs introduce people to using air via the terminal? Within RStudio/Positron, using the terminal is pretty easy.
| 2. Registers the filter in the front matter at the `pre-ast` stage, replacing any | ||
| earlier registration. `--no-inject` skips this; `--filter=` names a different | ||
| file. | ||
| 3. Sets slide-friendly YAML (skip with `--no-settings`): | ||
| - adds `execute.echo: true` (renders source code on slides) | ||
| - adds `execute.output-location: fragment` (renders code results as separate chunk) | ||
| - adds `format.revealjs.smaller: true` (text shrinks to fit on slides) | ||
| - removes `format.revealjs.scrollable` (disables scrolling through slides) |
There was a problem hiding this comment.
--no-inject and --no-settings make the entire process more complex for little benefits IMO. What if the R script didn't modify the YAML at all and instead we'd just recommend that people copy-paste the YAML from ggplot/index.qmd for instance? That way they could tweak the YAML if needed and we'd get rid of these two options.
There was a problem hiding this comment.
I was trying to make the whole procedure as painless as possible for users (by doing the YAML changes for them). I'm fine with removing the --no-settings option and making this always happen, but I think asking people to manually copy YAML and "tweak" it themselves is less user friendly and is a recipe for more headaches.
| The front matter is checked for valid YAML before anything is written. Needs the | ||
| `readr`, `stringr`, `yaml`, and `fs` packages. |
There was a problem hiding this comment.
That's only in CI, right? Does this need to be mentioned here?
There was a problem hiding this comment.
These checks are also done with the web_and_slides.r script:
Lines 216 to 231 in d10e77a
|
|
||
| With no `output.qmd` specified it rewrites the input in place. | ||
|
|
||
| # Two ways to build a module |
There was a problem hiding this comment.
I think this should come before explaining the lua + R script workflow above since this workflow is only relevant for the "long-form first then convert" section.
| One folder per module: `<module>/index.qmd`, plus whatever images and data it | ||
| needs. Every module is rendered twice from that single source: 1) as a page on the | ||
| [Palaeoverse website](https://palaeoverse.org/training/modules) and 2) as a | ||
| reveal.js slide deck (`index-slides.html`) for teaching the same material live. |
There was a problem hiding this comment.
I think we had chatted on Zulip about allowing both having a single qmd that creates the long format and the slides, and two qmds with one per format? I think @LewisAJones would prefer two qmds.
There was a problem hiding this comment.
I personally would prefer we stick to a single document to reduce maintenance overhead (since I have a hunch that the individual authors will not be maintaining their own modules longterm), but I suppose as long as everything is reproducible (and easy to maintain), it wouldn't be the end of the world if someone makes two separate documents (but I would prefer that we avoid using powerpoints, etc).
|
👋🏻 @willgearty @etiennebacher thanks for all your work on this... this was a pretty interesting technical issue to read through! I've not reviewed the code properly at this stage as there are things perhaps worth discussing. I think you've done a great job with the With your current "Two ways to build a module", if I was forced to choose, I would almost certainly use option 1 (long-form first, then convert) to just give me an initial scaffold and then edit accordingly. However, I personally would not want my long format and slide content in the same document. I would find this very cumbersome for editing, resolving issues/bugs, reviewing, and updating. I do see @willgearty's point that this should make it easier to ensure that relevant content remains in sync across the long format and slides. That said, there are other ways we can ensure this. For example, the workflow @etiennebacher setup to make sure that our DESCRIPTION and citation file remain in sync. I also don't think it's too much to expect maintainers to update relevant sections in both files (they will be living next to each other in a folder anyway?). If I think about how I would actually want to work (in terms of efficiency and focusing on content development), I'd most likely just duplicate my long-format I do see the value in what you've put together here though, and I imagine it could be useful to those more familiar with Quarto, or want to make use of this workflow. However, we should probably just accept that individuals might want to work in different ways for this, and as long as everything is prepared in Quarto and can be rendered appropriately, we allow them to use their own approach? I view what you've put together here as a tool to help module developers rather than a required workflow. If you agree, should we then have 3(?) "recommended approaches", and simply define what they must provide at a minimum (e.g. I realise I've rambled a lot here and appreciate you've been working on this for some time so I've likely missed context... do let me know if you want to jump on a call to discuss anything. A couple of small comments:
|
|
I think that's where @etiennebacher and I were converging here as well. I'll update the README accordingly.
|
This introduces some infrastructure to make a single longform module quarto file render well for both a webpage (
html) and for slides (revealjs). At the moment it uses no external extensions.There are two components:
web_and_slides.R: this script can be used to convert a standard longform quarto file to one that supports webpage/slides rendering::: {.narration}, which is treated as notes for revealjs and as normal prose for htmlweb_and_slides.luafilter to the yaml front matter if it isn't there (see # 2 below)execute: output-location: fragmentandexecute: echo: trueto the yaml front matter; this ensures that code chunk output is included in the slides and is added as fragments (separate slides) by defaultrevealjs.smaller = trueto the yaml front matter: this ensures that figures shrink to fit on slides#header with text after it)web_and_slides.lua: contains various filters and processing steps that alter the way the quarto file is rendered to slides.narration(notes for slides, prose for webpage)##) are promoted so each becomes its own slidefragmentfunctionality)So the general workflow would look something like this:
web_and_slides.R.narrationwherever text should be shown on slides verbatimRendered webpage:
https://palaeoverse.org/modules/pr-preview/pr-7/training/modules/ggplot/index.html
Rendered slides:
https://palaeoverse.org/modules/pr-preview/pr-7/training/modules/ggplot/index-slides.html
TODO:
.narrationusageNote that the script and .lua filter were generated iteratively over the course of a substantial conversation with Claude. The original module file was made entirely by me, and I've reviewed all of the code along the way.