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

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions