% =====================================================================
%% This is file `biblatex-cse.bbx'
%%
%% A Council of Science Editors (CSE) Name–Year bibliography style
% =====================================================================
%%
%% Copyright (C) 2024–26 by João Lourenço <joao.lourenco@fct.unl.pt>
%%
%% This file may be distributed and/or modified under the conditions of
%% the LaTeX Project Public License, either version 1.3c of this license
%% or (at your option) any later version. The latest version of this
%% license is in:
%%
%%    http://www.latex-project.org/lppl.txt
%%
%% and version 1.3c or later is part of all distributions of LaTeX
%% version 2006/05/20 or later.
%%
\def\bltxcsefileversion{2.0.1}
\def\bltxcsefiledate   {2026/05/16}
\edef\filename  {biblatex-cse}

\ProvidesFile{\filename.bbx}[%
  \bltxcsefiledate\  v\bltxcsefileversion (João M. Lourenço) CSE Name–Year bibliography style]

\RequireBibliographyStyle{standard} % start from a neutral base

% =========
% GLOBALS
% =========
% CSE 9th edition rules:
% - In the bibliography: list up to 5 authors; if >5, show only the first + "et al."
% - In citations: show both names for 2 authors; ≥3 → first author + "et al."
\ExecuteBibliographyOptions{
  giveninits      = true,  % use initials for given names
  maxbibnames     = 5,
  minbibnames     = 1,
  maxcitenames    = 2,
  mincitenames    = 1,
  doi             = true,
  url             = true,
  date            = year,    % print only the year unless date unknown is needed
  uniquelist      = minyear, % extend author list to disambiguate et-al citations
  language        = auto
}

% ===========================
% STRINGS / “et al” spelling
% ===========================
% CSE uses "et al." with a trailing abbreviation period.
\DefineBibliographyStrings{english}{
  andothers = {et\addabbrvspace al\adddot}
}

% ===========================
% FULL-DATE HELPER
% ===========================
% CSE requires "YYYY Mon DD" dates for newspapers, webpages,
% conference presentations, and patents.
\newcommand*{\csemonabrv}[1]{%
  \ifcase#1\relax
  \or Jan\or Feb\or Mar\or Apr\or May\or Jun%
  \or Jul\or Aug\or Sep\or Oct\or Nov\or Dec%
  \fi}

\newbibmacro*{cse:fulldate}{%
  \printfield{year}%
  \iffieldundef{month}{}{\addspace\csemonabrv{\thefield{month}}}%
  \iffieldundef{day}{}{\addspace\thefield{day}}%
}

% "updated YYYY Mon DD" block (uses eventdate fields)
\newbibmacro*{cse:eventdate}{%
  \iffieldundef{eventyear}{}{%
    \mkbibbrackets{%
      updated\addspace\thefield{eventyear}%
      \iffieldundef{eventmonth}{}{\addspace\csemonabrv{\thefield{eventmonth}}}%
      \iffieldundef{eventday}{}{\addspace\thefield{eventday}}%
    }%
  }%
}

% "accessed YYYY Mon DD" block (uses urldate fields)
\newbibmacro*{cse:urldate}{%
  \iffieldundef{urlyear}{}{%
    \mkbibbrackets{%
      accessed\addspace\thefield{urlyear}%
      \iffieldundef{urlmonth}{}{\addspace\csemonabrv{\thefield{urlmonth}}}%
      \iffieldundef{urlday}{}{\addspace\thefield{urlday}}%
    }%
  }%
}

% ===========================
% NAME FORMAT (bibliography)
% ===========================
% Surname Initials  (no comma, no periods after initials)
\DeclareNameFormat{author}{%
  \usebibmacro{name:family-given}
    {\namepartfamily}
    {\namepartgiven}   % 'giveninits=true' turns this into initials
    {\namepartprefix}
    {\namepartsuffix}%
  \usebibmacro{name:andothers}%
}

\DeclareNameFormat{editor}{%
  \usebibmacro{name:family-given}
    {\namepartfamily}
    {\namepartgiven}
    {\namepartprefix}
    {\namepartsuffix}%
  \usebibmacro{name:andothers}%
}
% No periods between initials; no separator between initials.
\renewcommand*{\bibinitdelim}{}%
\renewcommand*{\bibinitperiod}{}%

% ===========================
% LIST DELIMITERS
% ===========================
% Bibliography wants commas between all authors, no "and" before the last.
\DeclareDelimFormat{multinamedelim}{\addcomma\space}
\DeclareDelimFormat{finalnamedelim}{\addcomma\space}

% After author block, always a period + space.
\renewcommand*{\labelnamepunct}{\addperiod\space}

% ===========================
% FIELD FORMATS
% ===========================
% Titles should be in sentence case and plain (no quotes or italics by default).
% (Ensure your .bib titles are correctly cased for species etc.)
\DeclareFieldFormat{title}{\MakeSentenceCase{#1}}

% If any citation command prints a title (e.g., \citetitle), keep it unquoted:
\DeclareFieldFormat{citetitle}{#1}
\DeclareFieldFormat[article]{citetitle}{#1}

% Journals: CSE expects abbreviated journal titles supplied in data.
% We print whatever is in 'journaltitle' as plain text, then a period.
\DeclareFieldFormat*{journaltitle}{#1\addperiod}

% DOI should be rendered as a DOI-based URL and must not be followed by a period.
\DeclareFieldFormat*{doi}{\href{https://doi.org/#1}{https://doi.org/#1}}

% URL: print raw (no trailing dot)
\DeclareFieldFormat*{url}{#1}

% Pages: print bare numbers — no "p." / "pp." prefix (CSE uses Volume(issue):pages)
\DeclareFieldFormat{pages}{#1}
\DeclareFieldFormat[article]{pages}{#1}
\DeclareFieldFormat[incollection]{pages}{#1}
\DeclareFieldFormat[inproceedings]{pages}{#1}

% Edition ordinal: "2nd ed.", "3rd ed.", etc.
% Returns the full ordinal string for N=0..29; falls back to "Nth" for N>29.
\newcommand*{\cseordinal}[1]{%
  \ifcase#1\relax
    0th\or 1st\or 2nd\or 3rd\or 4th\or 5th\or 6th\or 7th\or 8th\or 9th\or
    10th\or 11th\or 12th\or 13th\or 14th\or 15th\or 16th\or 17th\or 18th\or 19th\or
    20th\or 21st\or 22nd\or 23rd\or 24th\or 25th\or 26th\or 27th\or 28th\or 29th%
  \else #1th\fi}

\DeclareFieldFormat{edition}{%
  \ifinteger{#1}
    {\cseordinal{#1}\addspace ed\adddot}
    {#1\addspace ed\adddot}}
\DeclareFieldFormat{pagetotal}{#1\space p\adddot}

% --- NEVER quote titles (CSE wants plain, sentence case) ---
% Articles
\DeclareFieldFormat[article]{title}{\MakeSentenceCase{#1}}
\DeclareFieldFormat[article]{subtitle}{\MakeSentenceCase{#1}}

% Chapters / conference papers (incollection/inproceedings)
\DeclareFieldFormat[incollection]{title}{\MakeSentenceCase{#1}}
\DeclareFieldFormat[incollection]{subtitle}{\MakeSentenceCase{#1}}
\DeclareFieldFormat[inproceedings]{title}{\MakeSentenceCase{#1}}
\DeclareFieldFormat[inproceedings]{subtitle}{\MakeSentenceCase{#1}}

% Books / theses / online, etc. (kept plain too)
\DeclareFieldFormat[book]{title}{\MakeSentenceCase{#1}}
\DeclareFieldFormat[thesis]{title}{\MakeSentenceCase{#1}}
\DeclareFieldFormat[online]{title}{\MakeSentenceCase{#1}}
\DeclareFieldFormat[misc]{title}{\MakeSentenceCase{#1}}


% ===========================
% MACROS (helpers)
% ===========================
% Prints a terminal URL/DOI with no trailing punctuation and proper spacing.
% If both DOI and URL are present, only prints DOI
\newbibmacro*{cse:trailurl}{%
  \iffieldundef{doi}
    {\iffieldundef{url}{}{\setunit{\addspace}\printfield{url}}}
    {\setunit{\addspace}\printfield{doi}}%
}

% Volume(issue):pages or Volume:pages
\newbibmacro*{cse:vol-issue-pages}{%
  \iffieldundef{volume}{}{\printfield{volume}}%
  \iffieldundef{number}{}{\mkbibparens{\printfield{number}}}%
  \iffieldundef{pages}{}{\addcolon\space\printfield{pages}}%
}

% Volume with supplement strings, article numbers, etc.
% We adopt this logic:
% - If pages empty but 'eid' present -> print eid as the location after colon.
% - If volume is a range (e.g., 157–158), that's already in 'volume' field.
\newbibmacro*{cse:location}{%
  \iffieldundef{pages}
    {\iffieldundef{eid}{}{\addcolon\space\printfield{eid}}}
    {\addcolon\space\printfield{pages}}%
}

% ===========================
% DRIVERS
% ===========================
% ---- ARTICLE ----
% Authors. Year. Article title. Journal title. Volume(issue):pages. DOI/URL
\DeclareBibliographyDriver{article}{%
  \usebibmacro{bibindex}%
  \usebibmacro{begentry}%
  \printnames{author}\addperiod\space
  \printfield{year}\addperiod\space
  \printfield{title}\addperiod\space
  \printfield{journaltitle}\space
  % ---- Volume(issue):pages ----
  \printfield{volume}%
  \iffieldundef{number}
    {%
      \iffieldundef{issue}
        {}{\mkbibparens{\printfield{issue}}}% use 'issue' if 'number' missing
    }
    {\mkbibparens{\printfield{number}}}%
  \iffieldundef{pages}
    {\iffieldundef{eid}{}{\addcolon\space\printfield{eid}}}
    {\addcolon\space\printfield{pages}}%
  % ---- Trailing DOI/URL ----
  \setunit{\addperiod\space}%
  \usebibmacro{cse:trailurl}%
  \usebibmacro{finentry}%
}

% ---- BOOK ----
% Authors/Editors. Year. Title. Edition. Publisher. URL (optional)
% CSE 9th ed.: publisher location is omitted.
\DeclareBibliographyDriver{book}{%
  \usebibmacro{bibindex}\usebibmacro{begentry}%
  \ifnameundef{author}
    {\printnames{editor}\addcomma\space
     \ifboolexpr{
       test {\ifnumgreater{\value{editor}}{1}} or
       test {\ifandothers{editor}}
     }{editors}{editor}\addperiod\space}%
    {\printnames{author}\addperiod\space}%
  \printfield{year}\addperiod\space
  \printfield{title}\addperiod\space
  \iffieldundef{edition}{}{\printfield{edition}\addperiod\space}%
  \printlist{publisher}\addperiod
  \setunit{\addspace}\usebibmacro{cse:trailurl}%
  \usebibmacro{finentry}%
}

% ---- INCOLLECTION (chapter in edited book) ----
% Authors. Year. Chapter title. In: Editor(s), editor(s). Book title. Edition. Publisher. p N–N. URL
% CSE 9th ed.: publisher location is omitted.
\DeclareBibliographyDriver{incollection}{%
  \usebibmacro{bibindex}\usebibmacro{begentry}%
  \printnames{author}\addperiod\space
  \printfield{year}\addperiod\space
  \printfield{title}\addperiod\space
  In:\space
  \ifnameundef{editor}
    {}
    {\printnames{editor}\addcomma\space
     \ifboolexpr{
       test {\ifnumgreater{\value{editor}}{1}} or
       test {\ifandothers{editor}}
     }{editors}{editor}\addperiod\space}%
  \printfield{booktitle}\addperiod\space
  \iffieldundef{edition}{}{\printfield{edition}\addperiod\space}%
  \printlist{publisher}%
  \iffieldundef{pages}{}{.\space p\addspace\printfield{pages}}%
  \addperiod\space
  \usebibmacro{cse:trailurl}%
  \usebibmacro{finentry}%
}

% ---- THESIS / DISSERTATION ----
% Author. Year. Title [dissertation|master's thesis]. Institution. URL
% CSE 9th ed.: publisher location is omitted.
\DeclareBibliographyDriver{thesis}{%
  \usebibmacro{bibindex}\usebibmacro{begentry}%
  \printnames{author}\addperiod\space
  \printfield{year}\addperiod\space
  \printfield{title}\addspace
  \ifboolexpr{
    test {\iffieldequalstr{type}{mathesis}} or
    test {\ifkeyword{mastersthesis}}
  }
    {\mkbibbrackets{master's thesis}}
    {\mkbibbrackets{dissertation}}%
  \addperiod\space
  \printlist{institution}\addperiod
  \setunit{\addspace}\usebibmacro{cse:trailurl}%
  \usebibmacro{finentry}%
}

% ---- ONLINE / WEBPAGE ----
% Author. Date. Title. Publisher; [updated YYYY Mon DD]; [accessed YYYY Mon DD]. URL
% CSE 9th ed.: publisher location is omitted; access date only required when
%   source has no publication date, but is printed whenever supplied.
\DeclareBibliographyDriver{online}{%
  \usebibmacro{bibindex}\usebibmacro{begentry}%
  \ifnameundef{author}
    {\printfield{title}\addperiod\space}
    {\printnames{author}\addperiod\space}%
  \iffieldundef{year}
    {\printtext{\mkbibbrackets{date unknown}}\addperiod\space}
    {\usebibmacro{cse:fulldate}\addperiod\space}%
  \ifnameundef{author}
    {}% title already printed above
    {\printfield{title}\addperiod\space}%
  \printlist{publisher}%
  \usebibmacro{cse:eventdate}%  % [updated YYYY Mon DD]
  \usebibmacro{cse:urldate}%    % [accessed YYYY Mon DD]
  \addperiod\space
  \usebibmacro{cse:trailurl}%
  \usebibmacro{finentry}%
}

% ---- PATENT ----
% Inventor(s), inventors; Assignee, assignee. YYYY Mon DD. Title. Country patent <number>. URL
\DeclareBibliographyDriver{patent}{%
  \usebibmacro{bibindex}\usebibmacro{begentry}%
  \printnames{author}\addcomma\space inventors\addsemicolon\space
  \printlist{holder}\addcomma\space assignee\addperiod\space
  \usebibmacro{cse:fulldate}\addperiod\space
  \printfield{title}\addperiod\space
  \printlist{location}\space patent\space \printfield{number}\addperiod
  \setunit{\addspace}\usebibmacro{cse:trailurl}%
  \usebibmacro{finentry}%
}

% ---- NEWSPAPER ----
% Author. YYYY Mon DD. Title. Newspaper. [updated YYYY Mon DD]. URL
\DeclareBibliographyDriver{newspaper}{%
  \usebibmacro{bibindex}\usebibmacro{begentry}%
  \printnames{author}\addperiod\space
  \usebibmacro{cse:fulldate}\addperiod\space
  \printfield{title}\addperiod\space
  \printfield{journaltitle}\addperiod\space
  \usebibmacro{cse:eventdate}%  % [updated YYYY Mon DD]
  \setunit{\addspace}\usebibmacro{cse:trailurl}%
  \usebibmacro{finentry}%
}

% ---- MISC / FALLBACK ----
\DeclareBibliographyDriver{misc}{%
  \usebibmacro{bibindex}\usebibmacro{begentry}%
  \printnames{author}%
  \setunit{\addperiod\space}%
  \printfield{year}%
  \setunit{\addperiod\space}%
  \printfield{title}%
  \setunit{\addperiod\space}%
  \printlist{publisher}%
  \setunit{\addperiod\space}%
  \usebibmacro{cse:trailurl}%
  \usebibmacro{finentry}%
}

% ---- REPORT / TECHREPORT ----
% Author. Year. Title. Institution. Report No.: number. URL
% CSE 9th ed.: publisher location is omitted.
\DeclareBibliographyDriver{report}{%
  \usebibmacro{bibindex}\usebibmacro{begentry}%
  \printnames{author}\addperiod\space
  \printfield{year}\addperiod\space
  \printfield{title}\addperiod\space
  \printlist{institution}%
  \iffieldundef{number}{}{%
    \addperiod\space Report No\adddot\addcolon\space\printfield{number}}%
  \setunit{\addperiod\space}%
  \usebibmacro{cse:trailurl}%
  \usebibmacro{finentry}%
}

% ---- INPROCEEDINGS (conference paper) ----
% Authors. Year. Paper title. In: Editor(s), editors. Title of proceedings
%   (Conference name; YYYY Mon DD; Venue). Publisher. p N–N. DOI/URL
% CSE 9th ed.: publisher location is omitted.
\DeclareBibliographyDriver{inproceedings}{%
  \usebibmacro{bibindex}\usebibmacro{begentry}%
  \printnames{author}\addperiod\space
  \printfield{year}\addperiod\space
  \printfield{title}\addperiod\space
  In:\space
  \ifnameundef{editor}
    {}
    {\printnames{editor}\addcomma\space
     \ifboolexpr{
       test {\ifnumgreater{\value{editor}}{1}} or
       test {\ifandothers{editor}}
     }{editors}{editor}\addperiod\space}%
  \printfield{booktitle}%
  % Conference name/date/venue in parentheses when available
  \ifboolexpr{
    not test {\iffieldundef{eventtitle}} or
    not test {\iffieldundef{eventyear}} or
    not test {\iffieldundef{venue}}
  }{%
    \addspace\mkbibparens{%
      \iffieldundef{eventtitle}{}{\printfield{eventtitle}}%
      \iffieldundef{eventyear}{}%
        {\setunit{\addsemicolon\space}%
         \thefield{eventyear}%
         \iffieldundef{eventmonth}{}{\addspace\csemonabrv{\thefield{eventmonth}}}%
         \iffieldundef{eventday}{}{\addspace\thefield{eventday}}}%
      \iffieldundef{venue}{}{\setunit{\addsemicolon\space}\printfield{venue}}%
    }%
  }{}%
  \addperiod\space
  \printlist{publisher}%
  \iffieldundef{pages}{}{.\space p\addspace\printfield{pages}}%
  \setunit{\addperiod\space}%
  \usebibmacro{cse:trailurl}%
  \usebibmacro{finentry}%
}
