These internal markdown links (what appear when you link to sections in wikipedia, for example) are called 'Anchor Links'.
Check out the example that uses this module and it's source code.
We model all existing anchors simply as a list of strings.
Anchor link checking can go wrong in two ways:
DuplicatedAnchors: We generated two headings or so with the same anchor.
This is an issue, since linking to one of them won't work.InvalidAnchorLink: We generated a link to an anchor that doesn't exist.Fold a Validated value through your block.
If you don't know how to use this function, take a look at the example.
If you want to know more about what folds are, take a look at the [docs for
Scaffolded].
Map over the view inside a Validated value.
You can use this to construct a view function
myViewReducer : Scaffolded.Block (Html Msg) -> Html Msg
myViewReducer =
-- or any other implementation
Scaffolded.reduceHtml []
viewValidated : Scaffolded.Block (Validated (Html Msg)) -> Validated (Html Msg)
viewValidated block =
block
|> fold
-- Now, we have a `Validated (Scaffolded.Block (Html Msg))`
|> map myViewReducerMap over the Validated value and generate an anchor at the same time!
viewValidated : Scaffolded.Block (Validated (Html Msg)) -> Validated (Html Msg)
viewValidated block =
case block of
Scaffolded.Heading _ ->
block
|> fold
|> mapWithGeneratedAnchor
(\anchor -> Scaffolded.reduceHtml [ Attr.id anchor ])
_ ->
block
|> fold
|> map (Scaffolded.reduceHtml [])(See also the docs for map.)
The extracted words from markdown here are transformed into an 'anchor', which is a string, consisting only of the alphanumeric characters of the contained markdown joined by dashes.
Same as mapWithGeneratedAnchor, but you decide how to extract an anchor link from
the words inside markdown.
Validate given anchor link, to make sure it exists.
viewValidated : Scaffolded.Block (Validated (Html Msg)) -> Validated (Html Msg)
viewValidated block =
case block of
Scaffolded.Link { destination } ->
block
|> fold
|> validateLink destination
|> map (Scaffolded.foldHtml [])
Scaffolded.Heading _ ->
block
|> fold
|> mapWithGeneratedAnchor
(\anchor -> Scaffolded.foldHtml [ Attr.id anchor ])
_ ->
block
|> fold
|> map (Scaffolded.foldHtml [])(See also the docs for map and docs for mapWithGeneratedAnchor.)
If you just started building in your anchor validation, but haven't updated your
Html renderers to reduce to Validated values, just use this function to lift them
automatically.
Generate fairly descriptive error messages
The type we use for folds. You don't need to worry about it. You can use the API for working with it exclusively. That is,
resolve,fold, the variousmaps andvalidateLink.If you're curious what this type is about: Anchor link checking works in two phases:
The markdown gets reduced to the list of words and all used anchors at the same time (the
wordsandgeneratedAnchorsfields).With the information about what anchors there are in the markdown, we can now render it, validating that our links are not invalid at the same time (the
validatefield).