1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 % PUBLIST.BST version 1.01 03-08-05
6 % v1.01: "others" -> "\bgroup\scshape others\egroup"
7 % (thanks to Mathias Schulze for pointing out that bug)
9 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11 % This style extracts your list of publications from your .bib file. It is
12 % based on the plain.bst style file written by Oren Patashnik.
14 % In order to do so, you have to define your name and several possible
15 % options in a @config entry, which should also be included.
18 % Remarks, comments, suggestions are welcome : markey@lsv.ens-cachan.fr
20 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
26 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
52 url %% extra field, but requires loading url.sty.
54 myname %% Special @config field containing your name.
55 jointwork %% What will be written before the co-authors' names.
56 nameformat %% 0 = default = {ff }{vv~}{ll}{, jj}
57 %% 1 = {f. }{vv~}{ll}{, jj}
58 %% 2 = {vv~}{ll}{, jj}{, ff}
59 %% 3 = {vv~}{ll}{, jj}{, f.}
60 testlevel %% 0 = default = tight, 1 = medium, 2 = loose
61 no-url %% don't print URLs if not empty$
62 reverse-sort %% 0 = default = increasing date, otherwise decreasing date
67 STRINGS{your.name joint.work}
68 INTEGERS{name.format test.level url.used nourl reverse a b select total}
91 reverse-sort duplicate$ empty$
93 {chr.to.int$ #48 - 'reverse :=}
96 jointwork duplicate$ empty$
97 {"Joint work with " 'joint.work := pop$}
98 {" " * 'joint.work :=}
101 nameformat duplicate$ empty$
102 {pop$ #0 'name.format :=}
103 {chr.to.int$ #48 - 'name.format :=}
106 testlevel duplicate$ empty$
107 {pop$ #0 'test.level :=}
108 {chr.to.int$ #48 - 'test.level :=}
111 test.level duplicate$ #0 < swap$ #2 > or
116 myname duplicate$ empty$
117 {"I don't know who you are. Please tell me your name in a @config entry" warning$ pop$}
120 test.level #0 = {"{vv~}{ll}{,~jj}{,~ff}"}{} if$
121 test.level #1 = {"{vv~}{ll}{,~f.}"}{} if$
122 test.level #2 = {"{vv~}{ll}"}{} if$
124 duplicate$ " -- Extracting entries for " swap$ * " -- " * top$
125 "l" change.case$ 'your.name :=}
128 no-url duplicate$ empty$
146 INTEGERS { output.state before.all mid.sentence after.sentence after.block }
148 FUNCTION {init.state.consts}
151 #2 'after.sentence :=
157 FUNCTION {output.nonnull}
159 output.state mid.sentence =
161 { output.state after.block =
166 { output.state before.all =
168 { add.period$ " " * write$ }
172 mid.sentence 'output.state :=
185 FUNCTION {output.check}
188 { pop$ "empty " t * " in " * cite$ * warning$ }
193 FUNCTION {output.bibitem}
200 before.all 'output.state :=
210 { output.state before.all =
212 { after.block 'output.state := }
216 FUNCTION {new.sentence}
217 { output.state after.block =
219 { output.state before.all =
221 { after.sentence 'output.state := }
230 'a := %% on memorise la premiere valeur
231 'b := %% on memorise la deuxieme valeur
233 b #0 < %% L'idee ici est de mettre le signe
234 {#0 #1 - #0 b - 'b :=} %% de b sur la pile, et de prendre
235 {#1} %% la valeur absolue de b.
239 {b #0 >} %% tant que b est strictement positif,
240 { %% on ajoute a au premier element de
241 a + %% la pile, et on decremente b. A la
242 b #1 - 'b := %% fin, on a bien le produit de a
246 swap$ #1 = %% Enfin, on corrige le signe, si
247 'skip$ %% besoin, en testant le signe de b
248 {#0 swap$ -} %% que l'on avait mis sur la pile au
255 FUNCTION {chr.to.value} %% D'abord, la valeur d'un caractere.
257 chr.to.int$ #48 - %% en ASCII, "0" -> 48
258 duplicate$ duplicate$ %% "1" -> 49
259 #0 < swap$ #9 > or %% ...
262 " n'est pas un nombre..." *
263 warning$ %% Si c'est pas un chiffre,
264 pop$ #0 %% on retourne 0...
270 FUNCTION {str.to.int.aux} %% La fonction auxiliaire.
272 {duplicate$ empty$ not} %% Tant que la chaine n'est pas vide,
273 { %% on prend son premier chiffre
274 swap$ #10 mult 'a := %% et on le met comme il faut...
275 duplicate$ #1 #1 substring$
278 #2 global.max$ substring$
284 FUNCTION {str.to.int}
285 { %% On regarde si le nombre est negatif
286 duplicate$ #1 #1 substring$ "-" =
287 {#1 swap$ #2 global.max$ substring$}
290 %% On initialise, puis on appelle
291 #0 swap$ str.to.int.aux %% la fonction auxiliaire.
293 {#0 swap$ -} %% On met le signe comme il faut.
298 FUNCTION {new.block.checka}
305 FUNCTION {new.block.checkb}
314 FUNCTION {new.sentence.checka}
321 FUNCTION {new.sentence.checkb}
330 FUNCTION {field.or.null}
340 { "{\em " swap$ * "}" * }
344 INTEGERS { nameptr namesleft numnames removed localptr }
350 s localptr "{vv }{ll}{, jj}{, ff}" format.name$ purify$ "l" change.case$ yourname =
352 s localptr "{vv }{ll}{, f.}" format.name$ purify$ "l" change.case$ yourname = and
354 s localptr "{vv }{ll}" format.name$ purify$ "l" change.case$ yourname = and
363 author duplicate$ empty$
369 s num.names$ 'numnames :=
370 numnames 'namesleft :=
373 {#0 'notauthor := #0 'namesleft := select #1 + 'select :=}
376 nameptr #1 + 'nameptr :=
377 namesleft #1 - 'namesleft :=
382 FUNCTION {format.coauthor.names}
386 s num.names$ 'numnames :=
387 numnames 'namesleft :=
398 {#1 'removed :=} %% nothing to write
400 name.format duplicate$ #2 <
401 {#0 = {"{ff }{vv~}{ll}{,~jj}"} {"{f.~}{vv~}{ll}{, jj}"} if$ }
402 {#2 = {"{vv~}{ll}{,~jj}{, ff}"} {"{vv~}{ll}{,~jj}{,~f.}"} if$}
405 nameptr #1 > removed #0 = and nameptr #2 > or
406 { namesleft #2 > namesleft #2 = removed #1 = and or
419 nameptr #1 + 'nameptr :=
420 namesleft #1 - 'namesleft :=
427 %% Last, we test if you are an author...
428 %% This should never occur since we tested for that before...
429 removed #0 = {"I found a bug. Please report it to markey@lsv.ens-cachan.fr" warning$
430 "with the complete entry for " cite$ * warning$} {} if$
433 FUNCTION {format.names}
436 s num.names$ 'numnames :=
437 numnames 'namesleft :=
438 s nameptr "{vv~}\bgroup\scshape {ll}\egroup{, ff}{, jj}" format.name$ 't :=
446 t "\bgroup\scshape others\egroup" =
455 nameptr #1 + 'nameptr :=
456 namesleft #1 - 'namesleft :=
458 { s nameptr "{ff~}{vv~}\bgroup\scshape {ll}\egroup{, jj}" format.name$ 't :=
466 t "\bgroup\scshape others\egroup" =
475 nameptr #1 + 'nameptr :=
476 namesleft #1 - 'namesleft :=
482 FUNCTION {format.coauthors}
485 { author format.coauthor.names }
489 FUNCTION {format.authors}
492 { author format.names }
497 FUNCTION {format.editors}
500 { editor format.names
501 editor num.names$ #1 >
509 FUNCTION {format.title}
512 { title "t" change.case$ }
520 { t #1 #1 substring$ "-" =
521 { t #1 #2 substring$ "--" = not
523 t #2 global.max$ substring$ 't :=
525 { { t #1 #1 substring$ "-" = }
527 t #2 global.max$ substring$ 't :=
533 { t #1 #1 substring$ *
534 t #2 global.max$ substring$ 't :=
541 FUNCTION {format.date}
545 { "there's a month but no year in " cite$ * warning$
552 { month " " * year * }
558 FUNCTION {format.btitle}
562 FUNCTION {tie.or.space.connect}
563 { duplicate$ text.length$ #3 <
570 FUNCTION {either.or.check}
573 { "can't use both " swap$ * " fields in " * cite$ * warning$ }
577 FUNCTION {format.bvolume}
580 { "volume" volume tie.or.space.connect
583 { " of " * series emphasize * }
585 "volume and number" number either.or.check
590 FUNCTION {format.number.series}
593 { series field.or.null }
594 { output.state mid.sentence =
598 number tie.or.space.connect
600 { "there's a number but no series in " cite$ * warning$ }
601 { " in " * series * }
610 FUNCTION {format.edition}
613 { output.state mid.sentence =
614 { edition "l" change.case$ " edition" * }
615 { edition "t" change.case$ " edition" * }
621 INTEGERS { multiresult }
623 FUNCTION {multi.page.check}
632 swap$ duplicate$ "," =
635 { #1 'multiresult := }
636 { t #2 global.max$ substring$ 't := }
643 FUNCTION {format.pages}
646 { pages multi.page.check
647 { "pages" pages n.dashify tie.or.space.connect }
648 { "page" pages tie.or.space.connect }
654 FUNCTION {format.vol.num.pages}
655 { volume field.or.null
658 { "(" number * ")" * *
660 { "there's a number but no volume in " cite$ * warning$ }
668 { pop$ format.pages }
669 { ":" * pages n.dashify * }
675 FUNCTION {format.chapter.pages}
680 { type "l" change.case$ }
682 chapter tie.or.space.connect
685 { ", " * format.pages * }
691 FUNCTION {format.in.ed.booktitle}
695 { "In " booktitle emphasize * }
696 { "In " format.editors * ", " * booktitle emphasize * }
702 FUNCTION {empty.misc.check}
703 { author empty$ title empty$ howpublished empty$
704 month empty$ year empty$ note empty$
707 { "all relevant fields are empty in " cite$ * warning$ }
712 FUNCTION {format.thesis.type}
716 type "t" change.case$
721 FUNCTION {format.tr.number}
723 { "Technical Report" }
728 { number tie.or.space.connect }
732 FUNCTION {format.article.crossref}
735 { "need key or journal for " cite$ * " to crossref " * crossref *
739 { "In {\em " journal * "\/}" * }
744 " \cite{" * crossref * "}" *
747 FUNCTION {format.crossref.editor}
748 { editor #1 "{vv~}{ll}" format.name$
749 editor num.names$ duplicate$
754 { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" =
756 { " and " * editor #2 "{vv~}{ll}" format.name$ * }
764 FUNCTION {format.book.crossref}
766 { "empty volume in " cite$ * "'s crossref of " * crossref * warning$
769 { "Volume" volume tie.or.space.connect
774 editor field.or.null author field.or.null =
778 { "need editor, key, or series for " cite$ * " to crossref " *
782 { "{\em " * series * "\/}" * }
788 { format.crossref.editor * }
790 " \cite{" * crossref * "}" *
793 FUNCTION {format.incoll.inproc.crossref}
795 editor field.or.null author field.or.null =
799 { "need editor, key, or booktitle for " cite$ * " to crossref " *
803 { "In {\em " booktitle * "\/}" * }
809 { "In " format.crossref.editor * }
811 " \cite{" * crossref * "}" *
816 url missing$ nourl #1 = or
820 {"You use the URL field. Don't forget to include the `url' package." Warning$}
824 url duplicate$ #1 #4 substring$ duplicate$ "http" = swap$ "ftp:" = or
828 "\url{" swap$ "}" * *
836 % format.authors "author" output.check
838 format.title "title" output.check
841 { journal emphasize "journal" output.check
842 format.vol.num.pages output
843 format.date "year" output.check
845 { format.article.crossref output.nonnull
854 format.coauthors output
861 % { format.editors "author and editor" output.check }
862 % { format.authors output.nonnull
864 % { "author and editor" editor either.or.check }
870 format.btitle "title" output.check
872 { format.bvolume output
874 format.number.series output
876 publisher "publisher" output.check
880 format.book.crossref output.nonnull
883 format.edition output
884 format.date "year" output.check
890 format.coauthors output
896 % format.authors output
898 format.title "title" output.check
899 howpublished address new.block.checkb
908 format.coauthors output
915 % { format.editors "author and editor" output.check }
916 % { format.authors output.nonnull
918 % { "author and editor" editor either.or.check }
924 format.btitle "title" output.check
926 { format.bvolume output
927 format.chapter.pages "chapter and pages" output.check
929 format.number.series output
931 publisher "publisher" output.check
934 { format.chapter.pages "chapter and pages" output.check
936 format.book.crossref output.nonnull
939 format.edition output
940 format.date "year" output.check
946 format.coauthors output
950 FUNCTION {incollection}
952 % format.authors "author" output.check
954 format.title "title" output.check
957 { format.in.ed.booktitle "booktitle" output.check
958 format.bvolume output
959 format.number.series output
960 format.chapter.pages output
962 publisher "publisher" output.check
964 format.edition output
965 format.date "year" output.check
967 { format.incoll.inproc.crossref output.nonnull
968 format.chapter.pages output
976 format.coauthors output
980 FUNCTION {inproceedings}
982 % format.authors "author" output.check
984 format.title "title" output.check
987 { format.in.ed.booktitle "booktitle" output.check
988 format.bvolume output
989 format.number.series output
992 { organization publisher new.sentence.checkb
995 format.date "year" output.check
997 { address output.nonnull
998 format.date "year" output.check
1005 { format.incoll.inproc.crossref output.nonnull
1014 format.coauthors output
1018 FUNCTION {conference} { inproceedings }
1023 { organization empty$
1025 { organization output.nonnull
1030 % { format.authors output.nonnull }
1034 format.btitle "title" output.check
1036 { organization empty$
1037 { address new.block.checka
1043 { organization address new.block.checkb
1048 format.edition output
1055 format.coauthors output
1059 FUNCTION {mastersthesis}
1061 % format.authors "author" output.check
1063 format.title "title" output.check
1065 "Master's thesis" format.thesis.type output.nonnull
1066 school "school" output.check
1068 format.date "year" output.check
1074 format.coauthors output
1080 % format.authors output
1081 title howpublished new.block.checkb
1083 howpublished new.block.checka
1091 format.coauthors output
1096 FUNCTION {phdthesis}
1098 % format.authors "author" output.check
1100 format.btitle "title" output.check
1102 "PhD thesis" format.thesis.type output.nonnull
1103 school "school" output.check
1105 format.date "year" output.check
1111 format.coauthors output
1115 FUNCTION {proceedings}
1118 { organization output }
1119 % { format.editors output.nonnull }
1123 format.btitle "title" output.check
1124 format.bvolume output
1125 format.number.series output
1128 { publisher new.sentence.checka }
1129 { organization publisher new.sentence.checkb
1134 format.date "year" output.check
1136 { address output.nonnull
1137 format.date "year" output.check
1141 { organization output }
1151 format.coauthors output
1155 FUNCTION {techreport}
1157 % format.authors "author" output.check
1159 format.title "title" output.check
1161 format.tr.number output.nonnull
1162 institution "institution" output.check
1164 format.date "year" output.check
1170 format.coauthors output
1174 FUNCTION {unpublished}
1176 % format.authors "author" output.check
1178 format.title "title" output.check
1180 note "note" output.check
1185 format.coauthors output
1189 FUNCTION {default.type} { misc }
1191 MACRO {jan} {"January"}
1193 MACRO {feb} {"February"}
1195 MACRO {mar} {"March"}
1197 MACRO {apr} {"April"}
1201 MACRO {jun} {"June"}
1203 MACRO {jul} {"July"}
1205 MACRO {aug} {"August"}
1207 MACRO {sep} {"September"}
1209 MACRO {oct} {"October"}
1211 MACRO {nov} {"November"}
1213 MACRO {dec} {"December"}
1215 MACRO {acmcs} {"ACM Computing Surveys"}
1217 MACRO {acta} {"Acta Informatica"}
1219 MACRO {cacm} {"Communications of the ACM"}
1221 MACRO {ibmjrd} {"IBM Journal of Research and Development"}
1223 MACRO {ibmsj} {"IBM Systems Journal"}
1225 MACRO {ieeese} {"IEEE Transactions on Software Engineering"}
1227 MACRO {ieeetc} {"IEEE Transactions on Computers"}
1230 {"IEEE Transactions on Computer-Aided Design of Integrated Circuits"}
1232 MACRO {ipl} {"Information Processing Letters"}
1234 MACRO {jacm} {"Journal of the ACM"}
1236 MACRO {jcss} {"Journal of Computer and System Sciences"}
1238 MACRO {scp} {"Science of Computer Programming"}
1240 MACRO {sicomp} {"SIAM Journal on Computing"}
1242 MACRO {tocs} {"ACM Transactions on Computer Systems"}
1244 MACRO {tods} {"ACM Transactions on Database Systems"}
1246 MACRO {tog} {"ACM Transactions on Graphics"}
1248 MACRO {toms} {"ACM Transactions on Mathematical Software"}
1250 MACRO {toois} {"ACM Transactions on Office Information Systems"}
1252 MACRO {toplas} {"ACM Transactions on Programming Languages and Systems"}
1254 MACRO {tcs} {"Theoretical Computer Science"}
1258 FUNCTION {call.config}
1259 {type$ "config" = 'call.type$ 'skip$ if$}
1261 ITERATE{call.config}
1272 FUNCTION {chop.word}
1275 s #1 len substring$ =
1276 { s len #1 + global.max$ substring$ }
1281 FUNCTION {sort.format.names}
1285 s num.names$ 'numnames :=
1286 numnames 'namesleft :=
1292 s nameptr "{vv{ } }{ll{ }}{ ff{ }}{ jj{ }}" format.name$ 't :=
1293 nameptr numnames = t "others" = and
1297 nameptr #1 + 'nameptr :=
1298 namesleft #1 - 'namesleft :=
1303 FUNCTION {sort.format.title}
1307 "The " #4 t chop.word
1311 #1 global.max$ substring$
1314 FUNCTION {author.sort}
1317 { "to sort, need author or key in " cite$ * warning$
1323 { author sort.format.names }
1327 FUNCTION {author.editor.sort}
1331 { "to sort, need author, editor, or key in " cite$ * warning$
1337 { editor sort.format.names }
1340 { author sort.format.names }
1344 FUNCTION {author.organization.sort}
1346 { organization empty$
1348 { "to sort, need author, organization, or key in " cite$ * warning$
1354 { "The " #4 organization chop.word sortify }
1357 { author sort.format.names }
1361 FUNCTION {editor.organization.sort}
1363 { organization empty$
1365 { "to sort, need editor, organization, or key in " cite$ * warning$
1371 { "The " #4 organization chop.word sortify }
1374 { editor sort.format.names }
1381 #1 #1 substring$ chr.to.int$ duplicate$ #58 < #47 > or
1383 #2 #1 substring$ chr.to.int$ duplicate$ #58 < #47 > or
1385 #3 #1 substring$ chr.to.int$ duplicate$ #58 < #47 > or
1387 #4 #1 substring$ chr.to.int$ duplicate$ #58 < #47 > or
1393 type$ "config" = notauthor #1 = or
1399 % 'author.editor.sort
1400 % { type$ "proceedings" =
1401 % 'editor.organization.sort
1402 % { type$ "manual" =
1403 % 'author.organization.sort
1412 year duplicate$ empty$
1413 {"Entry " cite$ * " has no year, and will be placed at the end." * warning$ pop$ "9999"}
1414 {duplicate$ text.length$ duplicate$ #4 = not
1415 {"Entry " cite$ * " has a weird year-field, and will be put at the end." * warning$ pop$ pop$ "9999"}
1416 {#3 - #4 substring$ duplicate$ nan
1418 {"Entry " cite$ * " has an ambiguous year-field, and will be put at the end." * warning$ pop$ "9999"}
1423 {str.to.int #9999 swap$ -}
1426 duplicate$ duplicate$ #0 = swap$ #9999 = or
1436 #1 entry.max$ substring$
1446 STRINGS { longest.label }
1448 INTEGERS { number.label longest.label.width }
1450 FUNCTION {initialize.longest.label}
1451 { "" 'longest.label :=
1453 #0 'longest.label.width :=
1456 FUNCTION {longest.label.pass}
1457 { number.label int.to.str$ 'label :=
1458 number.label #1 + 'number.label :=
1459 label width$ longest.label.width >
1460 { label 'longest.label :=
1461 label width$ 'longest.label.width :=
1467 EXECUTE {initialize.longest.label}
1469 ITERATE {longest.label.pass}
1471 FUNCTION {begin.bib}
1474 { preamble$ write$ newline$ }
1476 "\begin{thebibliography}{" longest.label * "}" * write$ newline$
1481 EXECUTE {init.state.consts}
1483 FUNCTION{call.other.types}
1484 {type$ "l" change.case$ "config" =
1495 ITERATE{call.other.types}
1499 "\end{thebibliography}" write$ newline$
1500 " -- I selected " select int.to.str$ * " entries out of " * total int.to.str$ * ". -- " * top$