package graft
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file bib.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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120open Forester_core type common = { kind : Bibtex.Fields.kind; title : string; authors : Bibtex.Fields.name list; year : int; doi : string list; abstract : string; journal : string option; url : string option; } let number = let of_string s = match int_of_string_opt s with Some i -> `Int i | None -> `String s in let to_string = function `Int i -> string_of_int i | `String s -> s in Bibtex.Fields.named_field ~name:"number" Bibtex.Fields.{ to_ = to_string; from = of_string } let url = Bibtex.Fields.str_field ~name:"url" let to_common (k, data) = let open Bibtex.Fields in match ( data.%{kind.f}, data.%{title.f}, data.%{authors.f}, data.%{year.f}, data.%{doi.f}, data.%{abstract.f}, data.%{journal.f}, data.%{url.f} ) with | ( Some kind, Some title, Some , Some year, doi, Some abstract, journal, url ) -> let doi = Option.value ~default:[] doi in Some (k, { kind; title; authors; year; doi; abstract; journal; url }) | _ -> Fmt.epr "Warning: Skipping Bibtex Entry\n%!"; None let kind_to_string : Bibtex.Fields.kind -> string = function | Inproceedings -> "inproceedings" | Book -> "book" | Talk -> "talk" | Poster -> "poster" | Article -> "article" let rec inline_string ?(emph = false) s = if emph then Cmarkit.Inline.Strong_emphasis ( Cmarkit.Inline.Emphasis.make (inline_string ~emph:false s), Cmarkit.Meta.none ) else Cmarkit.Inline.Text (s, Cmarkit.Meta.none) let string_value name = function None -> [] | Some v -> [ (name, `String v) ] let parse_doc ~config s = let ( |>> ) database f = let open Bibtex.Fields in Database.add f.name (str f) database in let with_keys = Bibtex.Fields.Database.remove "number" Bibtex.Fields.default_keys |>> number |>> url in let data = Bibtex.parse ~with_keys @@ Lexing.from_string s in let entries = Bibtex.Database.to_list data |> List.filter_map to_common in let entry_to_document (key, c) = let = List.map (fun Bibtex.Fields.{ firstname; lastname } -> ("author", `String (Fmt.str "%s %s" firstname lastname))) c.authors in let nodes = `O ([ ("title", `String c.title); ("date", `String (string_of_int c.year)); ("taxon", `String "Reference"); ("tag", `String (c.kind |> kind_to_string)); ( "meta", `O ([ ("doi", Yaml.Util.string (String.concat "/" c.doi)) ] @ string_value "journal" c.journal @ string_value "external" c.url) ); ] @ authors) in let lines = inline_string c.abstract in let md = Cmarkit.Doc.make (Cmarkit.Block.Blocks ( [ Cmarkit.Block.Heading ( Cmarkit.Block.Heading.make ~level:2 (inline_string "Abstract"), Cmarkit.Meta.none ); Cmarkit.Block.Paragraph (Cmarkit.Block.Paragraph.make lines, Cmarkit.Meta.none); ], Cmarkit.Meta.none )) in let meta_nodes = List.map (Range.locate_opt None) @@ Markdown.code_of_yaml (Some nodes) in let body_nodes = Markdown.parse_doc ~config (Cmarkit_commonmark.of_doc md) in (key, meta_nodes @ body_nodes) in List.map entry_to_document entries