package bistro

  1. Overview
  2. Docs
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source

Source file html_report.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
open Core
open Bistro

module H = Tyxml.Html

type cell =
  | Text of string
  | Section of string
  | Subsection of string
  | Pdf of pdf pworkflow
  | Svg of svg pworkflow
  | Png of png pworkflow

type t = {
  title : string ;
  cells : cell list ;
}

let make ~title cells = { title ; cells }

let text s = Text s

let pdf x = Pdf x
let svg x = Svg x
let png x = Png x
let section x = Section x
let subsection x = Subsection x

let svg_of_pdf (pdf : pdf pworkflow) : svg pworkflow =
  Workflow.shell ~descr:"notebook.convert" Shell_dsl.[
    cmd "convert" [
      string "-append" ;
      seq ~sep:":" [string "pdf" ; dep pdf] ;
      seq ~sep:":" [string "svg" ; dest] ;
    ]
  ]

let picture  ?(alt = "") format path =
  let format = match format with
    | `svg -> "svg+xml"
    | `png -> "png"
  in
  let contents =
    In_channel.read_all path
    |> Base64.encode_exn
  in
  H.img
    ~src:(Printf.sprintf "data:image/%s;base64,%s" format contents)
    ~alt ()

let render_cell = function
  | Text str -> [%workflow H.p [ H.txt [%param str] ]]
  | Pdf w -> [%workflow picture `svg [%path svg_of_pdf w] ]
  | Svg w -> [%workflow picture `svg [%path w] ]
  | Png w -> [%workflow picture `png [%path w] ]
  | Section s -> [%workflow H.h2 [ H.txt [%param s] ]]
  | Subsection s -> [%workflow H.h3 [ H.txt [%param s] ]]

let%pworkflow render nb =
  let cells = [%eval Workflow.list @@ List.map nb.cells ~f:render_cell] in
  let head_contents = [
    H.link ~rel:[`Stylesheet] ~href:"https://unpkg.com/marx-css/css/marx.min.css" () ;
    H.meta ~a:[H.a_name "viewport" ; H.a_content "width=device-width, initial-scale=1"] () ;
  ]
  in
  let body_contents = [
    H.main (
      H.h1 [ H.txt nb.title ] :: H.hr () :: cells
    ) ;
  ]
  in
  let doc = H.html (H.head (H.title (H.txt nb.title)) head_contents) (H.body body_contents) in
  Out_channel.with_file [%dest] ~f:(fun oc ->
      Tyxml_html.pp () (Format.formatter_of_out_channel oc) doc
    )
OCaml

Innovation. Community. Security.