Your docs are a program

Zainab Ali

https://kebab-ca.se/presentations.html

catphoto

Questions

  • How do I get started?

  • Why should I store cat photos?

  • How do I get my photo?

  • What should I pass to the addPhoto function?

Types of docs

  • Tutorial: Getting started

  • Conceptual guide: Motivation and model

  • How-to: Task focused

  • Reference: Code focused

Doc Tools

Why

  • Functional programmer

  • Scala ambassador

  • Educator

Docs are artifacts

Reference docs

catphoto.scala

/** Gets the url of a random photo of a given cat. * * {{{ * >>> val album = new Album() * >>> album.addPhoto("Mao", "mao.png") * * >>> album.getPhoto("Mao") * mao.png * }}} * @name The name of the cat */ def getPhoto(name: String): String = ???

Reference docs

Doctest

catphoto.scala

/** Gets the url of a random photo of a given cat. * * {{{ * >>> val album = new Album() * >>> album.addPhoto("Mao", "mao.png") * * >>> album.getPhoto("Mao") * mao.png * * }}} */ def getPhoto(name: String): String = ...
sbt> test
[success]

Doctest

catphoto.scala

/** Gets the url of a random photo of a given cat. * * {{{ * >>> val album = new Album() * >>> album.addPhoto("Mao", "mao.png") * * >>> album.getPhoto("Mao") * mao.png * * }}} */ def getPhoto(name: String): Option[String] = ...
sbt> test
- CatPhoto.DocTest
[error] Failed tests

Doctest

catphoto.scala

/** Gets the url of a random photo of a given cat. * * {{{ * >>> val album = new Album() * >>> album.addPhoto("Mao", "mao.png") * * >>> album.getPhoto("Mao") * Some("mao.png") * * }}} */ def getPhoto(name: String): Option[String] = ???
sbt> test
+ CatPhoto.DocTest
[success]

Guides

getting-started.md

# Getting started Create a photo album. ```scala val album = Album() ``` Add a photo for a cat named `Mao`. ```scala album.addPhoto("Mao", "mao.png") ```

mdoc

getting-started.md

# Getting started Create a photo album. ```scala mdoc val album = Album() ``` Add a photo for a cat named `Mao`. ```scala mdoc album.addPhoto("Mao", "mao.png") ```
> mdoc --in getting-started.md
error: getting-started.md:6:13:
Not found: Album - did you mean album?
val album = Album()
            ^^^^^

getting-started.md

# Getting started Import `catphoto.Album`. ```scala mdoc import catphoto.Album ```
> mdoc --in getting-started.md
[success]

out/getting-started.md

# Getting started Import `catphoto.Album` ```scala import catphoto.Album ``` Create a photo album. ```scala val album = Album() // album: Album = Album() ```

getting-started.md

# Getting started This guide is for @@VERSION@@.
> mdoc --site.VERSION="0.1.42" --in getting-started.md

out/getting-started.md

# Getting started This guide is for 0.1.42.

DisplayCatModifier.scala

class DisplayCatModifier extends PostModifier { val name = "displaycat" def process(ctx: PostModifierContext): String = ... }

getting-started.md

Get a random photo for Mao. ```scala mdoc:displaycat album.get("Mao") ```

out/getting-started.md

Get a random photo for Mao. ```scala album.get("Mao") // mao.png ``` ![Mao](mao.png)

Docs are artifacts

  • Compile, test and validate

  • Integrate into CI pipelines

  • Variable substitution

  • Manipulate output

Docs are trees

# Getting started

Import `catphoto.Album`
<html>
<h1>Getting started</h1>
<p>
  Import
  <span>catphoto.Album</span>
</p>
</html>

Docs are code

getting-started.md

# Getting started This guide is for @@VERSION@@. Import `catphoto.Album`. ```scala mdoc import catphoto.Album ``` ... Add a photo for a cat named `Mao`. ```scala mdoc:displaycat album.addPhoto("Mao", "mao.png") ```

thank-you.md

# Thank you! The following cats need lots of treats: - Mao - Popcorn

Bugs

getting-started.md

Add a photo for Cinder.
<html>
<h1>Getting started</h1>
<p>
  Import
  <span>catphoto.Album</span>
</p>
</html>
(html
(h1 Getting started  h1)
(p
  Import
  (span catphoto.Album  span)
  p)
  html)
(html
(h1 Getting started    )
(p
  Import
  (span catphoto.Album      )
   )
     )

Racket

cats.rkt

#lang racket (define myCat "Mao") (define myCats '("Mao" "Popcorn")) (define (stroke name) (string-append "Stroking " myCat))
> racket
λ>
λ> (require "cats.rkt")
λ> myCat
"Mao"
λ> (stroke myCat)
"Stroking Mao"

A language to write languages.

thank-you.html.pmd

#lang pollen # Thank you! The following cats need lots of treats: - Mao - Popcorn
> racket
λ> (require "thank-you.html.pmd")
λ> doc
'(root
  (h1 ((id "thank-you")) "Thank you!")
  (p "The following cats need lots of treats:")
  (ul (li "Mao") (li "Popcorn")))

catname.rkt

#lang racket (require "thank-you.html.pmd") ;; Get the cats from the doc (define cats (select* 'li doc)) ;; catname is a function (define (catname name) (if (member name cats) name (error "A cat wasn’t thanked!" name)))

getting-started.html.pmd

#lang pollen ◊(require "catname.rkt") Add a photo for ◊(catname "Cinder").
λ> (require "getting-started.html.pmd")
A cat wasn't thanked! "Cinder"

Docs are programs

  • Docs are artifacts

  • Docs are trees

  • Docs are code

  • Docs are programs

Where next?

Find me

Thank you!

Questions?