Shortened page ranges
[latex-mlastyle.git] / mlastyle.bst
index e2b446ac786928c92f6416b22aec299feea2ed74..83f4b76b6161947f6c09657cb2d6e230279bb0ae 100644 (file)
@@ -1,13 +1,14 @@
+% $Id: mlastyle.bst,v 1.13 2003-11-22 19:15:11 tpope Exp $
 % BibTeX bibliography style `mlastyle'
 % Based on BibTeX standard bibliography style `plain'
        % version 0.99a for BibTeX versions 0.99a or later, LaTeX version 2.09.
-       % Copyright (C) 1985, all rights reserved.
+       % Copyright (C) 2003 Tim Pope, all rights reserved.
        % Copying of this file is authorized only if either
        % (1) you make absolutely no changes to your copy, including name, or
        % (2) if you do make changes, you name it something other than
        % btxbst.doc, plain.bst, unsrt.bst, alpha.bst, and abbrv.bst.
        % This restriction helps ensure that all standard styles are identical.
-       % The file btxbst.doc has the documentation for this style.
+       % The file mlastyle.dvi has the documentation for this style.
 
 ENTRY
   { address
@@ -34,6 +35,7 @@ ENTRY
     year
     % New fields
     url
+    urldate
     accessdate
     urlpath
     version
@@ -43,6 +45,8 @@ ENTRY
 
 INTEGERS { output.state before.all mid.sentence after.sentence after.block after.title author.different author.last author.flast citealp.used url.used }
 
+STRINGS { s t u empty.title }
+
 % Rearranged such that true values require capital letters
 FUNCTION {init.consts}
 { #-1 'after.title :=
@@ -58,23 +62,66 @@ FUNCTION {init.consts}
 
   #0 'citealp.used :=
   #0 'url.used :=
+  " \ \ \ \ \unskip\unskip\unskip\unskip\unskip " 'empty.title :=
+  "" 'empty.title :=
+}
+
+FUNCTION {not}
+{   { #0 }
+    { #1 }
+  if$
+}
+
+FUNCTION {and}
+{   'skip$
+    { pop$ #0 }
+  if$
 }
 
-STRINGS { s t u } % Added u
+FUNCTION {or}
+{   { pop$ #1 }
+    'skip$
+  if$
+}
+
+INTEGERS {chars i j}
+
+% text.length$ does not include braces
+% ...this function is probably unnecessary
+FUNCTION {num.chars}
+{
+  #0 'chars :=
+    { duplicate$ duplicate$ #1 chars substring$ = not }
+    { duplicate$ duplicate$ text.length$ swap$ #1 chars
+    substring$ text.length$ - chars + #1 + 'chars := }
+  while$
+    { duplicate$ duplicate$ #1 chars #1 - substring$ = }
+    { chars #1 - 'chars := }
+  while$
+  pop$ chars
+}
 
 % Puts the period inside any quotes
 FUNCTION {do.period}
-{ 
-  duplicate$ #-1 #3 substring$ "'''" =
-    { duplicate$ text.length$ #3 - text.prefix$ add.period$ "'\thinspace''" * }
-    { duplicate$ #-1 #3 substring$ "''}" =
-       { #2 global.max$ substring$ duplicate$
-         text.length$ #2 - text.prefix$ add.period$ "{" swap$ * "''}" * }
-       { duplicate$ #-1 #2 substring$ "''" =
-           { duplicate$ text.length$ #2 - text.prefix$ add.period$ "''" * }
-           { add.period$ }
-         if$
+{
+  duplicate$ #-1 #2 substring$ "''" =
+    { #2 'i :=
+       { duplicate$ #-1 i - #11 substring$ "'\thinspace" = }
+       { i #11 + 'i := }
+      while$
+      duplicate$ #-1 i - global.max$ substring$
+      add.period$ swap$ #-1 i substring$ *
+    }
+    {
+      duplicate$ #-1 #3 substring$ "''}" =
+       { #3 'i :=
+           { duplicate$ #-1 i - #11 substring$ "'\thinspace" = }
+           { i #11 + 'i := }
+         while$
+         duplicate$ #-1 i - global.max$ substring$
+         add.period$ swap$ #-1 i substring$ *
        }
+       { add.period$ }
       if$
     }
   if$
@@ -157,24 +204,6 @@ FUNCTION {new.sentence}
 %  if$
 %}
 
-FUNCTION {not}
-{   { #0 }
-    { #1 }
-  if$
-}
-
-FUNCTION {and}
-{   'skip$
-    { pop$ #0 }
-  if$
-}
-
-FUNCTION {or}
-{   { pop$ #1 }
-    'skip$
-  if$
-}
-
 FUNCTION {new.block.checka}
 { empty$
     'skip$
@@ -214,6 +243,11 @@ FUNCTION {field.or.null}
   if$
 }
 
+FUNCTION {sortify}
+{ purify$
+  "l" change.case$
+}
+
 FUNCTION {emphasize}
 { duplicate$ empty$
     { pop$ "" }
@@ -221,6 +255,67 @@ FUNCTION {emphasize}
   if$
 }
 
+FUNCTION {enquote}
+{ duplicate$ empty$
+    { pop$ "" }
+    {
+      #1 'i :=
+      #0 'j :=
+       { duplicate$ i #1 substring$ "" = not }
+       { duplicate$ duplicate$ i #1 substring$ quote$ =
+         swap$ i #1 - #1 substring$ "\" = not and %"
+           { duplicate$ #1 i #1 - substring$ swap$
+             i #1 + global.max$ substring$
+             j
+               { swap$ duplicate$ #-1 #1 substring$ "'" =
+                   { swap$ "\thinspace'" }
+                   { swap$ "'" }
+                 if$
+                  #0 'j :=
+               }
+               { duplicate$ #1 #1 substring$ "`" =
+                   { "`\thinspace" }
+                   { "`" }
+                 if$
+               #1 'j :=
+               }
+             if$
+             swap$ * *
+           }
+           'skip$
+         if$
+         i #1 + 'i :=
+       }
+      while$
+      j #1 =
+       { "odd number of quotation marks in " cite$ * warning$ }
+       'skip$
+      if$
+      duplicate$ #1 #1 substring$ "`" =
+       { "``\thinspace" swap$ * }
+       { "``" swap$ *}
+      if$
+      duplicate$ #-1 #1 substring$ "'" =
+       { "\thinspace''" * }
+       { "''" *}
+      if$
+    }
+  if$
+}
+
+FUNCTION {selective.enquote}
+{ field.or.null duplicate$ sortify 's :=
+  s #1 #8 substring$ duplicate$ "rev. of " = swap$ "rev.~of " = or
+  s #1 #9 substring$ "rev.\ of " = or
+  s "introduction" = or
+  s "preface" = or
+  s "forward" = or
+  s "afterward" = or
+    'skip$
+    'enquote
+  if$
+}
+
 INTEGERS { nameptr namesleft numnames }
 
 FUNCTION {format.names.custom}
@@ -265,8 +360,12 @@ FUNCTION {format.names.beginning}
     { namesleft #0 > }
     { nameptr #1 =
        { s nameptr "{vv~}{ll}{, ff}{, jj}" format.name$
-         duplicate$ #1 #1 substring$ "u" change.case$ swap$
-         duplicate$ #-1 swap$ text.length$ #1 - substring$ * 't := }
+         duplicate$ #1 #1 substring$ duplicate$ "{" =
+           'skip$
+           { "u" change.case$ }
+         if$
+         swap$ #2 global.max$ substring$ * 't :=
+       }
        { s nameptr "{ff~}{vv~}{ll}{, jj}" format.name$ 't := }
       if$
       nameptr #1 >
@@ -343,14 +442,7 @@ FUNCTION {format.publisher}
 
 % Changed to preserve case and use quotes
 FUNCTION {format.title}
-{ title empty$
-    { "" }
-    { title #1 text.prefix$ "`" =
-       { "``\thinspace" title * "''" * }
-       { "``" title * "''" *}
-      if$
-    }
-  if$
+{ title selective.enquote
 }
 
 FUNCTION {n.dashify}
@@ -395,8 +487,13 @@ FUNCTION {format.date}
   if$
 }
 
+%INTEGERS {xx}
 FUNCTION {format.btitle}
 { title emphasize
+  %title num.chars int.to.str$ top$
+  %#0 'xx :=
+  %{ xx title num.chars < }
+  %{ title xx #1 + duplicate$ 'xx := #1 substring$ top$ } while$
 }
 
 FUNCTION {tie.or.space.connect}
@@ -446,13 +543,6 @@ FUNCTION {format.bvolume.or.num.series}
   if$
 }
 
-FUNCTION {format.number.series}
-{ volume empty$
-    { "" }
-    { "" }
-  if$
-}
-
 % Changed edition to MLA abbreviation
 FUNCTION {format.edition}
 { edition empty$
@@ -461,13 +551,14 @@ FUNCTION {format.edition}
        { "Vers.~" version *}
       if$
     }
-    { edition "l" change.case$ 's := edition 't :=
+    { edition sortify 's := edition 't :=
       ""
       "10th" "tenth" "9th" "ninth" "8th" "eighth" "7th" "seventh" "6th" "sixth"
       "5th" "fifth" "4th" "fourth" "3rd" "third" "2nd" "second" "1st" "first"
+      "Rev." "revised" "Abr." "abridged"
       {duplicate$ empty$ { pop$ #0 }{ #1 } if$ }{ s = { 't := }{ pop$ } if$ }
       while$
-      t " ed." *
+      t "\ ed." *
       "edition and version" version either.or.check
     }
   if$
@@ -498,11 +589,53 @@ FUNCTION {multi.page.check}
 FUNCTION {format.pages}
 { pages empty$
     { "" }
-    { %pages multi.page.check
-%      { "pages" pages n.dashify tie.or.space.connect }
-%      { "page" pages tie.or.space.connect }
-%      if$
-    pages n.dashify
+    {
+% j is positive if pages contains a comma
+% (not fully implemented)
+      #0 'j :=
+      pages n.dashify 't :=
+      ""
+       { t empty$ not }
+       { t #1 #2 substring$ "--" =
+           { t #3 global.max$ substring$ 't :=
+             duplicate$ num.chars 'i :=
+             "--" *
+             i t num.chars =
+               {   { i #2 > }
+                   { duplicate$ #1 i #2 - substring$
+                     t #1 i #2 - substring$ =
+                       { t i #1 - global.max$ substring$ * "" 't :=  #2 'i := }
+                       { i #1 - 'i := }
+                     if$
+                   }
+                 while$
+               }
+               'skip$
+             if$
+           }
+           { t #1 #1 substring$ *
+             t #2 global.max$ substring$ 't :=
+           }
+         if$
+       }
+      while$
+    }
+  if$
+}
+
+FUNCTION {format.year}
+{ year empty$
+    { "" }
+    { year n.dashify
+      duplicate$ duplicate$ num.chars #10 =
+      swap$ #5 #2 substring$ "--" = and
+       { duplicate$ duplicate$ #1 #2 substring$ swap$ #7 #2 substring$ =
+           { duplicate$ #1 #6 substring$ swap$ #8 #2 substring$ * }
+           {}
+         if$
+       }
+       {}
+      if$
     }
   if$
 }
@@ -558,6 +691,8 @@ FUNCTION {format.vol.num.pages}
 % chapter might be useful if type is set to "pars."
 FUNCTION {format.chapter.pages}
 { chapter empty$
+  type field.or.null sortify duplicate$ "def." = swap$ "definition" = or
+  or
     'format.pages
     { type empty$
        { "Chapter" }
@@ -572,17 +707,6 @@ FUNCTION {format.chapter.pages}
   if$
 }
 
-FUNCTION {format.in.ed.booktitle}
-{ booktitle empty$
-    { "" }
-    { editor empty$
-       { "In " booktitle emphasize * }
-       { booktitle emphasize add.period$ format.editors.mid * }
-      if$
-    }
-  if$
-}
-
 FUNCTION {empty.misc.check}
 { author empty$ title empty$ howpublished empty$
   month empty$ year empty$ note empty$
@@ -616,11 +740,16 @@ FUNCTION {format.tr.number}
 FUNCTION {format.url}
 { url empty$
     { "" }
-    { accessdate empty$
-       { "There's a url but no accessdate in " cite$ * warning$ "" }
-       { accessdate " " * }
+    { urldate empty$
+       { accessdate empty$
+           { "there's a url but no urldate in " cite$ * warning$ "\today" }
+           { "accessdate in " cite$ * " depreciated; use urldate instead" *
+             warning$ accessdate }
+           if$
+       }
+       { urldate }
       if$
-      "$<$\url{" * url * "}$>$" *
+      " $<$\url{" * url * "}$>$" *
       urlpath empty$
        'skip$
        { do.period " Path: " * urlpath * }
@@ -629,89 +758,12 @@ FUNCTION {format.url}
   if$
 }
 
-FUNCTION {format.article.crossref}
-{ %key empty$
-    %{ journal empty$
-       %{ "need key or journal for " cite$ * " to crossref " * crossref *
-       %  warning$
-       %  ""
-       %}
-       %{ "In {\em " journal * "\/}" * }
-      %if$
-    %}
-    %{ "In " key * }
-  %if$
-  pages empty$ { "\citealp" } { "\citealp[" format.chapter.pages * "]" * } if$
-  "{" * crossref * "}" *
-}
-
-FUNCTION {format.crossref.editor}
-{ editor #1 "{vv~}{ll}" format.name$
-  editor num.names$ duplicate$
-  #2 >
-    { pop$ " et~al." * }
-    { #2 <
-       'skip$
-       { editor #2 "{ff }{vv }{ll}{, jj}" format.name$ "others" =
-           { " et~al." * }
-           { " and " * editor #2 "{vv~}{ll}" format.name$ * }
-         if$
-       }
-      if$
-    }
-  if$
-}
-
-FUNCTION {format.book.crossref}
-{% volume empty$
-%    { "empty volume in " cite$ * "'s crossref of " * crossref * warning$
-%      "In "
-%    }
-%    { "Vol." volume tie.or.space.connect add.period$
-%    }
-%  if$
-%  editor empty$
-%  editor field.or.null author field.or.null =
-%  or
-%    { key empty$
-%      { series empty$
-           %{ "need editor, key, or series for " cite$ * " to crossref " *
-           %  crossref * warning$
-           %  "" *
-           %}
-           %{ "{\em " * series * "\/}" * }
-         %if$
-%      }
-%      { key * }
-%      if$
-%    }
-%    { format.crossref.editor * }
-%  if$
+FUNCTION {format.crossref}
+{
   pages empty$ { "\citealp" } { "\citealp[" format.chapter.pages * "]" * } if$
   "{" * crossref * "}" *
 }
 
-FUNCTION {format.incoll.inproc.crossref}
-{% editor empty$
-%  editor field.or.null author field.or.null =
-%  or
-%    { key empty$
-%      { booktitle empty$
-%          { "need editor, key, or booktitle for " cite$ * " to crossref " *
-%            crossref * warning$
-%            ""
-%          }
-%          { "In {\em " booktitle * "\/}" * }
-%        if$
-%      }
-%      { "In " key * }
-%      if$
-%    }
-%    { "In " format.crossref.editor * }
-%  if$
-  pages empty$ { "\citealp" } { "\citealp[" format.chapter.pages * "]" * } if$
-  "{" * crossref * "}" *
-}
 
 FUNCTION {cite.title}
 { title empty$ journal empty$ not and
@@ -720,11 +772,12 @@ FUNCTION {cite.title}
        { "empty title and key in " cite$ * warning$ "" }
        { key empty$ {title}{key} if$
          type$ "book" =
+         type$ "booklet" =
          type$ "inbook" =
          type$ "manual" =
          type$ "phdthesis" =
          type$ "proceedings" =
-         or or or or
+         or or or or or
            { emphasize }
            { type$ "article" =
              %type$ "booklet" =
@@ -735,7 +788,7 @@ FUNCTION {cite.title}
              type$ "techreport" =
              type$ "unpublished" =
              or or or or or or
-               {"``" swap$ * "''" *  }
+               { selective.enquote }
                {}
              if$
            }
@@ -762,7 +815,8 @@ FUNCTION {cite.label}
     { author }
   if$
   duplicate$ empty$
-    { cite.title * "( \ \ \ \ \unskip\unskip\unskip\unskip\unskip \unskip)" * }
+    { cite.title *
+    "(" * empty.title * ")" * }
     { duplicate$
       author.shared author.different =
        { "{vv~}{ll}" format.names.custom 's := }
@@ -777,9 +831,9 @@ FUNCTION {cite.label}
        }
       if$
       s
-      "( \ \ \ \ \unskip\unskip\unskip\unskip\unskip " *
-      author.duplicate { cite.title * }{ "\unskip" * } if$
-      ")" * swap$ "{ff~}{vv~}{ll}{, jj}" format.names.custom *
+      "(" * empty.title *
+      author.duplicate { cite.title * }{} if$
+      ")" * swap$ "{ff~}{vv~}{ll}{, jj}" format.names.custom purify$ *
     }
   if$
       %}
@@ -809,12 +863,28 @@ FUNCTION {article}
   format.title "title" output.check
   new.block
   crossref missing$
-    { journal emphasize "journal" output.check after.title 'output.state :=
+    { type empty$
+       'skip$
+       { type sortify "review" =
+           { "Rev.\ of " booktitle emphasize * 
+           "booktitle" output.check new.block
+           }
+           { "Ignoring invalid type in " cite$ warning$ }
+         if$
+       }
+      if$
+      journal emphasize "journal" output.check after.title 'output.state :=
+      address empty$
+       'skip$
+       { "[" address * "]" * output
+         after.title 'output.state :=
+       }
+      if$
       %format.date "year" output.check
       %edition output
       format.vol.num.year.pages output
     }
-    { format.article.crossref output.nonnull
+    { format.crossref output.nonnull
       %format.pages output
     }
   if$
@@ -845,7 +915,7 @@ FUNCTION {book}
     }
     {% format.date "year" output
       new.block
-      format.book.crossref output.nonnull
+      format.crossref output.nonnull
     }
   if$
   new.block
@@ -859,7 +929,7 @@ FUNCTION {booklet}
 { output.bibitem
   format.authors output
   new.block
-  format.title "title" output.check
+  format.btitle "title" output.check
   howpublished address new.block.checkb
   howpublished output
   address output
@@ -890,9 +960,9 @@ FUNCTION {inbook}
       format.chapter.pages "chapter and pages" output.check
       %address output
     }
-    {% format.chapter.pages "chapter and pages" output.check
+    {
       new.block
-      format.book.crossref output.nonnull
+      format.crossref output.nonnull
     }
   if$
   new.block
@@ -906,15 +976,19 @@ FUNCTION {incollection}
   format.authors "author" output.check
   chapter empty$
     { new.block type output }
-    {}
+    'skip$
   if$
   new.block
   format.title "title" output.check
+  type field.or.null sortify duplicate$ "definition" = swap$ "def." = or
+    { new.block "Def.~" chapter field.or.null * "chapter" output.check } 
+    'skip$
+  if$
   new.block
   crossref missing$
     { 
       booktitle emphasize "booktitle" output.check
-      new.sentence
+      new.block
       format.editors.mid "editor" output.check
       new.block
       format.edition output
@@ -927,7 +1001,7 @@ FUNCTION {incollection}
       new.sentence
       format.chapter.pages output
     }
-    { format.incoll.inproc.crossref output.nonnull
+    { format.crossref output.nonnull
       %format.chapter.pages output
     }
   if$
@@ -945,7 +1019,7 @@ FUNCTION {inproceedings}
   format.title "title" output.check
   new.block
   crossref missing$
-    { %format.in.ed.booktitle "booktitle" output.check
+    {
       booktitle "booktitle" output.check
       new.sentence
       format.editors.mid output
@@ -974,8 +1048,7 @@ FUNCTION {inproceedings}
       new.sentence
       format.pages output
     }
-    { format.incoll.inproc.crossref output.nonnull
-      %format.pages output
+    { format.crossref output.nonnull
     }
   if$
   new.block
@@ -1031,7 +1104,7 @@ FUNCTION {mastersthesis}
   new.block
   format.title "title" output.check
   new.block
-  "Diss." format.thesis.type output.nonnull
+  "Diss." format.thesis.type do.period output.nonnull
   after.title 'output.state :=
   school "school" output.check
   address output
@@ -1066,7 +1139,7 @@ FUNCTION {phdthesis}
   new.block
   format.btitle "title" output.check
   new.block
-  "Diss." format.thesis.type output.nonnull
+  "Diss." format.thesis.type do.period output.nonnull
   after.title 'output.state :=
   school "school" output.check
   address output
@@ -1086,7 +1159,7 @@ FUNCTION {proceedings}
   if$
   new.block
   format.btitle "title" output.check
-  new.sentence
+  new.block
   format.bvolume.or.num.series output
   address empty$
     { editor empty$
@@ -1122,6 +1195,7 @@ FUNCTION {techreport}
   format.title "title" output.check
   new.block
   format.tr.number output.nonnull
+  new.block
   institution "institution" output.check
   address output
   format.date "year" output.check
@@ -1169,6 +1243,8 @@ MACRO {nov} {"Nov."}
 
 MACRO {dec} {"Dec."}
 
+% Currently left in to help with compatibility
+
 MACRO {acmcs} {"ACM Computing Surveys"}
 
 MACRO {acta} {"Acta Informatica"}
@@ -1212,11 +1288,6 @@ MACRO {tcs} {"Theoretical Computer Science"}
 
 READ
 
-FUNCTION {sortify}
-{ purify$
-  "l" change.case$
-}
-
 INTEGERS { len }
 
 FUNCTION {chop.word}
@@ -1254,7 +1325,14 @@ FUNCTION {sort.format.title}
 { 't :=
   "A " #2
     "An " #3
-      "The " #4 t chop.word
+      "The " #4
+       "Rev. of " #8
+         "Rev.~of " #8
+           "Rev.\ of " #9
+           t chop.word
+         chop.word
+       chop.word
+      chop.word
     chop.word
   chop.word
   sortify
@@ -1358,7 +1436,6 @@ ITERATE {presort}
 SORT
 
 STRINGS {a b}
-INTEGERS {i j}
 
 FUNCTION {init.vars}
 { #0 int.to.chr$ 'a :=