File: bib.pl

package info (click to toggle)
swi-prolog-packages 5.0.1-1
  • links: PTS
  • area: main
  • in suites: woody
  • size: 50,688 kB
  • ctags: 25,904
  • sloc: ansic: 195,096; perl: 91,425; cpp: 7,660; sh: 3,046; makefile: 2,750; yacc: 843; awk: 14; sed: 12
file content (153 lines) | stat: -rw-r--r-- 5,330 bytes parent folder | download | duplicates (2)
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*  $Id: bib.pl,v 1.1.1.1 1994/06/27 13:17:20 jan Exp $

    Part of XPCE
    Designed and implemented by Anjo Anjewierden and Jan Wielemaker
    E-mail: jan@swi.psy.uva.nl

    Copyright (C) 1994 University of Amsterdam. All rights reserved.
*/


:- module(pce_bibtex, []).
:- use_module(library(pce)).

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
This library file defines a parser  for   BibTeX  database files.  It is
intended as an example  for  using   XPCE's  text-manipulation  and data
representation techniques and may  be  used   as  a  starting  point for
implementing a BibTeX database manager program.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

		 /*******************************
		 *	      DATABASE		*
		 *******************************/

:- pce_begin_class(bibtex_db,	hash_table, "BibTeX DataBase").

variable(strings,	sheet,	get, "Table of strings").
variable(file,		file*,	get, "File it was loaded from").

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
A BibTeX database is  represented  by   a  hash_table  mapping keys onto
bibtex_entry objects.  A bibtex_entry is subclass of class sheet.

The  database  as  a  whole  also  stores    a  sheet  for  the  defined
string-constants as well as a reference to   the file it was loaded from
(if any).
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

initialise(DB, File:[file]*) :->
	"Create BibTeX database from file"::
	send(DB, send_super, initialise),
	send(DB, slot, strings, new(sheet)),
	(   File \== @default
	->  send(DB, slot, file, File),
	    send(DB, load, File)
	).


/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The database is parsed using a text_buffer.    This  allows us to easily
exploit the regular-expression capabilities of XPCE implemented by class
regex.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

load(DB, File:file) :->
	"Load entries from file"::
	new(TB, text_buffer),
	send(TB, insert_file, 0, File),
	send(DB, parse, TB),
	free(TB).


/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Toplevel loop to parse a BibTeX file.  First of all, the syntax-table of
the text_buffer is  modified  to  treat   the  newline  as  white_space,
allowing the '\s ' operator in regular expressions to include newlines.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

parse(DB, TB:text_buffer) :->
	"Parse all entries from given text-buffer"::
	new(Here, number(0)),
	get(TB, size, Size),
	send(TB, syntax, new(S, syntax_table)),
	send(S, add_syntax, '\n', white_space),
	repeat,
		send(DB, parse_entry, TB, Here),
		get(Here, value, Size), !.


/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Regular expression constants for the various   fields  of a BibTeX file.
Note that GNU-regular expression define `syntax categories': '\s ' means
`any white character (as defined by the  syntax table)', '\w' means `any
word character'.  '\S ' and '\W' are   negations.  See class regex for a
full description.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

:- pce_global(@bibtex_head_regex,
   new(regex('@\(\w+\){'))).
:- pce_global(@bibtex_key_regex,
   new(regex('\s *\(\S +\)\s *,'))).
:- pce_global(@bibtex_att_regex,
   new(regex('\s *\(\w+\)\s *=\s *\("\(\\"\|[^"]\)*"\|\w+\|[^,]+\)\s *,?'))).
:- pce_global(@bibtex_end_attr_regex,
   new(regex('\s *}\s *'))).


parse_entry(DB, TB:text_buffer, Here:number) :->
	"Parse 1 entry"::
	send(@bibtex_head_regex, search, TB, Here), !,
	get(@bibtex_head_regex, register_value, TB, 1, name, T0),
	send(Here, value, @bibtex_head_regex?register_end),
	get(T0, downcase, Type),
	(   Type == string
	->  (	send(@bibtex_att_regex, match, TB, Here)
	    ->	get(@bibtex_att_regex, register_value, TB, 1, name, SName),
		get(@bibtex_att_regex, register_value, TB, 2, SValue),
		send(DB?strings, value, SName, SValue),
		send(Here, value, @bibtex_att_regex?register_end)
	    ;	send(TB, report, error, 'Illegal string at %d', Here),
		fail
	    )
	;   send(@bibtex_key_regex, match, TB, Here),
	    get(@bibtex_key_regex, register_value, TB, 1, name, Key),
	    send(DB, append, Key, new(E, bibtex_entry(Type, Key))),
	    send(Here, value, @bibtex_key_regex?register_end),
	    repeat,
	    (   send(E, parse_attribute, TB, Here)
	    ->	(   send(@bibtex_end_attr_regex, match, TB, Here)
		->  !,
		    send(Here, value, @bibtex_end_attr_regex?register_end)
		;   fail
		)
	    ;	!,
		send(TB, report, error, 'Cannot parse attribute at %d', Here),
		fail
	    )
	).

:- pce_end_class.


		 /*******************************
		 *	       ENTRY		*
		 *******************************/

:- pce_begin_class(bibtex_entry, sheet).

initialise(E, Type:name, Key:name) :->
	send(E, send_super, initialise),
	send(E, value, type, Type),
	send(E, value, key, Key).

	
parse_attribute(E, TB:text_buffer, Here:number) :->
	"Parse attribute-value pair"::
	send(@bibtex_att_regex, match, TB, Here),
	get(@bibtex_att_regex, register_value, TB, 1, name, AName),
	get(@bibtex_att_regex, register_value, TB, 2, AValue),
	send(E, value, AName, AValue),
	send(Here, value, @bibtex_att_regex?register_end).

:- pce_end_class.