diff --git a/src/libraries/utils/markdown.ml b/src/libraries/utils/markdown.ml
index 0295d8007b6588eac586be4811bc619ef65947d2..7ba2e768fe1742008c87f6a94c73b0f552b7cd15 100644
--- a/src/libraries/utils/markdown.ml
+++ b/src/libraries/utils/markdown.ml
@@ -1,136 +1,71 @@
-(**************************************************************************)
-(*                                                                        *)
-(*  This file is part of Frama-C.                                         *)
-(*                                                                        *)
-(*  Copyright (C) 2007-2019                                               *)
-(*    CEA (Commissariat à l'énergie atomique et aux énergies              *)
-(*         alternatives)                                                  *)
-(*                                                                        *)
-(*  you can redistribute it and/or modify it under the terms of the GNU   *)
-(*  Lesser General Public License as published by the Free Software       *)
-(*  Foundation, version 2.1.                                              *)
-(*                                                                        *)
-(*  It is distributed in the hope that it will be useful,                 *)
-(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)
-(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *)
-(*  GNU Lesser General Public License for more details.                   *)
-(*                                                                        *)
-(*  See the GNU Lesser General Public License version 2.1                 *)
-(*  for more details (enclosed in the file licenses/LGPLv2.1).            *)
-(*                                                                        *)
-(**************************************************************************)
-
-(* -------------------------------------------------------------------------- *)
-(* --- Markdown Documentation Generation Utility                          --- *)
-(* -------------------------------------------------------------------------- *)
-
-type md = Format.formatter -> unit
-type text = md
-type block = md
-type section = md
-
-let pretty fmt w = w fmt
-let pp_text = pretty
-let pp_block = pretty
-let pp_section = pretty
-
-(* -------------------------------------------------------------------------- *)
-(* --- Context                                                            --- *)
-(* -------------------------------------------------------------------------- *)
-
-type toc = level:int -> name:string -> title:string -> unit
-
-type context = {
-  page: string ;
-  path: string list ;
-  names: bool ;
-  level: int ;
-  toc: toc option ;
-}
-
-let context = ref {
-    page = "" ;
-    path = [] ;
-    names = false ;
-    level = 0 ;
-    toc = None ;
+type align = Left | Center | Right
+
+type href =
+  | URL of string
+  | Page of string
+  | Name of string
+  | Section of string * string
+
+type inline =
+  | Plain of string
+  | Emph of string
+  | Bold of string
+  | Inline_code of string
+  | Link of text * href (** [Link(text,url)] *)
+  | Image of string * string (** [Image(alt,location)] *)
+
+and text = inline list
+
+type block_element =
+  | Text of text (** single paragraph of text. *)
+  | Block_quote of element list
+  | UL of block list
+  | OL of block list
+  | DL of (text * text) list (** definition list *)
+  | EL of (string option * text) list (** example list *)
+  | Code_block of string * string list
+
+and block = block_element list
+
+and element =
+  | Block of block
+  | Raw of string list
+   (** non-markdown. Each element of the list is printed as-is on its own line.
+       A blank line separates the [Raw] node from the next one. *)
+  | Comment of string (** markdown comment, printed <!-- like this --> *)
+  | H1 of text * string option (** optional label. *)
+  | H2 of text * string option
+  | H3 of text * string option
+  | H4 of text * string option
+  | H5 of text * string option
+  | H6 of text * string option
+  | Table of { caption: text option; header: (text * align) list;
+                content: text list list; }
+
+type pandoc_markdown =
+  { title: text;
+    authors: text list;
+    date: text;
+    elements: element list
   }
 
-let local ctxt job data =
-  let current = !context in
-  try context := ctxt ; job data ; context := current
-  with err -> context := current ; raise err
+let plain s = [ Plain s]
 
-(* -------------------------------------------------------------------------- *)
-(* --- Combinators                                                        --- *)
-(* -------------------------------------------------------------------------- *)
+let plain_format txt = Format.kasprintf plain txt
 
-let nil _fmt = ()
-let empty= nil
-let space fmt = Format.pp_print_space fmt ()
-let newline fmt = Format.pp_print_newline fmt ()
+let plain_link h =
+  let s = match h with
+    | URL url -> url
+    | Page p -> p
+    | Section (_,s) -> s
+    | Name a -> a
+  in
+  Link ([Inline_code s], URL s)
 
-let merge sep ds fmt =
-  match List.filter (fun d -> d != nil) ds with
-  | [] -> ()
-  | d::ds -> d fmt ; List.iter (fun d -> sep fmt ; d fmt) ds
-
-let glue ?sep ds fmt =
-  match sep with
-  | None -> List.iter (fun d -> d fmt) ds
-  | Some s -> merge s ds fmt
-
-let (<@>) a b =
-  if a == empty then b else
-  if b == empty then a else
-    fun fmt -> a fmt ; b fmt
-
-let (<+>) a b =
-  if a == empty then b else
-  if b == empty then a else
-    fun fmt -> a fmt ; space fmt ; b fmt
-
-let (</>) a b =
-  if a == empty then b else
-  if b == empty then a else
-    fun fmt -> a fmt ; newline fmt ; b fmt
-
-let fmt_text k fmt = Format.fprintf fmt "@[<h 0>%t@]" k
-let fmt_block k fmt = Format.fprintf fmt "@[<v 0>%t@]@\n" k
-
-(* -------------------------------------------------------------------------- *)
-(* --- Elementary Text                                                    --- *)
-(* -------------------------------------------------------------------------- *)
-
-let raw s fmt = Format.pp_print_string fmt s
-let rm s fmt = Format.pp_print_string fmt s
-let it s fmt = Format.fprintf fmt "_%s_" s
-let bf s fmt = Format.fprintf fmt "**%s**" s
-let tt s fmt = Format.fprintf fmt "`%s`" s
-let text = merge space
-let praw s = fmt_block (raw s)
-
-(* -------------------------------------------------------------------------- *)
-(* --- Links                                                              --- *)
-(* -------------------------------------------------------------------------- *)
-
-type href = [
-  | `URL of string
-  | `Page of string
-  | `Name of string
-  | `Section of string * string
-]
-
-let filepath m = String.split_on_char '/' m
-
-let rec relative source target =
-  match source , target with
-  | p::ps , q::qs when p = q -> relative ps qs
-  | [] , _ -> target
-  | _::d , _ -> List.map (fun _ -> "..") d @ target
-
-let lnk target =
-  String.concat "/" (relative !context.path (filepath target))
+let codelines lang pp code =
+  let s = Format.asprintf "@[%a@]" pp code in
+  let lines = String.split_on_char '\n' s in
+  Code_block (lang, lines)
 
 let id m =
   let buffer = Buffer.create (String.length m) in
@@ -149,185 +84,176 @@ let id m =
       | _ -> ()) m ;
   Buffer.contents buffer
 
-let href ?title (h : href) fmt =
-  match title , h with
-  | None , `URL url -> Format.fprintf fmt "%s" url
-  | Some w , `URL url -> Format.fprintf fmt "[%s](%s)" w url
-  | None , `Page p -> Format.fprintf fmt "[%s](%s)" p (lnk p)
-  | Some w , `Page p -> Format.fprintf fmt "[%s](%s)" w (lnk p)
-  | None , `Section(p,s) -> Format.fprintf fmt "[%s](%s#%s)" s (lnk p) (id s)
-  | Some w , `Section(p,s) -> Format.fprintf fmt "[%s](%s#%s)" w (lnk p) (id s)
-  | None , `Name a -> Format.fprintf fmt "[%s](#%s)" a (id a)
-  | Some w , `Name a -> Format.fprintf fmt "[%s](#%s)" w (id a)
-
-(* -------------------------------------------------------------------------- *)
-(* --- Blocks                                                             --- *)
-(* -------------------------------------------------------------------------- *)
-
-let aname anchor fmt =
-  Format.fprintf fmt "<a name=\"%s\"></a>@\n" (id anchor)
-
-let title h ?name title fmt =
-  begin
-    let { level ; names ; toc } = !context in
-    let level = max 0 (min 5 (level + h - 1)) in
-    Format.fprintf fmt "%s %s" (String.make level '#') title ;
-    if names || name <> None || toc <> None then
-      begin
-        let anchor = match name with None -> title | Some a -> a in
-        Format.fprintf fmt " {#%s}" (id anchor) ;
-        (match toc with
-         | None -> ()
-         | Some callback ->
-           callback ~level ~name:anchor ~title) ;
-      end ;
-    Format.pp_print_newline fmt () ;
-  end
-
-let h1 = title 1
-let h2 = title 2
-let h3 = title 3
-let h4 = title 4
-
-let indent h w fmt = local { !context with level = !context.level + h } w fmt
-
-let in_h1 = indent 1
-let in_h2 = indent 2
-let in_h3 = indent 3
-let in_h4 = indent 4
-
-let hrule fmt = Format.pp_print_string fmt "-------------------------@."
-
-let par w fmt = Format.fprintf fmt "@[<hov 0>%t@]@." w
-
-let list ws fmt =
-  List.iter
-    (fun w -> Format.fprintf fmt "@[<hov 2>- %t@]@." w) ws
-
-let enum ws fmt =
-  let k = ref 0 in
-  List.iter
-    (fun w -> incr k ; Format.fprintf fmt "@[<hov 3>%d. %t@]@." !k w) ws
-
-let description items fmt =
-  List.iter
-    (fun (a,w) -> Format.fprintf fmt "@[<hov 2>- **%s** %t@]@." a w) items
-
-let code ?(lang="") pp fmt =
-  begin
-    Format.fprintf fmt "@[<v 0>```%s" lang ;
-    let buffer = Buffer.create 80 in
-    let bfmt = Format.formatter_of_buffer buffer in
-    pp bfmt ; Format.pp_print_flush bfmt () ;
-    let content = Buffer.contents buffer in
-    let lines = String.split_on_char '\n' content in
-    let rec clean = function [] -> [] | ""::w -> clean w | w -> w in
+let pp_href fmt = function
+  | URL s | Page s -> Format.pp_print_string fmt s
+  | Section (p,s) -> Format.fprintf fmt "%s#%s" p (id s)
+  | Name a -> Format.fprintf fmt "#%s" (id a)
+
+let rec pp_inline fmt =
+  function
+  | Plain s -> Format.pp_print_string fmt s
+  | Emph s -> Format.fprintf fmt "_%s_" (String.trim s)
+  | Bold s -> Format.fprintf fmt "**%s**" (String.trim s)
+  | Inline_code s -> Format.fprintf fmt "`%s`" (String.trim s)
+  | Link (text,url) ->
+    Format.fprintf fmt "@[<h>[%a](%a)@]@ " pp_text text pp_href url
+  | Image (alt,url) -> Format.fprintf fmt "@[<h>![%s](%s)@]@ " alt url
+
+and pp_text fmt l =
+  match l with
+  | [] -> ()
+  | [ elt ] -> pp_inline fmt elt
+  | elt :: text -> Format.fprintf fmt "%a@ %a" pp_inline elt pp_text text
+
+let pp_lab fmt = function
+  | None -> ()
+  | Some lab -> Format.fprintf fmt " {#%s}" lab
+
+let test_size txt = String.length (Format.asprintf "%a" pp_text txt)
+
+let pp_dashes fmt size =
+  let dashes = String.make (size + 2) '-' in
+  Format.fprintf fmt "%s+" dashes
+
+let pp_sep_line fmt sizes =
+Format.fprintf fmt "@[<h>+";
+List.iter (pp_dashes fmt) sizes;
+Format.fprintf fmt "@]@\n"
+
+let pp_header fmt (t,_) size =
+  let real_size = test_size t in
+  let spaces = String.make (size - real_size) ' ' in
+  Format.fprintf fmt " %a%s |" pp_text t spaces
+
+let pp_headers fmt l sizes =
+  Format.fprintf fmt "@[<h>|";
+  List.iter2 (pp_header fmt) l sizes;
+  Format.fprintf fmt "@]@\n"
+
+let compute_sizes headers contents =
+  let check_line i m line =
+    try max m (test_size (List.nth line i) + 2)
+    with Failure _ -> m
+  in
+  let column_size (i,l) (h,_) =
+    let max = List.fold_left (check_line i) (test_size h) contents in
+    (i+1, max :: l)
+  in
+  let (_,sizes) = List.fold_left column_size (0,[]) headers in
+  List.rev sizes
+
+let pp_align fmt align size =
+  let sep = String.make size '=' in
+  match align with
+  | (_,Left) -> Format.fprintf fmt ":%s=+" sep
+  | (_,Center) -> Format.fprintf fmt ":%s:+" sep
+  | (_,Right) -> Format.fprintf fmt "%s=:+" sep
+
+let pp_aligns fmt headers sizes =
+  Format.fprintf fmt "@[<h>+";
+  List.iter2 (pp_align fmt) headers sizes;
+  Format.fprintf fmt "@]@\n"
+
+let pp_table_cell fmt size t =
+  let real_size = test_size t in
+  let spaces = String.make (size - real_size) ' ' in
+  Format.fprintf fmt " %a%s |" pp_text t spaces
+
+let pp_table_line fmt sizes l =
+  Format.fprintf fmt "@[<h>|";
+  List.iter2 (pp_table_cell fmt) sizes l;
+  Format.fprintf fmt "@]@\n";
+  pp_sep_line fmt sizes
+
+let pp_table_content fmt l sizes =
+  Format.fprintf fmt "@[<v>";
+  List.iter (pp_table_line fmt sizes) l;
+  Format.fprintf fmt "@]"
+
+let rec pp_block_element fmt = function
+  | Text t -> Format.fprintf fmt "@[<hov>%a@]@\n" pp_text t
+  | Block_quote l -> pp_quote fmt l
+  | UL l -> pp_list "*" fmt l
+  | OL l -> pp_list "#." fmt l
+  | DL l ->
     List.iter
-      (fun l -> Format.fprintf fmt "@\n%s" l)
-      (List.rev (clean (List.rev (clean lines)))) ;
-    Format.fprintf fmt "@\n```@]@."
-  end
-
-type column = [
-  | `Left of string
-  | `Right of string
-  | `Center of string
-]
-
-let table columns rows fmt =
-  begin
-    Format.fprintf fmt "@[<v 0>" ;
+      (fun (term,def) ->
+         Format.fprintf fmt "@[<h>%a@]@\n@\n@[<hov 2>: %a@]@\n@\n"
+           pp_text term pp_text def)
+      l
+  | EL l ->
     List.iter
-      (function `Left h | `Right h | `Center h -> Format.fprintf fmt "| %s " h)
-      columns ;
-    Format.fprintf fmt "|@\n" ;
-    List.iter (fun column ->
-        let dash h k = String.make (max 3 (String.length h + k)) '-' in
-        match column with
-        | `Left h -> Format.fprintf fmt "|:%s" (dash h 1)
-        | `Right h -> Format.fprintf fmt "|%s:" (dash h 1)
-        | `Center h -> Format.fprintf fmt "|:%s:" (dash h 0)
-      ) columns ;
-    Format.fprintf fmt "|@\n" ;
-    List.iter (fun row ->
-        List.iter (fun col -> Format.fprintf fmt "| @[<h 0>%t@] " col) row ;
-        Format.fprintf fmt "|@\n" ;
-      ) rows ;
-    Format.fprintf fmt "@]@." ;
-  end
-
-let concat ps = merge newline (List.filter (fun p -> p != empty) ps)
-
-(* -------------------------------------------------------------------------- *)
-(* --- Refs                                                               --- *)
-(* -------------------------------------------------------------------------- *)
-
-let mk f fmt = (f ()) fmt
-let mk_text = mk
-let mk_block = mk
-
-(* -------------------------------------------------------------------------- *)
-(* --- Sections                                                           --- *)
-(* -------------------------------------------------------------------------- *)
-
-let document s = s
-
-let subsections section subsections = section </> in_h1 (merge newline subsections)
-
-let section ?name ~title content subsections =
-  h1 ?name title </> content </> in_h1 (merge newline subsections)
-
-(* -------------------------------------------------------------------------- *)
-(* --- Include File                                                       --- *)
-(* -------------------------------------------------------------------------- *)
-
-let from_file path fmt =
-  let inc = open_in path in
-  try
-    while true do
-      let line = input_line inc in
-      Format.pp_print_string fmt line ;
-      Format.pp_print_newline fmt () ;
-    done
-  with
-  | End_of_file -> close_in inc
-  | exn -> close_in inc ; raise exn
-
-let read_block = from_file
-let read_section = from_file
-let read_text path fmt = Format.fprintf fmt "@[<h 0>%t@]" (from_file path)
-
-(* -------------------------------------------------------------------------- *)
-(* --- Dump to File                                                       --- *)
-(* -------------------------------------------------------------------------- *)
-
-let rec mkdir root page =
-  let dir = Filename.dirname page in
-  if dir <> "." && dir <> ".." then
-    let path = Printf.sprintf "%s/%s" root dir in
-    if not (Sys.file_exists path) then
-      begin
-        mkdir root dir ;
-        try Unix.mkdir path 0o755
-        with Unix.Unix_error _ ->
-          failwith (Printf.sprintf "Can not create direcoty '%s'" dir)
-      end
-
-let dump ~root ~page ?(names=false) ?toc doc =
-  local
-    { page ; path = filepath page ; level = 1 ; toc ; names = names }
-    begin fun () ->
-      mkdir root page ;
-      let out = open_out (Printf.sprintf "%s/%s" root page) in
-      let fmt = Format.formatter_of_out_channel out in
-      try
-        doc fmt ;
-        Format.pp_print_newline fmt () ;
-        close_out out ;
-      with err ->
-        Format.pp_print_newline fmt () ;
-        close_out out ;
-        raise err
-    end ()
-
-(* -------------------------------------------------------------------------- *)
+      (fun (lab,txt) ->
+         match lab with
+         | None -> Format.fprintf fmt "@[<hov 4>(@@) %a@]@\n" pp_text txt
+         | Some s -> Format.fprintf fmt "@[<hov 4>(@@%s) %a@]@\n" s pp_text txt)
+      l
+  | Code_block (language, lines) ->
+    Format.fprintf fmt "@[<h>```%s@]@\n" language;
+    List.iter (fun line -> Format.fprintf fmt "@[<h>%s@]@\n" line) lines;
+    Format.fprintf fmt "```@\n"
+
+and pp_list prefix fmt l =
+  List.iter
+    (fun item ->
+       Format.fprintf fmt "@[<v 4>@[<hov>%s %a@]@]" prefix pp_block item)
+    l
+
+and pp_block fmt l =
+  match l with
+  | [ elt ] -> pp_block_element fmt elt
+  | _ ->
+    Format.fprintf fmt "%a@\n"
+      (Format.pp_print_list ~pp_sep:Format.pp_force_newline pp_block_element) l
+
+and pp_quote fmt l =
+  List.iter
+    (fun elt -> Format.fprintf fmt "@[<v>> %a@]" pp_element elt) l
+
+and pp_element fmt = function
+  | Block b -> Format.fprintf fmt "@[<v>%a@]" pp_block b
+  | Raw l ->
+    Format.(
+      fprintf fmt "%a"
+        (pp_print_list ~pp_sep:pp_force_newline pp_print_string) l)
+  | Comment s ->
+    Format.fprintf fmt
+      "@[<hv>@[<hov 5><!-- %a@]@ -->@]" Format.pp_print_text s
+  | H1(t,lab) -> Format.fprintf fmt "@[<h># %a%a@]" pp_text t pp_lab lab
+  | H2(t,lab) -> Format.fprintf fmt "@[<h>## %a%a@]" pp_text t pp_lab lab
+  | H3(t,lab) -> Format.fprintf fmt "@[<h>### %a%a@]" pp_text t pp_lab lab
+  | H4(t,lab) -> Format.fprintf fmt "@[<h>#### %a%a@]" pp_text t pp_lab lab
+  | H5(t,lab) -> Format.fprintf fmt "@[<h>##### %a%a@]" pp_text t pp_lab lab
+  | H6(t,lab) -> Format.fprintf fmt "@[<h>###### %a%a@]" pp_text t pp_lab lab
+  | Table { caption; header; content } ->
+    (match caption with
+     | None -> ()
+     | Some t -> Format.fprintf fmt "@[<h>Table: %a@]@\n@\n" pp_text t);
+    let sizes = compute_sizes header content in
+    pp_sep_line fmt sizes;
+    pp_headers fmt header sizes;
+    pp_aligns fmt header sizes;
+    pp_table_content fmt content sizes
+
+let pp_elements fmt l =
+  let pp_sep fmt () =
+    Format.pp_print_newline fmt ();
+    Format.pp_print_newline fmt ()
+  in
+  Format.pp_print_list ~pp_sep pp_element fmt l
+
+let pp_authors fmt l =
+  List.iter (fun t -> Format.fprintf fmt "@[<h>- %a@]@\n" pp_text t) l
+
+let pp_pandoc fmt { title; authors; date; elements } =
+  Format.fprintf fmt "@[<v>";
+  if title <> [] || authors <> [] || date <> [] then begin
+    Format.fprintf fmt "@[<h>---@]@\n";
+    Format.fprintf fmt "@[<h>title: %a@]@\n" pp_text title;
+    Format.fprintf fmt "@[<h>author:@]@\n%a" pp_authors authors;
+    Format.fprintf fmt "@[<h>date: %a@]@\n" pp_text date;
+    Format.fprintf fmt "@[<h>...@]@\n";
+    Format.pp_print_newline fmt ();
+  end;
+  pp_elements fmt elements;
+  Format.fprintf fmt "@]%!"
diff --git a/src/libraries/utils/markdown.mli b/src/libraries/utils/markdown.mli
index 34b955919fcc8696722172e66ad43680b689335c..5580883687bda1d784ca95c2bc7a35f36013e298 100644
--- a/src/libraries/utils/markdown.mli
+++ b/src/libraries/utils/markdown.mli
@@ -1,183 +1,76 @@
-(**************************************************************************)
-(*                                                                        *)
-(*  This file is part of Frama-C.                                         *)
-(*                                                                        *)
-(*  Copyright (C) 2007-2019                                               *)
-(*    CEA (Commissariat à l'énergie atomique et aux énergies              *)
-(*         alternatives)                                                  *)
-(*                                                                        *)
-(*  you can redistribute it and/or modify it under the terms of the GNU   *)
-(*  Lesser General Public License as published by the Free Software       *)
-(*  Foundation, version 2.1.                                              *)
-(*                                                                        *)
-(*  It is distributed in the hope that it will be useful,                 *)
-(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)
-(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *)
-(*  GNU Lesser General Public License for more details.                   *)
-(*                                                                        *)
-(*  See the GNU Lesser General Public License version 2.1                 *)
-(*  for more details (enclosed in the file licenses/LGPLv2.1).            *)
-(*                                                                        *)
-(**************************************************************************)
-
-(* -------------------------------------------------------------------------- *)
-(* --- Markdown Documentation Generation Utility                          --- *)
-(* -------------------------------------------------------------------------- *)
-
-(** {2 Markdown}
-
-    A lightweight helper for generating Markdown documentation.
-    Two levels of formatters are defined to help managing indentation and
-    spaces: [text] for inline markdown, and [block] for markdown paragraphs.
-
-*)
-
-type text
-type block
-type section
-
-val (<@>) : text -> text -> text (** Infix operator for [glue] *)
-val (<+>) : text -> text -> text (** Infix operator for [text] *)
-val (</>) : block -> block -> block (** Infix operator for [concat] *)
-
-(** {2 Text Constructors} *)
-
-val nil : text (** Empty *)
-val raw : string -> text (** inlined markdown format *)
-val rm : string -> text (** roman (normal) style *)
-val it : string -> text (** italic style *)
-val bf : string -> text (** bold style *)
-val tt : string -> text (** typewriter style *)
-
-val glue : ?sep:text -> text list -> text (** Glue text fragments *)
-val text : text list -> text (** Glue text fragments with spaces *)
-
-(** {2 Block Constructors} *)
-
-val empty : block (** Empty *)
-val hrule : block (** Horizontal rule *)
-
-val h1 : ?name:string -> string -> block (** Title level 1 *)
-val h2 : ?name:string -> string -> block (** Title level 2 *)
-val h3 : ?name:string -> string -> block (** Title level 3 *)
-val h4 : ?name:string -> string -> block (** Title level 4 *)
-
-val in_h1 : block -> block (** Increment title levels by 1 *)
-val in_h2 : block -> block (** Increment title levels by 2 *)
-val in_h3 : block -> block (** Increment title levels by 3 *)
-val in_h4 : block -> block (** Increment title levels by 4 *)
-
-val par : text -> block (** Simple text paragraph *)
-val praw : string -> block (** Simple raw paragraph *)
-val list : text list -> block (** Itemized list *)
-val enum : text list -> block (** Enumerated list *)
-val description : (string * text) list -> block (** Description list *)
-
-(** Formatted code.
-
-    The code content is pretty-printed in a vertical [<v0>] box
-    with default [Format] formatter.
-    Leading and trailing empty lines are removed and indentation is
-    preserved. *)
-val code : ?lang:string -> (Format.formatter -> unit) -> block
-
-val concat : block list -> block (** Glue paragraphs with empty lines *)
-
-(** {2 Hyperlinks}
-
-    [`Page], [`Name] and [`Section] links refers to the current document,
-    see [dump] function below.
-
-    In [`Section(p,t)], [p] is the page path relative to the
-    document {i root}, and [t] is the section title {i or} name.
-
-    For [`Name a], the links refers to name or title [a]
-    in the {i current} page.
-
-    Hence, everywhere throughout a self-content document directory [~root],
-    local page [~page] inside [~root] can be referenced
-    by [`Page page], and its sections can by [`Section(page,title)]
-    or [`Section(page,name)].
-
-*)
-
-type href = [
-  | `URL of string
-  | `Page of string
-  | `Name of string
-  | `Section of string * string
-]
-
-(** Default [~title] is taken from [href]. When printed,
-    actual link will be relativized with respect to current page. *)
-val href : ?title:string -> href -> text
-
-(** Define a local anchor *)
-val aname : string -> block
-
-(** {2 Tables} *)
-
-type column = [
-  | `Left of string
-  | `Right of string
-  | `Center of string
-]
-
-val table : column list -> text list list -> block
-
-(** {2 Markdown Generator}
-    Generating function are called each time the markdown
-    fragment is printed. *)
-
-val mk_text : (unit -> text) -> text
-val mk_block : (unit -> block) -> block
-
-(** {2 Sections}
-
-    Sections are an alternative to [h1-h4] constructors to build
-    properly nested sub-sections. Deep sections at depth 5 and more are
-    flattened.
-*)
-
-val section : ?name:string -> title:string -> block -> section list -> section
-val subsections : section -> section list -> section
-val document : section -> block
-
-(** {2 Dump to file}
-
-    Generate the markdown [~page] in directory [~root] with the given content.
-    The [~root] directory shall be absolute or relative to the current working
-    directory. The [~page] file-path shall be relative to the [~root] directory
-    and will be used to relocate hyperlinks to other [`Page] and [`Section]
-    properly.
-
-    Hence, everywhere throughout the document, [dump ~root ~page doc]
-    is referenced by [`Page page], and its sections are referenced by
-    [`Section(page,title)].
-
-*)
-
-(** Callback to listen for actual sections when printing a page. *)
-type toc = level:int -> name:string -> title:string -> unit
-
-(** Create a markdown page.
-    - [~root] document directory (relocatable)
-    - [~page] relative file-path of the page in [~root] (non relocatable)
-    - [~names] generate explicit [<a name=...>] tags for all titles
-    - [~toc] optional callback to register table of contents
-*)
-val dump : root:string -> page:string -> ?names:bool -> ?toc:toc -> block -> unit
-
-(** {2 Miscellaneous} *)
-
-val read_text : string -> text
-val read_block : string -> block
-val read_section : string -> section
-
-val fmt_text : (Format.formatter -> unit) -> text
-val fmt_block : (Format.formatter -> unit) -> block
-val pp_text : Format.formatter -> text -> unit
-val pp_block : Format.formatter -> block -> unit
-val pp_section : Format.formatter -> section -> unit
-
-(* -------------------------------------------------------------------------- *)
+type align = Left | Center | Right
+
+type href =
+  | URL of string
+  | Page of string
+  | Name of string
+  | Section of string * string
+
+type inline =
+  | Plain of string
+  | Emph of string
+  | Bold of string
+  | Inline_code of string
+  | Link of text * href
+  | Image of string * string (** [Image(alt,location)] *)
+
+and text = inline list
+
+type block_element =
+  | Text of text (** single paragraph of text. *)
+  | Block_quote of element list
+  | UL of block list
+  | OL of block list
+  | DL of (text * text) list (** definition list *)
+  | EL of (string option * text) list (** example list *)
+  | Code_block of string * string list
+
+and block = block_element list
+
+and element =
+  | Block of block
+  | Raw of string list
+   (** non-markdown. Each element of the list is printed as-is on its own line.
+       A blank line separates the [Raw] node from the next one. *)
+  | Comment of string (** markdown comment, printed <!-- like this --> *)
+  | H1 of text * string option (** optional label. *)
+  | H2 of text * string option
+  | H3 of text * string option
+  | H4 of text * string option
+  | H5 of text * string option
+  | H6 of text * string option
+  | Table of { caption: text option; header: (text * align) list;
+                content: text list list; }
+
+type pandoc_markdown =
+  { title: text;
+    authors: text list;
+    date: text;
+    elements: element list
+  }
+
+val plain: string -> text
+
+val plain_format: ('a, Format.formatter, unit, text) format4 -> 'a
+
+(** gives a link whose text is the URL itself. *)
+val plain_link: string -> inline
+
+(** [codelines lang pp code] returns a [Code_block] for [code], written
+in [lang], as pretty-printed by [pp]. *)
+val codelines:
+  string -> (Format.formatter -> 'a -> unit) -> 'a -> block_element
+
+val pp_inline: Format.formatter -> inline -> unit
+
+val pp_text: Format.formatter -> text -> unit
+
+val pp_block_element: Format.formatter -> block_element -> unit
+
+val pp_block: Format.formatter -> block -> unit
+
+val pp_element: Format.formatter -> element -> unit
+
+val pp_elements: Format.formatter -> element list -> unit
+
+val pp_pandoc: Format.formatter -> pandoc_markdown -> unit
diff --git a/src/libraries/utils/markdown_old.ml b/src/libraries/utils/markdown_old.ml
new file mode 100644
index 0000000000000000000000000000000000000000..0295d8007b6588eac586be4811bc619ef65947d2
--- /dev/null
+++ b/src/libraries/utils/markdown_old.ml
@@ -0,0 +1,333 @@
+(**************************************************************************)
+(*                                                                        *)
+(*  This file is part of Frama-C.                                         *)
+(*                                                                        *)
+(*  Copyright (C) 2007-2019                                               *)
+(*    CEA (Commissariat à l'énergie atomique et aux énergies              *)
+(*         alternatives)                                                  *)
+(*                                                                        *)
+(*  you can redistribute it and/or modify it under the terms of the GNU   *)
+(*  Lesser General Public License as published by the Free Software       *)
+(*  Foundation, version 2.1.                                              *)
+(*                                                                        *)
+(*  It is distributed in the hope that it will be useful,                 *)
+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)
+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *)
+(*  GNU Lesser General Public License for more details.                   *)
+(*                                                                        *)
+(*  See the GNU Lesser General Public License version 2.1                 *)
+(*  for more details (enclosed in the file licenses/LGPLv2.1).            *)
+(*                                                                        *)
+(**************************************************************************)
+
+(* -------------------------------------------------------------------------- *)
+(* --- Markdown Documentation Generation Utility                          --- *)
+(* -------------------------------------------------------------------------- *)
+
+type md = Format.formatter -> unit
+type text = md
+type block = md
+type section = md
+
+let pretty fmt w = w fmt
+let pp_text = pretty
+let pp_block = pretty
+let pp_section = pretty
+
+(* -------------------------------------------------------------------------- *)
+(* --- Context                                                            --- *)
+(* -------------------------------------------------------------------------- *)
+
+type toc = level:int -> name:string -> title:string -> unit
+
+type context = {
+  page: string ;
+  path: string list ;
+  names: bool ;
+  level: int ;
+  toc: toc option ;
+}
+
+let context = ref {
+    page = "" ;
+    path = [] ;
+    names = false ;
+    level = 0 ;
+    toc = None ;
+  }
+
+let local ctxt job data =
+  let current = !context in
+  try context := ctxt ; job data ; context := current
+  with err -> context := current ; raise err
+
+(* -------------------------------------------------------------------------- *)
+(* --- Combinators                                                        --- *)
+(* -------------------------------------------------------------------------- *)
+
+let nil _fmt = ()
+let empty= nil
+let space fmt = Format.pp_print_space fmt ()
+let newline fmt = Format.pp_print_newline fmt ()
+
+let merge sep ds fmt =
+  match List.filter (fun d -> d != nil) ds with
+  | [] -> ()
+  | d::ds -> d fmt ; List.iter (fun d -> sep fmt ; d fmt) ds
+
+let glue ?sep ds fmt =
+  match sep with
+  | None -> List.iter (fun d -> d fmt) ds
+  | Some s -> merge s ds fmt
+
+let (<@>) a b =
+  if a == empty then b else
+  if b == empty then a else
+    fun fmt -> a fmt ; b fmt
+
+let (<+>) a b =
+  if a == empty then b else
+  if b == empty then a else
+    fun fmt -> a fmt ; space fmt ; b fmt
+
+let (</>) a b =
+  if a == empty then b else
+  if b == empty then a else
+    fun fmt -> a fmt ; newline fmt ; b fmt
+
+let fmt_text k fmt = Format.fprintf fmt "@[<h 0>%t@]" k
+let fmt_block k fmt = Format.fprintf fmt "@[<v 0>%t@]@\n" k
+
+(* -------------------------------------------------------------------------- *)
+(* --- Elementary Text                                                    --- *)
+(* -------------------------------------------------------------------------- *)
+
+let raw s fmt = Format.pp_print_string fmt s
+let rm s fmt = Format.pp_print_string fmt s
+let it s fmt = Format.fprintf fmt "_%s_" s
+let bf s fmt = Format.fprintf fmt "**%s**" s
+let tt s fmt = Format.fprintf fmt "`%s`" s
+let text = merge space
+let praw s = fmt_block (raw s)
+
+(* -------------------------------------------------------------------------- *)
+(* --- Links                                                              --- *)
+(* -------------------------------------------------------------------------- *)
+
+type href = [
+  | `URL of string
+  | `Page of string
+  | `Name of string
+  | `Section of string * string
+]
+
+let filepath m = String.split_on_char '/' m
+
+let rec relative source target =
+  match source , target with
+  | p::ps , q::qs when p = q -> relative ps qs
+  | [] , _ -> target
+  | _::d , _ -> List.map (fun _ -> "..") d @ target
+
+let lnk target =
+  String.concat "/" (relative !context.path (filepath target))
+
+let id m =
+  let buffer = Buffer.create (String.length m) in
+  let lowercase = Char.lowercase_ascii in
+  let dash = ref false in
+  let emit c =
+    if !dash then (Buffer.add_char buffer '-' ; dash := false) ;
+    Buffer.add_char buffer c in
+  String.iter
+    (function
+      | '0'..'9' as c -> emit c
+      | 'a'..'z' as c -> emit c
+      | 'A'..'Z' as c -> emit (lowercase c)
+      | '.' | '_' as c -> emit c
+      | ' ' | '\t' | '\n' | '-' -> dash := (Buffer.length buffer > 0)
+      | _ -> ()) m ;
+  Buffer.contents buffer
+
+let href ?title (h : href) fmt =
+  match title , h with
+  | None , `URL url -> Format.fprintf fmt "%s" url
+  | Some w , `URL url -> Format.fprintf fmt "[%s](%s)" w url
+  | None , `Page p -> Format.fprintf fmt "[%s](%s)" p (lnk p)
+  | Some w , `Page p -> Format.fprintf fmt "[%s](%s)" w (lnk p)
+  | None , `Section(p,s) -> Format.fprintf fmt "[%s](%s#%s)" s (lnk p) (id s)
+  | Some w , `Section(p,s) -> Format.fprintf fmt "[%s](%s#%s)" w (lnk p) (id s)
+  | None , `Name a -> Format.fprintf fmt "[%s](#%s)" a (id a)
+  | Some w , `Name a -> Format.fprintf fmt "[%s](#%s)" w (id a)
+
+(* -------------------------------------------------------------------------- *)
+(* --- Blocks                                                             --- *)
+(* -------------------------------------------------------------------------- *)
+
+let aname anchor fmt =
+  Format.fprintf fmt "<a name=\"%s\"></a>@\n" (id anchor)
+
+let title h ?name title fmt =
+  begin
+    let { level ; names ; toc } = !context in
+    let level = max 0 (min 5 (level + h - 1)) in
+    Format.fprintf fmt "%s %s" (String.make level '#') title ;
+    if names || name <> None || toc <> None then
+      begin
+        let anchor = match name with None -> title | Some a -> a in
+        Format.fprintf fmt " {#%s}" (id anchor) ;
+        (match toc with
+         | None -> ()
+         | Some callback ->
+           callback ~level ~name:anchor ~title) ;
+      end ;
+    Format.pp_print_newline fmt () ;
+  end
+
+let h1 = title 1
+let h2 = title 2
+let h3 = title 3
+let h4 = title 4
+
+let indent h w fmt = local { !context with level = !context.level + h } w fmt
+
+let in_h1 = indent 1
+let in_h2 = indent 2
+let in_h3 = indent 3
+let in_h4 = indent 4
+
+let hrule fmt = Format.pp_print_string fmt "-------------------------@."
+
+let par w fmt = Format.fprintf fmt "@[<hov 0>%t@]@." w
+
+let list ws fmt =
+  List.iter
+    (fun w -> Format.fprintf fmt "@[<hov 2>- %t@]@." w) ws
+
+let enum ws fmt =
+  let k = ref 0 in
+  List.iter
+    (fun w -> incr k ; Format.fprintf fmt "@[<hov 3>%d. %t@]@." !k w) ws
+
+let description items fmt =
+  List.iter
+    (fun (a,w) -> Format.fprintf fmt "@[<hov 2>- **%s** %t@]@." a w) items
+
+let code ?(lang="") pp fmt =
+  begin
+    Format.fprintf fmt "@[<v 0>```%s" lang ;
+    let buffer = Buffer.create 80 in
+    let bfmt = Format.formatter_of_buffer buffer in
+    pp bfmt ; Format.pp_print_flush bfmt () ;
+    let content = Buffer.contents buffer in
+    let lines = String.split_on_char '\n' content in
+    let rec clean = function [] -> [] | ""::w -> clean w | w -> w in
+    List.iter
+      (fun l -> Format.fprintf fmt "@\n%s" l)
+      (List.rev (clean (List.rev (clean lines)))) ;
+    Format.fprintf fmt "@\n```@]@."
+  end
+
+type column = [
+  | `Left of string
+  | `Right of string
+  | `Center of string
+]
+
+let table columns rows fmt =
+  begin
+    Format.fprintf fmt "@[<v 0>" ;
+    List.iter
+      (function `Left h | `Right h | `Center h -> Format.fprintf fmt "| %s " h)
+      columns ;
+    Format.fprintf fmt "|@\n" ;
+    List.iter (fun column ->
+        let dash h k = String.make (max 3 (String.length h + k)) '-' in
+        match column with
+        | `Left h -> Format.fprintf fmt "|:%s" (dash h 1)
+        | `Right h -> Format.fprintf fmt "|%s:" (dash h 1)
+        | `Center h -> Format.fprintf fmt "|:%s:" (dash h 0)
+      ) columns ;
+    Format.fprintf fmt "|@\n" ;
+    List.iter (fun row ->
+        List.iter (fun col -> Format.fprintf fmt "| @[<h 0>%t@] " col) row ;
+        Format.fprintf fmt "|@\n" ;
+      ) rows ;
+    Format.fprintf fmt "@]@." ;
+  end
+
+let concat ps = merge newline (List.filter (fun p -> p != empty) ps)
+
+(* -------------------------------------------------------------------------- *)
+(* --- Refs                                                               --- *)
+(* -------------------------------------------------------------------------- *)
+
+let mk f fmt = (f ()) fmt
+let mk_text = mk
+let mk_block = mk
+
+(* -------------------------------------------------------------------------- *)
+(* --- Sections                                                           --- *)
+(* -------------------------------------------------------------------------- *)
+
+let document s = s
+
+let subsections section subsections = section </> in_h1 (merge newline subsections)
+
+let section ?name ~title content subsections =
+  h1 ?name title </> content </> in_h1 (merge newline subsections)
+
+(* -------------------------------------------------------------------------- *)
+(* --- Include File                                                       --- *)
+(* -------------------------------------------------------------------------- *)
+
+let from_file path fmt =
+  let inc = open_in path in
+  try
+    while true do
+      let line = input_line inc in
+      Format.pp_print_string fmt line ;
+      Format.pp_print_newline fmt () ;
+    done
+  with
+  | End_of_file -> close_in inc
+  | exn -> close_in inc ; raise exn
+
+let read_block = from_file
+let read_section = from_file
+let read_text path fmt = Format.fprintf fmt "@[<h 0>%t@]" (from_file path)
+
+(* -------------------------------------------------------------------------- *)
+(* --- Dump to File                                                       --- *)
+(* -------------------------------------------------------------------------- *)
+
+let rec mkdir root page =
+  let dir = Filename.dirname page in
+  if dir <> "." && dir <> ".." then
+    let path = Printf.sprintf "%s/%s" root dir in
+    if not (Sys.file_exists path) then
+      begin
+        mkdir root dir ;
+        try Unix.mkdir path 0o755
+        with Unix.Unix_error _ ->
+          failwith (Printf.sprintf "Can not create direcoty '%s'" dir)
+      end
+
+let dump ~root ~page ?(names=false) ?toc doc =
+  local
+    { page ; path = filepath page ; level = 1 ; toc ; names = names }
+    begin fun () ->
+      mkdir root page ;
+      let out = open_out (Printf.sprintf "%s/%s" root page) in
+      let fmt = Format.formatter_of_out_channel out in
+      try
+        doc fmt ;
+        Format.pp_print_newline fmt () ;
+        close_out out ;
+      with err ->
+        Format.pp_print_newline fmt () ;
+        close_out out ;
+        raise err
+    end ()
+
+(* -------------------------------------------------------------------------- *)
diff --git a/src/libraries/utils/markdown_old.mli b/src/libraries/utils/markdown_old.mli
new file mode 100644
index 0000000000000000000000000000000000000000..34b955919fcc8696722172e66ad43680b689335c
--- /dev/null
+++ b/src/libraries/utils/markdown_old.mli
@@ -0,0 +1,183 @@
+(**************************************************************************)
+(*                                                                        *)
+(*  This file is part of Frama-C.                                         *)
+(*                                                                        *)
+(*  Copyright (C) 2007-2019                                               *)
+(*    CEA (Commissariat à l'énergie atomique et aux énergies              *)
+(*         alternatives)                                                  *)
+(*                                                                        *)
+(*  you can redistribute it and/or modify it under the terms of the GNU   *)
+(*  Lesser General Public License as published by the Free Software       *)
+(*  Foundation, version 2.1.                                              *)
+(*                                                                        *)
+(*  It is distributed in the hope that it will be useful,                 *)
+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)
+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *)
+(*  GNU Lesser General Public License for more details.                   *)
+(*                                                                        *)
+(*  See the GNU Lesser General Public License version 2.1                 *)
+(*  for more details (enclosed in the file licenses/LGPLv2.1).            *)
+(*                                                                        *)
+(**************************************************************************)
+
+(* -------------------------------------------------------------------------- *)
+(* --- Markdown Documentation Generation Utility                          --- *)
+(* -------------------------------------------------------------------------- *)
+
+(** {2 Markdown}
+
+    A lightweight helper for generating Markdown documentation.
+    Two levels of formatters are defined to help managing indentation and
+    spaces: [text] for inline markdown, and [block] for markdown paragraphs.
+
+*)
+
+type text
+type block
+type section
+
+val (<@>) : text -> text -> text (** Infix operator for [glue] *)
+val (<+>) : text -> text -> text (** Infix operator for [text] *)
+val (</>) : block -> block -> block (** Infix operator for [concat] *)
+
+(** {2 Text Constructors} *)
+
+val nil : text (** Empty *)
+val raw : string -> text (** inlined markdown format *)
+val rm : string -> text (** roman (normal) style *)
+val it : string -> text (** italic style *)
+val bf : string -> text (** bold style *)
+val tt : string -> text (** typewriter style *)
+
+val glue : ?sep:text -> text list -> text (** Glue text fragments *)
+val text : text list -> text (** Glue text fragments with spaces *)
+
+(** {2 Block Constructors} *)
+
+val empty : block (** Empty *)
+val hrule : block (** Horizontal rule *)
+
+val h1 : ?name:string -> string -> block (** Title level 1 *)
+val h2 : ?name:string -> string -> block (** Title level 2 *)
+val h3 : ?name:string -> string -> block (** Title level 3 *)
+val h4 : ?name:string -> string -> block (** Title level 4 *)
+
+val in_h1 : block -> block (** Increment title levels by 1 *)
+val in_h2 : block -> block (** Increment title levels by 2 *)
+val in_h3 : block -> block (** Increment title levels by 3 *)
+val in_h4 : block -> block (** Increment title levels by 4 *)
+
+val par : text -> block (** Simple text paragraph *)
+val praw : string -> block (** Simple raw paragraph *)
+val list : text list -> block (** Itemized list *)
+val enum : text list -> block (** Enumerated list *)
+val description : (string * text) list -> block (** Description list *)
+
+(** Formatted code.
+
+    The code content is pretty-printed in a vertical [<v0>] box
+    with default [Format] formatter.
+    Leading and trailing empty lines are removed and indentation is
+    preserved. *)
+val code : ?lang:string -> (Format.formatter -> unit) -> block
+
+val concat : block list -> block (** Glue paragraphs with empty lines *)
+
+(** {2 Hyperlinks}
+
+    [`Page], [`Name] and [`Section] links refers to the current document,
+    see [dump] function below.
+
+    In [`Section(p,t)], [p] is the page path relative to the
+    document {i root}, and [t] is the section title {i or} name.
+
+    For [`Name a], the links refers to name or title [a]
+    in the {i current} page.
+
+    Hence, everywhere throughout a self-content document directory [~root],
+    local page [~page] inside [~root] can be referenced
+    by [`Page page], and its sections can by [`Section(page,title)]
+    or [`Section(page,name)].
+
+*)
+
+type href = [
+  | `URL of string
+  | `Page of string
+  | `Name of string
+  | `Section of string * string
+]
+
+(** Default [~title] is taken from [href]. When printed,
+    actual link will be relativized with respect to current page. *)
+val href : ?title:string -> href -> text
+
+(** Define a local anchor *)
+val aname : string -> block
+
+(** {2 Tables} *)
+
+type column = [
+  | `Left of string
+  | `Right of string
+  | `Center of string
+]
+
+val table : column list -> text list list -> block
+
+(** {2 Markdown Generator}
+    Generating function are called each time the markdown
+    fragment is printed. *)
+
+val mk_text : (unit -> text) -> text
+val mk_block : (unit -> block) -> block
+
+(** {2 Sections}
+
+    Sections are an alternative to [h1-h4] constructors to build
+    properly nested sub-sections. Deep sections at depth 5 and more are
+    flattened.
+*)
+
+val section : ?name:string -> title:string -> block -> section list -> section
+val subsections : section -> section list -> section
+val document : section -> block
+
+(** {2 Dump to file}
+
+    Generate the markdown [~page] in directory [~root] with the given content.
+    The [~root] directory shall be absolute or relative to the current working
+    directory. The [~page] file-path shall be relative to the [~root] directory
+    and will be used to relocate hyperlinks to other [`Page] and [`Section]
+    properly.
+
+    Hence, everywhere throughout the document, [dump ~root ~page doc]
+    is referenced by [`Page page], and its sections are referenced by
+    [`Section(page,title)].
+
+*)
+
+(** Callback to listen for actual sections when printing a page. *)
+type toc = level:int -> name:string -> title:string -> unit
+
+(** Create a markdown page.
+    - [~root] document directory (relocatable)
+    - [~page] relative file-path of the page in [~root] (non relocatable)
+    - [~names] generate explicit [<a name=...>] tags for all titles
+    - [~toc] optional callback to register table of contents
+*)
+val dump : root:string -> page:string -> ?names:bool -> ?toc:toc -> block -> unit
+
+(** {2 Miscellaneous} *)
+
+val read_text : string -> text
+val read_block : string -> block
+val read_section : string -> section
+
+val fmt_text : (Format.formatter -> unit) -> text
+val fmt_block : (Format.formatter -> unit) -> block
+val pp_text : Format.formatter -> text -> unit
+val pp_block : Format.formatter -> block -> unit
+val pp_section : Format.formatter -> section -> unit
+
+(* -------------------------------------------------------------------------- *)
diff --git a/src/plugins/markdown-report/markdown.ml b/src/plugins/markdown-report/markdown.ml
deleted file mode 100644
index 7ba2e768fe1742008c87f6a94c73b0f552b7cd15..0000000000000000000000000000000000000000
--- a/src/plugins/markdown-report/markdown.ml
+++ /dev/null
@@ -1,259 +0,0 @@
-type align = Left | Center | Right
-
-type href =
-  | URL of string
-  | Page of string
-  | Name of string
-  | Section of string * string
-
-type inline =
-  | Plain of string
-  | Emph of string
-  | Bold of string
-  | Inline_code of string
-  | Link of text * href (** [Link(text,url)] *)
-  | Image of string * string (** [Image(alt,location)] *)
-
-and text = inline list
-
-type block_element =
-  | Text of text (** single paragraph of text. *)
-  | Block_quote of element list
-  | UL of block list
-  | OL of block list
-  | DL of (text * text) list (** definition list *)
-  | EL of (string option * text) list (** example list *)
-  | Code_block of string * string list
-
-and block = block_element list
-
-and element =
-  | Block of block
-  | Raw of string list
-   (** non-markdown. Each element of the list is printed as-is on its own line.
-       A blank line separates the [Raw] node from the next one. *)
-  | Comment of string (** markdown comment, printed <!-- like this --> *)
-  | H1 of text * string option (** optional label. *)
-  | H2 of text * string option
-  | H3 of text * string option
-  | H4 of text * string option
-  | H5 of text * string option
-  | H6 of text * string option
-  | Table of { caption: text option; header: (text * align) list;
-                content: text list list; }
-
-type pandoc_markdown =
-  { title: text;
-    authors: text list;
-    date: text;
-    elements: element list
-  }
-
-let plain s = [ Plain s]
-
-let plain_format txt = Format.kasprintf plain txt
-
-let plain_link h =
-  let s = match h with
-    | URL url -> url
-    | Page p -> p
-    | Section (_,s) -> s
-    | Name a -> a
-  in
-  Link ([Inline_code s], URL s)
-
-let codelines lang pp code =
-  let s = Format.asprintf "@[%a@]" pp code in
-  let lines = String.split_on_char '\n' s in
-  Code_block (lang, lines)
-
-let id m =
-  let buffer = Buffer.create (String.length m) in
-  let lowercase = Char.lowercase_ascii in
-  let dash = ref false in
-  let emit c =
-    if !dash then (Buffer.add_char buffer '-' ; dash := false) ;
-    Buffer.add_char buffer c in
-  String.iter
-    (function
-      | '0'..'9' as c -> emit c
-      | 'a'..'z' as c -> emit c
-      | 'A'..'Z' as c -> emit (lowercase c)
-      | '.' | '_' as c -> emit c
-      | ' ' | '\t' | '\n' | '-' -> dash := (Buffer.length buffer > 0)
-      | _ -> ()) m ;
-  Buffer.contents buffer
-
-let pp_href fmt = function
-  | URL s | Page s -> Format.pp_print_string fmt s
-  | Section (p,s) -> Format.fprintf fmt "%s#%s" p (id s)
-  | Name a -> Format.fprintf fmt "#%s" (id a)
-
-let rec pp_inline fmt =
-  function
-  | Plain s -> Format.pp_print_string fmt s
-  | Emph s -> Format.fprintf fmt "_%s_" (String.trim s)
-  | Bold s -> Format.fprintf fmt "**%s**" (String.trim s)
-  | Inline_code s -> Format.fprintf fmt "`%s`" (String.trim s)
-  | Link (text,url) ->
-    Format.fprintf fmt "@[<h>[%a](%a)@]@ " pp_text text pp_href url
-  | Image (alt,url) -> Format.fprintf fmt "@[<h>![%s](%s)@]@ " alt url
-
-and pp_text fmt l =
-  match l with
-  | [] -> ()
-  | [ elt ] -> pp_inline fmt elt
-  | elt :: text -> Format.fprintf fmt "%a@ %a" pp_inline elt pp_text text
-
-let pp_lab fmt = function
-  | None -> ()
-  | Some lab -> Format.fprintf fmt " {#%s}" lab
-
-let test_size txt = String.length (Format.asprintf "%a" pp_text txt)
-
-let pp_dashes fmt size =
-  let dashes = String.make (size + 2) '-' in
-  Format.fprintf fmt "%s+" dashes
-
-let pp_sep_line fmt sizes =
-Format.fprintf fmt "@[<h>+";
-List.iter (pp_dashes fmt) sizes;
-Format.fprintf fmt "@]@\n"
-
-let pp_header fmt (t,_) size =
-  let real_size = test_size t in
-  let spaces = String.make (size - real_size) ' ' in
-  Format.fprintf fmt " %a%s |" pp_text t spaces
-
-let pp_headers fmt l sizes =
-  Format.fprintf fmt "@[<h>|";
-  List.iter2 (pp_header fmt) l sizes;
-  Format.fprintf fmt "@]@\n"
-
-let compute_sizes headers contents =
-  let check_line i m line =
-    try max m (test_size (List.nth line i) + 2)
-    with Failure _ -> m
-  in
-  let column_size (i,l) (h,_) =
-    let max = List.fold_left (check_line i) (test_size h) contents in
-    (i+1, max :: l)
-  in
-  let (_,sizes) = List.fold_left column_size (0,[]) headers in
-  List.rev sizes
-
-let pp_align fmt align size =
-  let sep = String.make size '=' in
-  match align with
-  | (_,Left) -> Format.fprintf fmt ":%s=+" sep
-  | (_,Center) -> Format.fprintf fmt ":%s:+" sep
-  | (_,Right) -> Format.fprintf fmt "%s=:+" sep
-
-let pp_aligns fmt headers sizes =
-  Format.fprintf fmt "@[<h>+";
-  List.iter2 (pp_align fmt) headers sizes;
-  Format.fprintf fmt "@]@\n"
-
-let pp_table_cell fmt size t =
-  let real_size = test_size t in
-  let spaces = String.make (size - real_size) ' ' in
-  Format.fprintf fmt " %a%s |" pp_text t spaces
-
-let pp_table_line fmt sizes l =
-  Format.fprintf fmt "@[<h>|";
-  List.iter2 (pp_table_cell fmt) sizes l;
-  Format.fprintf fmt "@]@\n";
-  pp_sep_line fmt sizes
-
-let pp_table_content fmt l sizes =
-  Format.fprintf fmt "@[<v>";
-  List.iter (pp_table_line fmt sizes) l;
-  Format.fprintf fmt "@]"
-
-let rec pp_block_element fmt = function
-  | Text t -> Format.fprintf fmt "@[<hov>%a@]@\n" pp_text t
-  | Block_quote l -> pp_quote fmt l
-  | UL l -> pp_list "*" fmt l
-  | OL l -> pp_list "#." fmt l
-  | DL l ->
-    List.iter
-      (fun (term,def) ->
-         Format.fprintf fmt "@[<h>%a@]@\n@\n@[<hov 2>: %a@]@\n@\n"
-           pp_text term pp_text def)
-      l
-  | EL l ->
-    List.iter
-      (fun (lab,txt) ->
-         match lab with
-         | None -> Format.fprintf fmt "@[<hov 4>(@@) %a@]@\n" pp_text txt
-         | Some s -> Format.fprintf fmt "@[<hov 4>(@@%s) %a@]@\n" s pp_text txt)
-      l
-  | Code_block (language, lines) ->
-    Format.fprintf fmt "@[<h>```%s@]@\n" language;
-    List.iter (fun line -> Format.fprintf fmt "@[<h>%s@]@\n" line) lines;
-    Format.fprintf fmt "```@\n"
-
-and pp_list prefix fmt l =
-  List.iter
-    (fun item ->
-       Format.fprintf fmt "@[<v 4>@[<hov>%s %a@]@]" prefix pp_block item)
-    l
-
-and pp_block fmt l =
-  match l with
-  | [ elt ] -> pp_block_element fmt elt
-  | _ ->
-    Format.fprintf fmt "%a@\n"
-      (Format.pp_print_list ~pp_sep:Format.pp_force_newline pp_block_element) l
-
-and pp_quote fmt l =
-  List.iter
-    (fun elt -> Format.fprintf fmt "@[<v>> %a@]" pp_element elt) l
-
-and pp_element fmt = function
-  | Block b -> Format.fprintf fmt "@[<v>%a@]" pp_block b
-  | Raw l ->
-    Format.(
-      fprintf fmt "%a"
-        (pp_print_list ~pp_sep:pp_force_newline pp_print_string) l)
-  | Comment s ->
-    Format.fprintf fmt
-      "@[<hv>@[<hov 5><!-- %a@]@ -->@]" Format.pp_print_text s
-  | H1(t,lab) -> Format.fprintf fmt "@[<h># %a%a@]" pp_text t pp_lab lab
-  | H2(t,lab) -> Format.fprintf fmt "@[<h>## %a%a@]" pp_text t pp_lab lab
-  | H3(t,lab) -> Format.fprintf fmt "@[<h>### %a%a@]" pp_text t pp_lab lab
-  | H4(t,lab) -> Format.fprintf fmt "@[<h>#### %a%a@]" pp_text t pp_lab lab
-  | H5(t,lab) -> Format.fprintf fmt "@[<h>##### %a%a@]" pp_text t pp_lab lab
-  | H6(t,lab) -> Format.fprintf fmt "@[<h>###### %a%a@]" pp_text t pp_lab lab
-  | Table { caption; header; content } ->
-    (match caption with
-     | None -> ()
-     | Some t -> Format.fprintf fmt "@[<h>Table: %a@]@\n@\n" pp_text t);
-    let sizes = compute_sizes header content in
-    pp_sep_line fmt sizes;
-    pp_headers fmt header sizes;
-    pp_aligns fmt header sizes;
-    pp_table_content fmt content sizes
-
-let pp_elements fmt l =
-  let pp_sep fmt () =
-    Format.pp_print_newline fmt ();
-    Format.pp_print_newline fmt ()
-  in
-  Format.pp_print_list ~pp_sep pp_element fmt l
-
-let pp_authors fmt l =
-  List.iter (fun t -> Format.fprintf fmt "@[<h>- %a@]@\n" pp_text t) l
-
-let pp_pandoc fmt { title; authors; date; elements } =
-  Format.fprintf fmt "@[<v>";
-  if title <> [] || authors <> [] || date <> [] then begin
-    Format.fprintf fmt "@[<h>---@]@\n";
-    Format.fprintf fmt "@[<h>title: %a@]@\n" pp_text title;
-    Format.fprintf fmt "@[<h>author:@]@\n%a" pp_authors authors;
-    Format.fprintf fmt "@[<h>date: %a@]@\n" pp_text date;
-    Format.fprintf fmt "@[<h>...@]@\n";
-    Format.pp_print_newline fmt ();
-  end;
-  pp_elements fmt elements;
-  Format.fprintf fmt "@]%!"
diff --git a/src/plugins/markdown-report/markdown.mli b/src/plugins/markdown-report/markdown.mli
deleted file mode 100644
index 5580883687bda1d784ca95c2bc7a35f36013e298..0000000000000000000000000000000000000000
--- a/src/plugins/markdown-report/markdown.mli
+++ /dev/null
@@ -1,76 +0,0 @@
-type align = Left | Center | Right
-
-type href =
-  | URL of string
-  | Page of string
-  | Name of string
-  | Section of string * string
-
-type inline =
-  | Plain of string
-  | Emph of string
-  | Bold of string
-  | Inline_code of string
-  | Link of text * href
-  | Image of string * string (** [Image(alt,location)] *)
-
-and text = inline list
-
-type block_element =
-  | Text of text (** single paragraph of text. *)
-  | Block_quote of element list
-  | UL of block list
-  | OL of block list
-  | DL of (text * text) list (** definition list *)
-  | EL of (string option * text) list (** example list *)
-  | Code_block of string * string list
-
-and block = block_element list
-
-and element =
-  | Block of block
-  | Raw of string list
-   (** non-markdown. Each element of the list is printed as-is on its own line.
-       A blank line separates the [Raw] node from the next one. *)
-  | Comment of string (** markdown comment, printed <!-- like this --> *)
-  | H1 of text * string option (** optional label. *)
-  | H2 of text * string option
-  | H3 of text * string option
-  | H4 of text * string option
-  | H5 of text * string option
-  | H6 of text * string option
-  | Table of { caption: text option; header: (text * align) list;
-                content: text list list; }
-
-type pandoc_markdown =
-  { title: text;
-    authors: text list;
-    date: text;
-    elements: element list
-  }
-
-val plain: string -> text
-
-val plain_format: ('a, Format.formatter, unit, text) format4 -> 'a
-
-(** gives a link whose text is the URL itself. *)
-val plain_link: string -> inline
-
-(** [codelines lang pp code] returns a [Code_block] for [code], written
-in [lang], as pretty-printed by [pp]. *)
-val codelines:
-  string -> (Format.formatter -> 'a -> unit) -> 'a -> block_element
-
-val pp_inline: Format.formatter -> inline -> unit
-
-val pp_text: Format.formatter -> text -> unit
-
-val pp_block_element: Format.formatter -> block_element -> unit
-
-val pp_block: Format.formatter -> block -> unit
-
-val pp_element: Format.formatter -> element -> unit
-
-val pp_elements: Format.formatter -> element list -> unit
-
-val pp_pandoc: Format.formatter -> pandoc_markdown -> unit