summaryrefslogtreecommitdiff
path: root/biblio/bibtex/utils/pybib/bibfilter
blob: 6f515047e83c99757bfda503fd1d1f721e5d20b7 (plain)
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
#! /usr/bin/env python
#
# Filter bib records that match search criteria
#
# todo:
#	handle tex accent characters, utf-16 etc

# Copyright (c) 2007, Peter Corke
#
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * The name of the copyright holder may not be used to endorse or 
#	promote products derived from this software without specific prior 
#	written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGE.

import Bibliography;
import BibEntry;
import BibTeX;
import string;
import sys;
import optparse;

startDate = None;
endDate = None;

## parse switches
usage = '''usage: %prog [options] [bibfiles]

:: Filter bib records that match search criteria
::   Multiple rules can be applied at the same time '''
p = optparse.OptionParser(usage)
p.add_option('--since', dest='since', action='store', type='str',
             help='start date for selection, format YYYY or MM/YYYY');
p.add_option('--before', dest='before', action='store', type='str',
             help='end date for selection, format YYYY or MM/YYYY');
p.add_option('-i', '--case', dest='caseSens', action='store_true',
             help='make search case sensitive');
p.add_option('--type', dest='type', action='store', type='str',
             help='reference type to search (default all)');
p.add_option('--field', dest='field', nargs=2, action='store', type='str',
             help='field to search (default all) and the value which matches any substring in the specified field');
p.add_option('--hasfield', dest='hasfield', action='store', type='str',
             help='true if specified field is present');
p.add_option('--brief', dest='showBrief', action='store_true',
             help='show the matching records in brief format (default is BibTeX)');
p.add_option('--count', dest='showCount', action='store_true',
             help='show just the number of matching records');
p.set_defaults(since=None, before=None, caseSens=False, type='all', hasfield=None, field=['all', '*'], showBrief=False, showCount=False);
(opts, args) = p.parse_args()
globals().update(opts.__dict__)

if len(args) == 0 and sys.stdin.isatty():
	p.print_help();
	sys.exit(0);

if since:
	startDate = map(int, since.split('/'));
if before:
	endDate = map(int, before.split('/'));


## read the input files	
bib = BibTeX.BibTeX();
if args:
	for f in args:
		bib.parseFile(f);
else:
	bib.parseFile();
			
#print >> sys.stderr,  "looking for <%s> in field <%s>, reftype <%s>" % (field[1], field[0], type)

# search the bibliography for all matches to the field query
l = bib.search(field[0], field[1], type, caseSens);
count = 0;
for be in l:
	# check if it has the required field
	if hasfield:
		if not be.getField(hasfield):
			continue;

	# check the date range
	if be.afterDate(startDate) and be.beforeDate(endDate):
		count += 1;
		if not showCount:
			if showBrief:
				print be;
			else:
				be.write();

if showCount:
	print count;