Incorporating Markdown documents into Scribble

43 views
Skip to first unread message

Shriram Krishnamurthi

unread,
Sep 12, 2020, 9:14:53 AM9/12/20
to Racket Users
I need a little help with `decode` vs `decode-flow` in Scribble. (Also, this thread is about a question I wasn't able to find answered anywhere, so hopefully it will lead to a solution that others can also use.)

Sometimes it's really useful to incorporate Markdown-formatted content into the middle of a Scribble document. (Let's not argue about this, please!) My assumption is that the Markdown document lives in a separate file (I'm not trying to do any clever textual inlining). Thanks to Greg Hendershott, I'm almost there! I use


Here are two versions of the inlining function:

@(require markdown markdown/scrib scribble/decode)

@(define (markdown-inline file)
   (decode-flow
       (xexprs->scribble-pres
         (with-input-from-file file read-markdown))))

@(define (markdown-part file)
   (decode
       (xexprs->scribble-pres
         (with-input-from-file file read-markdown))))

As a practical matter, `markdown-part` needs to take lots of extra arguments to create the appropriate part instead of just producing a title-less section. More importantly, you often don't want a separate section: you just want to "splice" the content into the current context.

`markdown-inline` works great for this purpose, except if the included Markdown file contains any sections of its own, e.g.,

This is text.

> Lorem ipsum

# Section

## Subsection

Then I get this error:

decode-flow: contract violation

  expected: pre-flow?

  given: (part-start 0 #f '((part "section")) (style #f '()) '("Section"))

Any recommendations on how to create a "splicing" version that also respects having sub-sections, or is that impossible? (I've tried pulling out parts of the `part`, etc., but without success.)

Thanks!

Shriram

Hendrik Boom

unread,
Sep 12, 2020, 12:37:42 PM9/12/20
to Racket Users
On Sat, Sep 12, 2020 at 06:14:53AM -0700, Shriram Krishnamurthi wrote:
> I need a little help with `decode` vs `decode-flow` in Scribble. (Also,
> this thread is about a question I wasn't able to find answered anywhere, so
> hopefully it will lead to a solution that others can also use.)
>
> Sometimes it's really useful to incorporate Markdown-formatted content into
> the middle of a Scribble document. (Let's not argue about this, please!) My
> assumption is that the Markdown document lives in a separate file (I'm not
> trying to do any clever textual inlining). Thanks to Greg Hendershott, I'm
> almost there! I use
>
> https://github.com/greghendershott/markdown
>
> Here are two versions of the inlining function:
>
> @(require markdown markdown/scrib scribble/decode)
>
> @(define (markdown-inline file)
> (decode-flow
> (xexprs->scribble-pres
> (with-input-from-file file read-markdown))))
>
> @(define (markdown-part file)
> (decode
> (xexprs->scribble-pres
> (with-input-from-file file read-markdown))))
>
> As a practical matter, `markdown-part` needs to take lots of extra
> arguments to create the appropriate part instead of just producing a
> title-less section. More importantly, you often don't want a separate
> section: you just want to "splice" the content into the current context.
>
> `markdown-inline` works great for this purpose, *except* if the included
> Markdown file contains any sections of its own, e.g.,
>
> This is text.
>
> > Lorem ipsum
>
> # Section
>
> ## Subsection
>
> Then I get this error:
>
> decode-flow: contract violation
>
> expected: pre-flow?
>
> given: (part-start 0 #f '((part "section")) (style #f '()) '("Section"))
> Any recommendations on how to create a "splicing" version that also
> respects having sub-sections, or is that impossible? (I've tried pulling
> out parts of the `part`, etc., but without success.)
>
> Thanks!
>
> Shriram
>
> --
> You received this message because you are subscribed to the Google Groups "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to racket-users...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/3f0b1012-783d-464a-a0ed-66d3f29f8893n%40googlegroups.com.

This looks very useful.

-- hendrik

Ryan Culpepper

unread,
Sep 13, 2020, 5:45:22 AM9/13/20
to Shriram Krishnamurthi, Racket Users
What should the splicing version do in the following case:

  some text
  @(markdown-inline "file-with-sections.md")
  some trailing text

In particular, what should happen to the trailing text? Scribble doesn't have a notion of returning to the top-level after a section. One possibility would be to append it to the final subsection of "file-with-sections.md"; another would be to create a "Continuation" section to hold trailing text. Both of those seem bad to me; if the trailing text contained another inline markdown file with sections, the second file's sections would be at a deeper section level than the first file's sections.

Or instead of mapping inline-Markdown sections to Scribble sections, you could traverse the Markdown result and convert the Markdown section headers to Scribble styled paragraphs instead. But then you would lose the benefits of Scribble sections (eg, secref, TOC).

Ryan
 


--

Shriram Krishnamurthi

unread,
Sep 13, 2020, 7:50:43 AM9/13/20
to ry...@racket-lang.org, Racket Users
It's useful to have this behave like a `#include`. There are settings where you want to have a non-Scribble person author things that go "in the middle"; you want to think of this as just a more convenient way of writing what you'd have written in Scribble.

I realize there's presumably a closure issue (`section` isn't going to come from the including file), and for that you probably want a different include form as well.

Ryan Culpepper

unread,
Sep 13, 2020, 9:08:49 AM9/13/20
to s...@cs.brown.edu, Ryan Culpepper, Racket Users
Okay, if I understand correctly, you would expect the trailing text in my example to be appended to the final subsection from the file.

In that case, does it work if you simply remove the call to `decode-flow` from the definition of `markdown-inline`? Then the function would just return a list of pre-parts to be spliced into the enclosing document.

If you want to make the Markdown sections properly nest under the current section, you would probably need to adjust the depths of all `part-start` instances in the result. For example, if you use `markdown-inline` within a subsection, you would probably want to increase the depth of all part-starts by 2. I don't know if it's possible to find the current depth automatically, so you might need to make it an extra argument to `markdown-inline`.

I also would have expected calling `decode` and then extracting and appending the blocks and parts to work, although it would have different behavior wrt the trailing text. Your original message said that didn't work, but how did it fail?

Ryan

Hendrik Boom

unread,
Sep 13, 2020, 10:24:59 AM9/13/20
to Racket Users
The main thing I need markdown for is to include nested small bullet points,
in an explorative mind-mapping style.

The Scribble syntax is too wordy to be convenient.

Just as @paragraph{ .... } would be inconvenient to mark all the paragraphs in
ordinary text.

-- hendrik

>
> --
> You received this message because you are subscribed to the Google Groups "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to racket-users...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/CAJUf2yRcPq3-Gvxy3F95PJhBmiebquEvU3Sz6-y%3D98LFb_Wnvw%40mail.gmail.com.

Shriram Krishnamurthi

unread,
Sep 13, 2020, 10:27:01 AM9/13/20
to ry...@racket-lang.org, Racket Users
In that case, does it work if you simply remove the call to `decode-flow` from the definition of `markdown-inline`? Then the function would just return a list of pre-parts to be spliced into the enclosing document.

Doh. It appears to indeed!
 
If you want to make the Markdown sections properly nest under the current section, you would probably need to adjust the depths of all `part-start` instances in the result. For example, if you use `markdown-inline` within a subsection, you would probably want to increase the depth of all part-starts by 2. I don't know if it's possible to find the current depth automatically, so you might need to make it an extra argument to `markdown-inline`.

Thanks.
 

I also would have expected calling `decode` and then extracting and appending the blocks and parts to work, although it would have different behavior wrt the trailing text. Your original message said that didn't work, but how did it fail?

Yeah, I can't even remember all the things I tried.

I think there's value to figuring out a good set of abstractions here. There's real value to being able to have, e.g., co-authors who can only handle Markdown incorporate their work into Scribble pages. For now, with my semester under way, I think I'll pass on that task (-:. Hopefully this thread is useful to someone else who comes along and needs to do this. Short and final version:

@(define (markdown-inline file)
   (pr
     (xexprs->scribble-pres
       (with-input-from-file file read-markdown))))

Shriram

Shriram

Shriram Krishnamurthi

unread,
Sep 13, 2020, 10:30:24 AM9/13/20
to Racket Users
Apologies, I left in some debugging code. All we need is

@(define (markdown-inline file)
   (xexprs->scribble-pres
     (with-input-from-file file read-markdown)))

This will do you job, Jos Koot. For instance:

@title{Hello}
@(markdown-inline "new.md")

combined with (as "new.md")

This is a

* list
* mind-mapping
* points

written in a style that isn't too wordy.

produces

image.png
Shriram
Reply all
Reply to author
Forward
0 new messages