fslaborg / zzarchive-FsLab

A collection of packages for data science with F#
http://fslab.org
Other
159 stars 42 forks source link

How does fslab add AddHtmlPrinter to fsi object? #118

Closed kflu closed 6 years ago

kflu commented 8 years ago

In digging into formatting object as HTML using AddHtmlPrinter, I ran into this code in fslab project. But I don't understand why adding AddHtmlPrinter to type __ReflectHelper.ForwardingInteractiveSettings could achieve it? What is __ReflectHelper.ForwardingInteractiveSettings?

  /// Extend the `fsi` object with `fsi.AddHtmlPrinter` 
  let addHtmlPrinter = """
    module FsInteractiveService = 
      let mutable htmlPrinters = []
      let tryFormatHtml o = htmlPrinters |> Seq.tryPick (fun f -> f o)
      let htmlPrinterParams = System.Collections.Generic.Dictionary<string, obj>()
      do htmlPrinterParams.["html-standalone-output"] <- @html-standalone-output

    type __ReflectHelper.ForwardingInteractiveSettings with
      member x.HtmlPrinterParameters = FsInteractiveService.htmlPrinterParams
      member x.AddHtmlPrinter<'T>(f:'T -> seq<string * string> * string) = 
        FsInteractiveService.htmlPrinters <- (fun (value:obj) ->
          match value with
          | :? 'T as value -> Some(f value)
          | _ -> None) :: FsInteractiveService.htmlPrinters"""

...

let addHtmlPrinter = addHtmlPrinter.Replace("@html-standalone-output", if ctx.Standalone then "true" else "false")
      match (fsi :> IFsiEvaluator).Evaluate(addHtmlPrinter, false, None) with
      | :? FsiEvaluationResult as res when res.ItValue.IsSome -> ()
      | _ -> failwith "Evaluating addHtmlPrinter code failed"
dsyme commented 6 years ago

Answered in comment on #119