-
Notifications
You must be signed in to change notification settings - Fork 27
/
bibfilter.ml
124 lines (112 loc) · 4 KB
/
bibfilter.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
120
121
122
123
124
(**************************************************************************)
(* bibtex2html - A BibTeX to HTML translator *)
(* Copyright (C) 1997-2014 Jean-Christophe Filliâtre and Claude Marché *)
(* *)
(* This software is free software; you can redistribute it and/or *)
(* modify it under the terms of the GNU General Public *)
(* License version 2, as published by the Free Software Foundation. *)
(* *)
(* This software 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 General Public License version 2 for more details *)
(* (enclosed in the file GPL). *)
(**************************************************************************)
(*s Filtering and saturating BibTeX files. *)
open Printf
open Bibtex
let debug = false
(*s [filter bib f] returns the list of keys of [bib] whose fields
satisfy the filter criterion [f] *)
let filter biblio criterion =
Bibtex.fold
(fun entry keys ->
match entry with
Entry(entry_type,key,fields)
when criterion entry_type key fields ->
KeySet.add key keys
| _ -> keys)
biblio
KeySet.empty
(*s [needed_keys biblio field value keys] returns the set of keys
[keys] augmented with the needed keys for [value] *)
let rec needed_keys_for_field biblio field value keys abbrevs =
if field = "crossref"
then
match value with
[String(s)] ->
if not (KeySet.mem s keys) then
begin
try
let e = find_entry s biblio
in
if debug then begin
eprintf "We need additional crossref %s\n" s
end;
needed_keys_for_entry biblio (KeySet.add s keys) abbrevs e
with Not_found ->
if not !Options.quiet then
eprintf "Warning: cross-reference \"%s\" not found.\n" s;
if !Options.warn_error then exit 2;
(keys,abbrevs)
end
else (keys,abbrevs)
| _ ->
if not !Options.quiet then
eprintf "Warning: cross-references must be constant strings\n";
if !Options.warn_error then exit 2;
(keys,abbrevs)
else
List.fold_right
(fun a (keys,abbrevs) ->
match a with
Id(id) ->
let id = String.lowercase_ascii id in
if not (KeySet.mem id abbrevs)
then
try
let e = find_abbrev id biblio in
if debug then begin
eprintf "We need additional abbrev %s\n" id
end;
needed_keys_for_entry biblio keys (KeySet.add id abbrevs) e
with Not_found ->
if abbrev_is_implicit id then (keys,abbrevs)
else
begin
if not !Options.quiet then
eprintf "Warning: string \"%s\" not found.\n" id;
if !Options.warn_error then exit 2;
(keys,abbrevs)
end
else (keys,abbrevs)
| _ -> (keys,abbrevs))
value
(keys,abbrevs)
and needed_keys_for_entry biblio keys abbrevs = function
Entry(entry_type,key,fields) ->
List.fold_right
(fun (field,value) (keys,abbrevs) ->
(*i eprintf "Field : %s\n" field; i*)
needed_keys_for_field biblio field value keys abbrevs)
fields
(keys,abbrevs)
| Abbrev(field,value) ->
needed_keys_for_field biblio field value keys abbrevs
| _ -> (keys,abbrevs)
(*s [saturate bib l] returns the smallest part of the bibliography
[bib] containing all the keys in l together with all the necessary
abbreviation strings and cross-references *)
let saturate biblio s =
let (keys,abbrevs) =
Bibtex.fold
(fun entry (keys,abbrevs) ->
match entry with
| Entry(_,key,_) as e when KeySet.mem key s ->
needed_keys_for_entry biblio keys abbrevs e
| _ -> (keys,abbrevs))
biblio
(s,KeySet.empty)
in
KeySet.union keys abbrevs