From 28c042edc113ec122432c26b86d4cf030a0e606d Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Fri, 10 Feb 2023 20:58:48 +0100 Subject: [PATCH] wip mathjax rendering in notebooks --- .../Plotly.NET.Interactive.fsproj | 3 +- .../CSharpLayer/GenericChartExtensions.fs | 2 +- src/Plotly.NET/ChartAPI/Chart.fs | 14 +++++---- src/Plotly.NET/ChartAPI/GenericChart.fs | 30 +++++++++++++++---- .../DisplayOptions/DisplayOptions.fs | 16 +++++++++- src/Plotly.NET/Globals.fs | 18 ++++++++--- .../Plotly.NET.Tests.FSharpConsole/Program.fs | 21 ++++--------- 7 files changed, 69 insertions(+), 35 deletions(-) diff --git a/src/Plotly.NET.Interactive/Plotly.NET.Interactive.fsproj b/src/Plotly.NET.Interactive/Plotly.NET.Interactive.fsproj index a786f24db..281934646 100644 --- a/src/Plotly.NET.Interactive/Plotly.NET.Interactive.fsproj +++ b/src/Plotly.NET.Interactive/Plotly.NET.Interactive.fsproj @@ -49,7 +49,8 @@ - + + diff --git a/src/Plotly.NET/CSharpLayer/GenericChartExtensions.fs b/src/Plotly.NET/CSharpLayer/GenericChartExtensions.fs index 91fa36c52..0b501d088 100644 --- a/src/Plotly.NET/CSharpLayer/GenericChartExtensions.fs +++ b/src/Plotly.NET/CSharpLayer/GenericChartExtensions.fs @@ -961,7 +961,7 @@ module GenericChartExtensions = [] member this.WithMathTex( [] ?AppendTags: bool, - [] ?MathJaxVersion: int + [] ?MathJaxVersion: MathJax ) = let append = Option.defaultValue true AppendTags diff --git a/src/Plotly.NET/ChartAPI/Chart.fs b/src/Plotly.NET/ChartAPI/Chart.fs index 9dec96a15..a16a17cf5 100644 --- a/src/Plotly.NET/ChartAPI/Chart.fs +++ b/src/Plotly.NET/ChartAPI/Chart.fs @@ -3207,25 +3207,27 @@ type Chart = [] static member withMathTex( [] ?AppendTags: bool, - [] ?MathJaxVersion: int + [] ?MathJaxVersion: MathJax ) = - let version = MathJaxVersion |> Option.defaultValue 3 + let version = MathJaxVersion |> Option.defaultValue MathJax.V2 let tags = - if version = 2 then - Globals.MATHJAX_V2_TAGS - else - Globals.MATHJAX_V3_TAGS + match version with + | V2 -> Globals.MATHJAX_V2_TAGS + | V3 -> Globals.MATHJAX_V3_TAGS + | _ -> [] (fun (ch: GenericChart) -> if (AppendTags |> Option.defaultValue true) then ch |> Chart.withAdditionalHeadTags tags + |> GenericChart.mapDisplayOptions (DisplayOptions.setMathJaxVersion version) |> Chart.withConfigStyle(TypesetMath=true) else ch |> Chart.withHeadTags tags + |> GenericChart.mapDisplayOptions (DisplayOptions.setMathJaxVersion version) |> Chart.withConfigStyle(TypesetMath=true) ) diff --git a/src/Plotly.NET/ChartAPI/GenericChart.fs b/src/Plotly.NET/ChartAPI/GenericChart.fs index 751a75d45..88653ebb9 100644 --- a/src/Plotly.NET/ChartAPI/GenericChart.fs +++ b/src/Plotly.NET/ChartAPI/GenericChart.fs @@ -30,16 +30,21 @@ type HTML() = static member CreateChartHTML( data: string, layout: string, - config: string + config: string, + mathjax: MathJax ) = - let scriptContent = """ var renderPlotly_[SCRIPTID] = function() { - var fsharpPlotlyRequire = requirejs.config({context:'fsharp-plotly',paths:{plotly:'https://cdn.plot.ly/plotly-[PLOTLYJS_VERSION].min'}}) || require; - fsharpPlotlyRequire(['plotly'], function(Plotly) { + var fsharpPlotlyRequire = requirejs.config( + { + context:'fsharp-plotly', + paths: [REQUIRE_PATHS] + }) || require; + fsharpPlotlyRequire([REQUIRE_LIST], function(Plotly) { var data = [DATA]; var layout = [LAYOUT]; var config = [CONFIG]; + [MATHJAX_CONFIG] Plotly.newPlot('[ID]', data, layout, config); }); }; @@ -57,12 +62,23 @@ else { """ let guid = Guid.NewGuid().ToString() + let require_list, require_paths, mathjax_config = + match mathjax with + | V2 -> """['plotly', 'mathjax']""", $"{{plotly: '{Globals.PLOTLY_REQUIRE_CDN}', mathjax: '{Globals.MATHJAX_V2_REQUIRE_CDN}'}}", Globals.MATHJAX_V2_CONFIG + // found no way on how to load mathjax v3 using requirejs + | V3 -> """['plotly', 'mathjax']""", $"{{plotly: '{Globals.PLOTLY_REQUIRE_CDN}', mathjax: '{Globals.MATHJAX_V3_REQUIRE_CDN}'}}", Globals.MATHJAX_V3_CONFIG + | _ -> """['plotly']""", $"{{plotly: {Globals.PLOTLY_REQUIRE_CDN}}}", "" + + [ div [_id guid] [comment "Plotly chart will be drawn inside this DIV"] script [_type "text/javascript"] [ rawText ( scriptContent .Replace("[PLOTLYJS_VERSION]",Globals.PLOTLYJS_VERSION) + .Replace("[REQUIRE_PATHS]",require_paths) + .Replace("[REQUIRE_LIST]",require_list) + .Replace("[MATHJAX_CONFIG]",mathjax_config) .Replace("[SCRIPTID]",guid.Replace("-","")) .Replace("[ID]",guid) .Replace("[DATA]",data) @@ -308,7 +324,8 @@ module GenericChart = yield! HTML.CreateChartHTML( tracesJson, layoutJson, - configJson + configJson, + displayOpts.MathJaxVersion ) yield! displayOpts.Description ] @@ -339,7 +356,8 @@ module GenericChart = chart = HTML.CreateChartHTML( tracesJson, layoutJson, - configJson + configJson, + displayOpts.MathJaxVersion ), AdditionalHeadTags = displayOpts.AdditionalHeadTags, Description = displayOpts.Description diff --git a/src/Plotly.NET/DisplayOptions/DisplayOptions.fs b/src/Plotly.NET/DisplayOptions/DisplayOptions.fs index df9a13910..d1a7ecc21 100644 --- a/src/Plotly.NET/DisplayOptions/DisplayOptions.fs +++ b/src/Plotly.NET/DisplayOptions/DisplayOptions.fs @@ -4,17 +4,25 @@ open DynamicObj open System.Runtime.InteropServices open Giraffe.ViewEngine +type MathJax = + | V2 + | V3 + | NoMathJax + type DisplayOptions = { AdditionalHeadTags: XmlNode list Description: XmlNode list + MathJaxVersion: MathJax } with static member Create( [] ?AdditionalHeadTags: XmlNode list, - [] ?Description: XmlNode list + [] ?Description: XmlNode list, + [] ?MathJaxVersion: MathJax ) = { AdditionalHeadTags = AdditionalHeadTags |> Option.defaultValue [] Description = Description |> Option.defaultValue [] + MathJaxVersion = MathJaxVersion |> Option.defaultValue MathJax.V2 } static member addAdditionalHeadTags (additionalHeadTags: XmlNode list) (displayOpts:DisplayOptions) = @@ -28,3 +36,9 @@ type DisplayOptions = { displayOpts with Description = List.append displayOpts.Description description } + + static member setMathJaxVersion (version: MathJax) (displayOpts:DisplayOptions) = + { + displayOpts with + MathJaxVersion = version + } diff --git a/src/Plotly.NET/Globals.fs b/src/Plotly.NET/Globals.fs index fda859d03..2af862884 100644 --- a/src/Plotly.NET/Globals.fs +++ b/src/Plotly.NET/Globals.fs @@ -7,6 +7,8 @@ open Giraffe.ViewEngine /// The plotly js version loaded from cdn in rendered html docs let [] PLOTLYJS_VERSION = "2.18.1" +let PLOTLY_CDN = $"""https://cdn.plot.ly/plotly-{PLOTLYJS_VERSION}.min.js""" +let PLOTLY_REQUIRE_CDN = $"""https://cdn.plot.ly/plotly-{PLOTLYJS_VERSION}.min""" /// let internal JSON_CONFIG = @@ -14,16 +16,24 @@ let internal JSON_CONFIG = ReferenceLoopHandling = ReferenceLoopHandling.Serialize ) +let [] MATHJAX_V2_CDN = """https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS-MML_HTMLorMML%2CSafe.js&ver=4.1""" +let [] MATHJAX_V2_REQUIRE_CDN = """https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS-MML_HTMLorMML%2CSafe.js&ver=4.1""" +let [] MATHJAX_V2_CONFIG = """MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']], processEscapes: true}});""" + +let [] MATHJAX_V3_CDN = """https://cdn.jsdelivr.net/npm/mathjax@3.2.0/es5/tex-svg.js""" +let [] MATHJAX_V3_REQUIRE_CDN = """https://cdn.jsdelivr.net/npm/mathjax@3.2.0/es5/tex-svg""" +let [] MATHJAX_V3_CONFIG = """MathJax = {tex: {inlineMath: [['$', '$'], ['\\(', '\\)']]}};""" + /// the mathjax v2 tags to add to html docs for rendering latex let internal MATHJAX_V2_TAGS = [ - script [_type "text/x-mathjax-config;executed=true"] [rawText """MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']], processEscapes: true}});"""] - script [_type "text/javascript"; _src """https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS-MML_HTMLorMML%2CSafe.js&ver=4.1"""] [] + script [_type "text/x-mathjax-config;executed=true"] [rawText MATHJAX_V2_CONFIG] + script [_type "text/javascript"; _src MATHJAX_V2_CDN] [] ] /// the mathjax v3 tags to add to html docs for rendering latex let internal MATHJAX_V3_TAGS = [ - script [] [rawText """MathJax = {tex: {inlineMath: [['$', '$'], ['\\(', '\\)']]}};"""] - script [_src """https://cdn.jsdelivr.net/npm/mathjax@3.2.0/es5/tex-svg.js"""] [] + script [] [rawText MATHJAX_V3_CONFIG] + script [_src MATHJAX_V3_CDN] [] ] \ No newline at end of file diff --git a/tests/Plotly.NET.Tests.FSharpConsole/Program.fs b/tests/Plotly.NET.Tests.FSharpConsole/Program.fs index 7a1e7bd13..644aa32fd 100644 --- a/tests/Plotly.NET.Tests.FSharpConsole/Program.fs +++ b/tests/Plotly.NET.Tests.FSharpConsole/Program.fs @@ -15,23 +15,12 @@ let from whom = [] let main argv = [ - Chart.Line([1,2; 3,4]) - |> Chart.withAxisAnchor(Y=1) - Chart.Spline([100,200; 300,400]) - |> Chart.withAxisAnchor(Y=2) + Chart.Point([(1.,2.)],@"$\beta_{1c} = 25 \pm 11 \text{ km s}^{-1}$") + Chart.Point([(2.,4.)],@"$\beta_{1c} = 25 \pm 11 \text{ km s}^{-1}$") ] |> Chart.combine - |> Chart.withYAxis (LinearAxis.init(), Id = StyleParam.SubPlotId.YAxis 1) - |> Chart.withYAxis (LinearAxis.init(Anchor = StyleParam.LinearAxisId.Free, Shift = -50, ShowLine = true), Id = StyleParam.SubPlotId.YAxis 2) - |> Chart.withDescription [ - h1 [] [str "now look at this!"] - ul [] [ - li [] [str "this"] - li [] [str "is"] - li [] [str "a"] - li [] [img [_src "https://images.deepai.org/machine-learning-models/0c7ba850aa2443d7b40f9a45d9c86d3f/text2imgthumb.jpeg"]] - ] - ] - |> Chart.withSize(1000,1000) + |> Chart.withTitle @"$\beta_{1c} = 25 \pm 11 \text{ km s}^{-1}$" + // include mathtex tags in . pass true to append these scripts, false to ONLY include MathTeX. + |> Chart.withMathTex(true) |> Chart.show 0 \ No newline at end of file