Markdown Interpolation, proper proposal

182 views
Skip to first unread message

Evan Czaplicki

unread,
Jul 10, 2013, 7:40:07 PM7/10/13
to elm-d...@googlegroups.com
Goal: It would be nice to place arbitrary Elm values in a Markdown document. This is a plan to enable this in a way that is type-safe, efficient, and at compile-time.

Overview: I would introduce two syntactic constructs to markdown blocks {{ 4 + 5 }} for non-signals and {~ Mouse.position ~} for signals. Both can hold arbitrary expressions. For example:

main = [markdown|
The factorial of 5 is {{ product [1..5] }}.
The mouse is currently at {~ Mouse.position ~}.
|]

A markdown block that only uses the {{ }} construct would itself be a non-signal. If a {~ ~} is used, the block becomes a signal as well.

Implementation and Types: The program above desugars to the following declaration:

main = customMarkdown (product [1..5]) Mouse.position

with the constraint that:

customMarkdown : a -> Signal b -> Signal Element

The number and type of arguments can be deduced during parsing because of the two kinds of quotations, so type inference still works out.

The actual customMarkdown function is generated by the compiler. It would replace interpolated expressions with <span> elements. When an Elm value needs to be displayed, you would use something very similar to the JS FFI to fill in a particular <span>. This would work for updates as well.

This means that the markdown can still be fully parsed and turned into HTML at compile time, no need for reparsing on the client-side.

Specifics of rendering: it seems reasonable to treat certain types specially to make things more convenient.
  • Element: display the element inline
  • Text: display the styled-escaped text inline
  • everything else: convert to a string with show and display the monospace escaped version.
This imposes nearly no implementation overhead and makes things generally nicer to use (no need to remember a whole family of type-specific quotes).

This means you'd need to say {{ plainText "hello" }} to get a string to display without the monospace font. This will surely catch some people, but I think it makes sense to only special case Text and Element because they really are about display.

Related Work: Tangle.js, AngularJS, templating languages in general. With this feature, I think it could be reasonable to argue that Elm is a more principled super-set of these projects.

Feedback Please!

Tim hobbs

unread,
Jul 11, 2013, 4:41:25 AM7/11/13
to elm-d...@googlegroups.com
What happens text wrapping wise when I do [| This is a bit of markdown {{plainText "with a really long string that certainly doesn't fit on one line in your browser, and really should be wrapped, but it's inside a plainText Element." }} |]. With this proposal?

Tim

Tim hobbs

unread,
Jul 11, 2013, 4:47:37 AM7/11/13
to elm-d...@googlegroups.com
And if it does wrap, then what happens when I do:

pte = plainText "This is a really long line, that wraps because it's too long to fit on the screen. And you know, that's cool, because then people can see all of it."

main = [markdown| A text Element {{pte}}  of width {{widthOf pte}} |]  -- Does the width then change when I resize the screen thus causing wrapping?

Tim

Alex Neslusan

unread,
Jul 11, 2013, 4:56:08 AM7/11/13
to elm-d...@googlegroups.com
This is definitely a good point to consider. It would make sense to me to have Text wrap but Elements not wrap. So

ptt = toText "This is a really long line, that wraps because it's too long to fit on the screen. And you know, that's cool, because then people can see all of it."
pte= plainText "This is a really long line, that wraps because it's too long to fit on the screen. And you know, that's cool, because then people can see all of it."

main = [markdown| This will wrap: {{ptt}} but this won't: {{pte}} |]

Evan Czaplicki

unread,
Jul 11, 2013, 4:56:24 AM7/11/13
to elm-d...@googlegroups.com
Oops, I meant to do {{ toText "hello" }} which would wrap. Text will just be placed in-line.

Elements have a fixed size, so the really long things you created would just be really long. When you resized, it would stay the same size. I think the biggest question here, is "how do Elements get placed into the document?" which I need to think about more.


--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Evan Czaplicki

unread,
Jul 11, 2013, 5:04:22 AM7/11/13
to elm-d...@googlegroups.com
To clarify the rephrased question, should an Element always get placed in as a <div>? I.e. not inlined?

I can imagine it'd be nice to have things inline sometimes though. What are some compelling examples of when this would be nice?

Maybe it could depend on whether you put the {{ element }} within a paragraph or if you put it on its own line?

--

Tim hobbs

unread,
Jul 11, 2013, 6:24:49 AM7/11/13
to elm-d...@googlegroups.com

I think it should depend on whether you put it within a paragraph or on it's own line.  I'd love to be able to make reactive fill in the blank worksheets for my students as I'm going to be teaching English next year.  It would be nice to be able to cram all those text fields into the markdown :)

wordEntry word = magical interactive field that turns green when the correct word is typed in.

main = [markdown| John saw {{wordEntry "a"}} cat running across {{wordEntry "the"}} street. |]

Evan Czaplicki

unread,
Jul 11, 2013, 6:35:53 AM7/11/13
to elm-d...@googlegroups.com
Okay, I agree with this. That would be a very cool example :)

Jake Verbaten

unread,
Jul 21, 2013, 9:50:18 PM7/21/13
to elm-d...@googlegroups.com
I noticed `quaint` today ( http://breuleux.net/quaint/ )

quaint has an interesting approach to being able to insert and apply arbitrary operators within "markdown"

This might be worth looking at / thinking about.

Evan Czaplicki

unread,
Jul 27, 2013, 4:11:54 PM7/27/13
to elm-d...@googlegroups.com
I talked with John today and we wrote two nice examples using the latest interpolation proposal.
Neither compiles of course, but based on the code, I am fairly convinced that this is a reasonable idea. What do people think of this code?


--

Tim hobbs

unread,
Jul 28, 2013, 4:51:29 AM7/28/13
to elm-d...@googlegroups.com
The first example looks real sweet! :D

I'm excited already, now get back to coding!

Tim

Jeff Smits

unread,
Jul 28, 2013, 9:47:30 AM7/28/13
to elm-d...@googlegroups.com
That looks nice Evan! :)
Reply all
Reply to author
Forward
0 new messages