diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 2a6fb15b..18d66ea0 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -22,6 +22,7 @@ * Show inherited members from documented base types in a new "Inherited members" section on type pages (MSDN-style). [#590](https://github.com/fsprojects/FSharp.Formatting/issues/590) * Add `true` project file setting to suppress "Inherited from" sections in generated API docs. [#1039](https://github.com/fsprojects/FSharp.Formatting/pull/1039) * Generate `llms.txt` and `llms-full.txt` for LLM consumption by default (opt out via `false`); when enabled, markdown output is always generated alongside HTML (even without a user-provided `_template.md`) and `llms.txt` links point to the `.md` files. [#951](https://github.com/fsprojects/FSharp.Formatting/issues/951) [#980](https://github.com/fsprojects/FSharp.Formatting/pull/980) +* Document `--saveimages` flag (`none`|`some`|`all`) with an explanation of each mode, and add a new "Embedding Images" section covering inline Base64 images and `fsi.AddHtmlPrinter` usage for chart/plot output. [#683](https://github.com/fsprojects/FSharp.Formatting/issues/683) ### Fixed * Strip parameter attribute annotations (e.g. `[]`, `[]`) from hover tooltips in code snippets — these attributes made tooltips unreadable for methods with many optional parameters. [#858](https://github.com/fsprojects/FSharp.Formatting/issues/858) diff --git a/docs/commandline.md b/docs/commandline.md index c44983cf..0e1a4257 100644 --- a/docs/commandline.md +++ b/docs/commandline.md @@ -30,7 +30,7 @@ The command line options accepted are: | `--noapidocs` | Disable generation of API docs | | `--ignoreprojects` | Disable project cracking | | `--eval` | Evaluate F# fragments in scripts | -| `--saveimages` | Save images referenced in docs | +| `--saveimages` | Save images referenced in docs (`none`\|`some`\|`all`, default: `none`). If `some`, images are downloaded and saved locally for LaTeX (`.tex`) and notebook (`.ipynb`) outputs. If `all`, images are also saved for HTML and Markdown outputs. See [Embedding Images](#embedding-images) for details. | | `--nolinenumbers` | Don't add line numbers, the default is to add line numbers. | | `--parameters` | Additional substitution parameters for templates | | `--nonpublic` | The tool will also generate documentation for non-public members | @@ -123,3 +123,47 @@ To add search to your own `_template.html`: ``` + + +## Embedding Images + +### Downloading Remote Images (`--saveimages`) + +The `--saveimages` flag controls whether images referenced in your docs are downloaded and saved locally alongside the generated output. This is primarily useful for non-HTML output formats such as LaTeX (PDF) and Jupyter Notebook (`.ipynb`), which cannot reference remote URLs at display time. + +| Value | Behaviour | +|-------|-----------| +| `none` (default) | Images are referenced by their original URL; nothing is downloaded. | +| `some` | Images are downloaded and saved for LaTeX and notebook outputs only. | +| `all` | Images are downloaded and saved for all output formats including HTML and Markdown. | + +Example: + + [lang=text] + fsdocs build --saveimages some + +### Embedding Images Generated by Scripts + +When using `--eval` to evaluate literate F# scripts, you can embed images produced by code (e.g. charts, plots) directly into the HTML output. + +**Option 1: Inline Base64 image using `include-it-raw`** + +Write a helper that reads an image file and returns an HTML `` tag with the image data embedded as a Base64 string. Then use `(*** include-it-raw ***)` to inject the raw HTML into the output: + + [lang=fsharp] + let inlinePng (fileName: string) = + let bytes = System.IO.File.ReadAllBytes(fileName) + let b64 = System.Convert.ToBase64String(bytes) + sprintf """""" b64 + + // Generate the image in your script, then embed it: + // myChart.SavePng("chart.png") + // (*** hide ***) + // inlinePng "chart.png" + // (*** include-it-raw ***) + +The `(*** hide ***)` command suppresses the source code of the expression, so only the rendered image appears in the output. + +**Option 2: Custom HTML printer via `fsi.AddHtmlPrinter`** + +If your charting library produces values of a known type, you can register a custom HTML printer so that values of that type are automatically rendered as images whenever they appear via `(*** include-it ***)`. See [Embedding Script Output](evaluation.html#using-addprinter-and-addhtmlprinter) for details. diff --git a/docs/evaluation.fsx b/docs/evaluation.fsx index ce06e490..faa2f39d 100644 --- a/docs/evaluation.fsx +++ b/docs/evaluation.fsx @@ -79,6 +79,47 @@ You can use the `include-value` command to format a specific value: You can use `fsi.AddPrinter`, `fsi.AddPrintTransformer` and `fsi.AddHtmlPrinter` to extend the formatting of objects. +`fsi.AddHtmlPrinter` lets you register a function that renders values of a particular type as raw HTML. +The function receives the value and returns a sequence of CSS/JS resource pairs and an HTML string. +Registered printers are invoked automatically when a value of the matching type is included via +`(*** include-it ***)` or `(*** include-it-raw ***)`. + +A common use-case is embedding chart or plot images. For example, if your charting library produces +values of type `MyChart`, you can register a printer that converts them to an `` tag: + + [lang=fsharp] + fsi.AddHtmlPrinter(fun (chart: MyChart) -> + // Convert the chart to a PNG byte array + let bytes = chart.ToPngBytes() + let b64 = System.Convert.ToBase64String(bytes) + // Return (no extra resources, HTML string) + Seq.empty, sprintf """""" b64) + + let myChart = MyChart.Create(data) + (*** include-it ***) + +With this printer registered, `(*** include-it ***)` will emit the chart as an inline Base64 image +in the HTML output. + +If you don't have a custom type but still want to embed an image produced by your script, you can +use a plain helper function together with `(*** include-it-raw ***)`: + + [lang=fsharp] + let inlinePng (fileName: string) = + let bytes = System.IO.File.ReadAllBytes(fileName) + let b64 = System.Convert.ToBase64String(bytes) + sprintf """""" b64 + + // Generate the image, then embed it: + // myChart.SavePng("chart.png") + (*** hide ***) + // inlinePng "chart.png" + (*** include-it-raw ***) + +The `(*** hide ***)` command suppresses the source code of the expression so that only the rendered +image appears in the output. See [Embedding Images](commandline.html#embedding-images) in the command-line +reference for more details, including the `--saveimages` flag for downloading remote images. + ## Emitting Raw Text To emit raw text in F# literate scripts use the following: