When packages are published to package.elm-lang.org
, documentation
is generated for all of the exposed modules (and all of the exposed values).
These docs are formatted as JSON for easy consumption by anyone.
This module helps you decode the JSON docs into nice Elm values! It is
currently used by package.elm-lang.org
to help turn JSON into nice
web pages!
decoder : Json.Decode.Decoder Module
Decode the JSON documentation produced by elm-make
for an individual
module. The documentation for a whole package is an array of module docs,
so you may need to say (Decode.list Docs.decoder)
depending on what you
want to do.
{ name : String
, comment : String
, unions : List Union
, aliases : List Alias
, values : List Value
, binops : List Binop
}
All the documentation for a particular module.
name
is the module namecomment
is the module commentThe actual exposed stuff is broken into categories.
{ name : String
, comment : String
, args : List String
, tipe : Elm.Type.Type
}
Documentation for a type alias. For example, if you had the source code:
{-| pair of values -}
type alias Pair a = ( a, a )
When it became an Alias
it would be like this:
{ name = "Pair"
, comment = " pair of values "
, args = ["a"]
, tipe = Tuple [ Var "a", Var "a" ]
}
{ name : String
, comment : String
, args : List String
, tags : List ( String
, List Elm.Type.Type )
}
Documentation for a union type. For example, if you had the source code:
{-| maybe -}
type Maybe a = Nothing | Just a
When it became a Union
it would be like this:
{ name = "Maybe"
, comment = " maybe "
, args = ["a"]
, tags =
[ ("Nothing", [])
, ("Just", [Var "a"])
]
}
{ name : String
, comment : String
, tipe : Elm.Type.Type
}
Documentation for values and functions. For example, if you had the source code:
{-| do not do anything -}
identity : a -> a
identity value =
value
The Value
would look like this:
{ name = "identity"
, comment = " do not do anything "
, tipe = Lambda (Var "a") (Var "a")
}
{ name : String
, comment : String
, tipe : Elm.Type.Type
, associativity : Associativity
, precedence : Basics.Int
}
Documentation for binary operators. The content for (+)
might look
something like this:
{ name = "+"
, comment = "Add numbers"
, tipe = Lambda (Var "number") (Lambda (Var "number") (Var "number"))
, associativity = Left
, precedence = 6
}
The associativity of an infix operator. This determines how we add parentheses around everything. Here are some examples:
1 + 2 + 3 + 4
We have to do the operations in some order, so which of these interpretations should we choose?
((1 + 2) + 3) + 4 -- left-associative
1 + (2 + (3 + 4)) -- right-associative
This is really important for operators like (|>)
!
Some operators are non-associative though, meaning we do not try to add
missing parentheses. (==)
is a nice example. 1 == 2 == 3
just is not
allowed!
toBlocks : Module -> List Block
The module comment describes exactly how the generated docs should look.
It is a mix of markdown and @docs
declarations that specify when other
documentation should appear. Matching all this information up is somewhat
tricky though.
So calling toBlocks
on a Module
gives you a List Block
with all the
information necessary to visualize the docs as intended.
This type represents a Block
of documentation to show to the user.
After getting a List Block
from toBlocks
, everything is in the right order
and you can focus on turning the blocks into HTML exactly how you want.
Note: This should never produce an UnknownBlock
but I figured it
would be better to let the block visualizer decide what to do in that case.