Skip to content

Include images in documentation in generated content #928

@tymokvo

Description

@tymokvo

Hello,

I have been trying to include visual content in library documentation. My use case is that I am working on a project that interfaces heavily with CAD workflows. So, it would be very valuable to be able to save snapshots of diagrams/drawings and include them in documentation that is then built into the static content by fsdocs.

I first asked on the fsharp slack for advice on the topic.

For example:

/// Pi is the ratio of circle's circumference to its diameter.
/// ![remote image](https://www.probability.ca/jeff/writing/pi1.jpg)
///
/// ![local image](images/pi.png)
let pi = 3.14159

Would result in an HTML tag like <img src="{root}content/img/pi.png" /> (or some other path in the output directory) in the documentation for that value.

It would be nice to be able to support embedded HTML, especially for resizing images. But I think supporting markdown images would be a good start if it is not already supported.

I have tried running fsdocs build --saveimages=all flag, but it seems to have no effect. This is possibly due to #683.


Looking through the markdown parser, it seems that this syntax should be supported to include an image:

| '!' :: DirectLink(body, link, rest) ->
let (value, ctx) = accLiterals.Value
yield! value
let link, title = getLinkAndTitle (String(Array.ofList link), MarkdownRange.zero)
yield DirectImage(String(Array.ofList body), link, title, ctx.CurrentRange)
yield! parseChars [] rest ctx
| '!' :: IndirectLink(body, link, original, rest) ->
let (value, ctx) = accLiterals.Value
yield! value
let key =
if String.IsNullOrEmpty(link) then
String(body |> Array.ofSeq)
else
link
yield IndirectImage(String(Array.ofList body), original, key, ctx.CurrentRange)
yield! parseChars [] rest ctx

And looking through the BuildCommand, it seems that remote and local images should be supported:

let createImageSaver (rootOutputFolderAsGiven) =
// Download images so that they can be embedded
let wc = new WebClient()
let mutable counter = 0
fun (url: string) ->
if
url.StartsWith("http", StringComparison.Ordinal)
|| url.StartsWith("https", StringComparison.Ordinal)
then
counter <- counter + 1
let ext = Path.GetExtension(url)
let url2 = sprintf "savedimages/saved%d%s" counter ext
let fn = sprintf "%s/%s" rootOutputFolderAsGiven url2
ensureDirectory (sprintf "%s/savedimages" rootOutputFolderAsGiven)
printfn "downloading %s --> %s" url fn
wc.DownloadFile(url, fn)
url2
else
url

Though, the imageSaverOpt value in processFile seems to only ever be passed into the Literate methods, which is what I assume the linked issue is in reference to.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions