$30 off During Our Annual Pro Sale. View Details »

md2sht with Haskell

Justin Woo
November 04, 2016

md2sht with Haskell

Small talk I gave for Futurice WWWeeklies for a tool I wrote to convert Markdown into inline-Styled HTml for our CMS.

Justin Woo

November 04, 2016
Tweet

More Decks by Justin Woo

Other Decks in Programming

Transcript

  1. md2sht with Haskell
    Justin Woo

    View Slide

  2. Convert Markdown to
    inline-styled HTML

    View Slide

  3. The problem
    For a tech company, we just don’t have enough
    tech posts on our blog.
    Flockler requires inline-styled HTML to be input
    to the “code view” to get styled HTML in posts
    (especially important for code blocks).
    Everyone complains about Flockler being terrible
    since it doesn’t have Markdown support.
    As a result, shit don’t get done.
    How much do
    developers like…?
    Testing Writing PLs Bitching

    View Slide

  4. The solution
    Why not make a tool to
    make inline-styled HTML
    generation easy?
    We can use some amazing
    Haskell libraries to do this!

    View Slide

  5. The team
    Who even likes Haskell anyway?
    Justin Oleg
    Some weird Asian guy who
    decided he should be
    solving this problem for
    everyone, whose picture
    isn’t even here
    FutuHaskell guru who
    helped fix the terrible code
    Justin wrote, whose
    picture is also not here
    You
    You might not think so, but
    you are also vital to this
    project, as a user and as a
    developer.

    View Slide

  6. Timeline
    How md2sht came to be
    January 2016
    Justin goes back to Japan for vacation
    after visiting Futurice in Oct 2015
    April 2016
    Justin moves to
    Helsinki
    October 2016
    Justin asks some silly questions
    about writing a CSS Parser for
    some ungodly reason
    October 2016
    md2sht is published on GitHub,
    much to the dismay of the
    civilized world
    Jan Feb Mar Apr May Jun Jul Aug Sept Oct Nov Dec

    View Slide

  7. Why Haskell?
    Mature libraries like Pandoc, attoparsec
    Good small HTML parsing libs like TagSoup
    Fun!
    How would I get involved?
    Start using md2sht, read some source code, ask
    questions on Flowdock/Twitter or in Person!
    Don’t I need to know a lot of hard/unfamiliar
    functional programming to do Haskell?
    Nope! Most of the code uses little more than
    “Either Error [Rule]” and [Rule] -> String -> String
    Why/How?

    View Slide

  8. Install md2sht and run md2sht
    --input YourPost.md
    md2sht writers’ workflow
    Step 1
    Write your post with Markdown like you
    normally would
    Step 2
    Step 3
    Copy the generated HTML into the Flockler
    code view and save your post

    View Slide

  9. Haskell
    Fun for everyone
    * for certain definitions of “fun”

    View Slide

  10. md2sht process
    The md2sht program is composed of
    ● the executable, which takes
    care of
    ○ parsing command line
    options
    ○ reading input
    ○ outputting the results
    ● the library, which contains
    ○ a function to parse and
    apply transforms to our
    HTML
    ○ a parser for CSS
    Parse CSS using AttoParsec to a flat
    List of Rules of Selector and List of
    Lines (property-value pairs)
    Parse HTML using TagSoup to a flat
    List of Tags (Open, Closing, Text, etc.)
    Extract the styles by matching the
    Rules to classes in the HTML and inline
    them, removing classes in the process

    View Slide

  11. Parsing CSS
    First need to put it in terms of types we
    can work with, using simple data
    types.
    Then we use AttoParsec’s functions to
    write instructions to move around a
    cursor and parse the result out.
    “>>” -- sequentially compose two
    actions and throw away the left side).
    “<|>” -- attempt the left action, and
    apply the right if it fails ~48 LOC with
    whitespace
    This is the whole parser!

    View Slide

  12. Transforming
    HTML
    We should be able to take a list of our
    Rules and input HTML to produce
    transformed HTML.
    We use TagSoup here to parse the
    HTML and conditionally apply a
    transform as we need.
    We extract styles that we need from
    the rules using a list of classnames
    that we get from the tag. We then
    remove the class attribute since
    Flockler will wipe all attributes if it
    exists on a tag.

    View Slide

  13. Extracting styles
    We use the simplest way possible to
    match the styles, by looking for
    “.classname” being an infix of a
    selector (which was defined as simply
    Selector Text).
    For every match, we return the result
    of all the inlinable strings
    concatenated together per Line, per
    Rule.

    View Slide

  14. Result
    ```js
    function a(b) {
    return Promise.resolve(
    b.x + 123 + window.x
    );
    }
    ```
    md2sht

    View Slide

  15. That’s it!
    112 lines, 410 words in src/
    63 lines, 244 words in app/
    Only bug after compiling and running:
    comment parsing in CSS (faulty logic)
    ...which is why you write tests!

    View Slide

  16. Tests!

    View Slide

  17. Tests (cont.)
    ● You will never write another
    “expect(a).toBeType(A)” again
    ● Testing pure functions is very easy, and
    you won’t even be allowed to implicitly test
    effectful functions by the compiler (but
    you can explicitly if you need/want to)
    ● You only ever need to test values and logic
    (e.g. not “does this function correctly
    return an object with these keys?”)

    View Slide

  18. That’s it!
    ● Haskell checks our code and guides us as we guide it
    ● Our code can be very descriptive and still be short
    ● We still need tests for value-level details
    ● Everyone can write Haskell and have FUNctional programming
    And even if you don’t care about Haskell,
    ● Writing technical posts on Flockler is super easy now, so do it!

    View Slide

  19. Thanks for listening!
    ● Code is on github.com/justinwoo/md2sht
    ● Oleg is collecting posts on futurice/tech-blogs
    ○ (internal-only repo, sorry everyone)

    View Slide