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.
{ validate : Anchors -> Result Error view
, words : List String
, generatedAnchors : Anchors
}
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 various map
s and
validateLink
.
If you're curious what this type is about: Anchor link checking works in two phases:
words
and generatedAnchors
fields).validate
field).List String
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 : Markdown.Scaffolded.Block (Validated view) -> Validated (Markdown.Scaffolded.Block view)
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 fold
s are, take a look at the [docs for
Scaffolded
].
map : (a -> b) -> Validated a -> Validated b
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 myViewReducer
mapWithGeneratedAnchor : (String -> a -> b) -> Validated a -> Validated b
Map 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.
mapWithCustomGeneratedAnchor : (List String -> String) -> (String -> a -> b) -> Validated a -> Validated b
Same as [mapWithGeneratedAnchor
], but you decide how to extract an anchor link from
the words inside markdown.
validateLink : String -> Validated view -> Validated view
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
.)
liftHtmlRenderer : Markdown.Html.Renderer (List a -> a) -> Markdown.Html.Renderer (List (Validated a) -> Validated a)
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.
resolve : (Error -> error) -> List (Validated a) -> Result error (List a)
Resolve validation errors
errorToString : Error -> String
Generate fairly descriptive error messages