With the switch to `cmark`, the “second phase” parsing of individual
stanzas omitted an EOF check to ensure that the entire stanza had been
parsed. This resulted in parses where we end up with truncated sets of
UCM commands or API requests, which could either result in premature
success or failures occurring later in the transcript, where they’d
complain about the wrong thing.
With #5142, Ormolu was upgraded from 0.5.2.0 to 0.7.2.0. This formats
the codebase to avoid spurious formatting comingled in other commits.
Almost all of the changes are simply wrapping single constraints in parens, like
```diff
-hashBranch :: forall m. Monad m => Branch m -> m BranchHash
+hashBranch :: forall m. (Monad m) => Branch m -> m BranchHash
```
There is also some reordering of language pragmas and imports,
indentation correction (some of which gets precedence wrong), and switching
some Haddock from `-- ^` to `-- |` .
- `Transcript` – the data model
- `Transcript.Parser` – the parser and printer
- `Transcript.Runner` – the runner
There is unfortunately still some printing tightly coupled to the
runner, but this makes it more obvious. Also, the runner is the only
component tied to the CLI.
A bunch of small changes in TranscriptParser
- remove dead code
- don’t use `Show` for formatted output
- put processed blocks in a separate sum type from unprocessed blocks
- remove `Transcript` from identifiers (changed importers to use
`qualified as Transcript`)
- deduplicated some error reporting
And one happy fix, IMO – got rid of the `Text.init` that plagued me in
We don’t need a very rich parser for transcripts, but we _do_ need to
reliably identify fenced code blocks, and that implies a number of
subtle cases. Using a polished CommonMark parser/printer handles those
subtleties for us.
I chose `cmark` for a few reasons:
- it’s a wrapper around `libcmark`, which is the reference
implementation of CommonMark, so it should be correct;
- it provides both a parser and a printer (unlike MMark); and
- it is extremely fast (about 20x faster than MMark), so the fact that
our home-rolled parser got to skip over everything that’s not a block
isn’t an issue.).
This only _partially_ uses the `cmark` printer. I think it should use it
entirely, but for the cases where we do streaming output (processing UCM
commands, etc.) it’s a more involved change. So I think it should be
handled separately.