Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More control over date formats #863

Open
gusbrs opened this issue Jan 25, 2019 · 15 comments
Open

More control over date formats #863

gusbrs opened this issue Jan 25, 2019 · 15 comments

Comments

@gusbrs
Copy link
Contributor

gusbrs commented Jan 25, 2019

Currently, date formats (year, short, long, terse etc.) are preamble only options which affect any given datetype globally in the document. It would be interesting, from an user’s perspective, to be able to have more flexibility than that.

Consider two possibilities:

  • One would like to have different date formats, for the same datetype, for different entrytypes.
  • One would like to have different date formats, for the same datetype and entrytype, in their short and long format citations.

(Conceptually, the situation could be extended to time too. Though I see less relevance there.)

As it stands, the only way around this, that I know of, is to extend the datamodel and create, e.g. shortdate, use a sourcemap to copy the contents of date to shortdate and, then, use \printdate or \printshortdate as required.

I envisage two (non-excluding?) possible interfaces for this. One would be to add an optional argument to the \printdates commands, as in e.g. \printdate[long]. The other, more interesting, I think, but probably more complicated to implement, is to incorporate the date format as an additional optional argument in the formatting directives for date fields. Or provide an equivalent mechanism for the date format in particular (\DeclareDateFormat?).

I’m well aware date fields are “special” (and tricky). I make the request from an user’s perspective, not knowing if this might be technically viable. I’ve argued though the reasons I think this could be desirable.

Below, I leave two MWEs which may serve as test bases for each of the use cases mentioned above.

MWE1:

\documentclass{article}

\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
  @book{book1,
    author = {Author},
    title = {Book title},
    date = {2011-03-04},
  }

  @article{article1,
    author = {Buthor},
    title = {Article title},
    journal = {Foo},
    date = {2003-12-17},
  }
\end{filecontents}

\usepackage[style=authoryear]{biblatex}

\addbibresource{\jobname.bib}

% could this date also be ‘short’, besides ‘bold’?
\DeclareFieldFormat[article]{date}{\mkbibbold{#1}}

\begin{document}

\nocite{*}

\printbibliography

\end{document}

MWE2:

\documentclass{article}

\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
  @customa{custom1,
    author = {Author},
    title = {Custom long title longer than the short one},
    shorttitle = {Short title},
    date = {2011-03-04},
  }
\end{filecontents}

\usepackage[style=verbose]{biblatex}

\addbibresource{\jobname.bib}

\DeclareBibliographyDriver{customa}{%
  \usebibmacro{bibindex}%
  \usebibmacro{begentry}%
  \usebibmacro{author/editor+others/translator+others}%
  \setunit{\printdelim{nametitledelim}}\newblock
  \usebibmacro{title}%
  \newunit\newblock
  \usebibmacro{organization+location+date}%
  \usebibmacro{finentry}}

\renewbibmacro*{cite:short}{%
  \printnames{labelname}%
  \setunit*{\printdelim{nametitledelim}}%
  \printtext[bibhyperlink]{%
    \printfield[citetitle]{labeltitle}}%
  \ifentrytype{customa}{%
    \newunit
    % could this date be ‘short’?
    % I see no immediate formatting directive approach, in this case. Unless
    % ‘cite:short’ is a valid context?
    \printdate%
  }{}%
}

\begin{document}

\autocite{custom1}

\autocite{custom1}

\end{document}
@moewew
Copy link
Collaborator

moewew commented Jan 27, 2019

Just a short update and a reminder for me in case I forget anything.


I thought that the first MWE could be helped with something like

\ExecuteBibliographyOptions[article]{date=iso}

that is, \ExecuteBibliographyOptions{<datetype>=<format>} could essentially serve as \DeclareDateFormat{<datetype>}{<format>} (if useful, we could even make the second an alias for the first). But as it turns out, the date options are only global at the moment.

So I went down the rabbit hole of trying to consolidate option handling on the three levels global, type and entry and met a few options on the way that could probably be extended to more levels. Some of them are Biber-options, so I should probably open issues for their implementation, but I should probably only do that after I have made sure that the scopes even make sense.

The implementation of the date format options, as it turns out, does not really lend itself to a natural extension to per-type and per-entry scope, so that would need extra work. (If I understand correctly the issue is as follows: The options just set the internal macro \blx@imc@printdate to resolve to the date printing macro with the correct format. The user-level command \printdate is \let to \blx@imc@printdate via the usual \blx@regimcs in \blx@blxinit. But at the point when per-type and per-entry options are processed \blx@blxinit has already been executed and \printdate's meaning is fixed.) The entire date stuff has generated quite a lot of auxiliary options, which makes it hard to wrap my head round.


I haven't yet looked at something like \printdate[short] for the second MWE. But I hope that once I have understood how date handling works to make 1 work it should be possible to get 2 working as well.


Please let me know if I missed of misunderstood anything.

@gusbrs
Copy link
Contributor Author

gusbrs commented Jan 27, 2019

No @moewew , I don't think you've missed or misunderstood anything. And I sympathize and appreciate the idea of consolidating option handling on each level, though it's no mean task.

I did miss the possibility of using \ExecuteBibliographyOptions per entrytype, so that's already one case covered. If this should be made an alias to \DeclareDateFormat, I'm not sure. But, well, if in your overall look in consolidating the options you think it makes sense, I don't see any harm it could do either (except, perhaps, backward compatibility management further down the road).

As to something like \printdate[short] that's the only idea I came up with in a situation as the one described. But, as with the other one, I might have missed something.

Still, my suggestion here is to extend an equivalent flexibility in formatting dates as there are to other field types, in general, for I believe it makes sense (again, from an user's perspective). I do see you concur on that, given you not only bought the idea, but are considering generalizing it.
Anyway, those were two cases I could see where such a flexibility might come handy, the second being a concrete use case of mine (though this is no argument).

moewew added a commit to moewew/biblatex that referenced this issue Jan 29, 2019
* Add new \DeclareBiblatexOption to declare option for multiple scopes
  at once.
* Extend some options to new scopes.
* Related to plk#863.
@gusbrs
Copy link
Contributor Author

gusbrs commented Jan 30, 2019

While working on something else, I came up with another kind of flexibility which might be desirable with respect to dates: datecirca and dateuncertain. (I haven't gone all the way through with the idea, or tried to achieve this through other means. So, it's just food for thought).

For example, it might be desirable to have "circa" and "?" (for uncertain) in the bibliography, while leaving those out from a citation (labeldate). But datecirca and dateuncertain are currently preamble only options (they don't seem to be included in #866 ). (Don't blame me, but this would blend quite well with #861 ).

A MWE for this case:

\documentclass{article}

\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@Book{ARBED1965,
  author       = {Author},
  title        = {A title},
  date         = {1965~},
  location     = {A city},
  publisher    = {Publishers \& Co.},
}
\end{filecontents}

\usepackage[style=authoryear, datecirca=true]{biblatex}
\addbibresource{\jobname.bib}

\begin{document}

% would it be possible to omit "ca." here?
\textcite{ARBED1965}

\printbibliography

\end{document}

moewew added a commit that referenced this issue Feb 3, 2019
Consolidate option handling

* Add new \DeclareBiblatexOption to declare option for multiple scopes
  at once.
* Extend some options to new scopes.
* Tighten (max|min)(bib|cite)?names options.
* Related to #863.
moewew added a commit to moewew/biblatex that referenced this issue Feb 15, 2020
... at least the easy ones...
@moewew
Copy link
Collaborator

moewew commented Feb 22, 2020

I have a commit lined up that generalises all date options to per-type and per-entry scopes. It took a bit of fiddling, but should hopefully be working.

Currently, I'm looking at other ways to control the date format. It should be possible to add an optional argument to \printdate and friends where you can use key-value syntax and options similar to the standard date options to control the output locally. Ideally I'd want to extend that to a \DeclareDateOptions (current working title, but I don't think it can be the final name, since \DeclareTypeOption does something entirely different), where you can preset some of these options. The question is how this \DeclareDateOptions can and should interact with the global, per-type and per-entry date options.

@gusbrs
Copy link
Contributor Author

gusbrs commented Feb 23, 2020

@moewew I'm very glad to see this going forward. And, as usual, for a request which was already bold, you deliver plenty more than was asked. What you already have there, and what you are looking into, seems very promising and interesting indeed. Thank you very much.

I understand your comment was not "just for the OP", but for everyone. Still, I thought it worth mentioning it is much appreciated, and to lend myself at your disposal for some testing. When you think its time for such, let me know.

moewew added a commit to moewew/biblatex that referenced this issue Feb 23, 2020
@moewew
Copy link
Collaborator

moewew commented Feb 23, 2020

You can have a first look at https://github.com/moewew/biblatex/tree/localdateoptions (changes to current dev dev...moewew:localdateoptions). You'll need Biber 2.15 dev from SourceForge to run that version of biblatex.

I'm still thinking about more granular control for datecirca and friends. Currently they apply to all dates alike and creating new options for each date type (labeldatecirca, urldatecirca, ...) would let the number of options explode and would lead to backwards compatibility issues, since what is now datecirca should then be alldatescirca and datecirca would only apply to date and not other dates (not that a lot of people would notice it ...). So I was thinking about something like \ExecuteDateOptions{<datetype>}{<options>}, but the question is how that should interfere with the 'normal' options.

@gusbrs
Copy link
Contributor Author

gusbrs commented Mar 1, 2020

@moewe As promised, I went for a spin of the localdateoptions branch. It is hard to be totally systematic in this area, given the range of possible combinations, but I tried to be thorough, and tested at least every dimension of new functionality. It looks very good indeed, not only for the possibilities it opens, but because things which are being introduced are basically working as expected. But you are right in your previous comments that this new flexibility requires some decisions to be made and bring new interactions into play. So what follows tries to contribute in this direction.

The first thing here is regarding the namespace of date related options and the strain that every new feature/option inevitably brings in this area. I tried to find some sort of way around the namespace for this, but as you can imagine, I stumbled. And in doing so, I'm convinced the user interface for date options might benefit from a more systematic implementation. I tried to come up with something -- in line with what you were already thinking, taking from your comments -- and suggest one possible interface for discussion. (Using the "working title", I'm not arguing here for the macro name, just the UI).

We could have a preamble \DeclareDateOptions with following syntax:

\DeclareDateOptions[<entrytype>]{<datetype>}{<keyvalue options>}
\DeclareDateOptions*{<datetype>}{<keyvalue options>}

The starred version applying to all entrytypes. <datetype> could also receive special value "all" to apply to all datetypes. Either one could receive a comma separated list or values. Current load-time options could be kept as they currently are, and more flexibility than they grant would require the use of the new macro. With this, a single name could be used for each option (dateformat, timeformat, usetime, era, eraauto, circa, uncertain and so on), and the interface is enough to specify the scope to which it applies.

If desired, the availability of such an interface could be used to curb down the global option namespace with time, and due warning ("could", if it "should" is another matter).

This is enough to allow full global, entrytype and datetype scopes flexibility for dates options. Per-entry scope is not covered though, and would still rely on the global names of options. It might be enough, but if full flexibility is desired also at this level, some more handles would be required. In this case, entryfields named <datetype>opts could be used. I'm not sure how welcome this kind of change would be, but there is the langidopts as precedent. And, well, it does fell "biblatexy" to me. With this, single named options could also be applied to per-entry scope.

Regarding testing properly, I came up with some issues, some of which are more general than the new functionality of the branch, but are within the broad scope of this issue. Also, a number of them are not necessarily "problems", but things that called my attention while testing, and the only thing I mean in bringing them here is to check with you if those are really expected results.

  1. Local options given to \printdate and friends override per-entry options. I'm not sure this is a desirable precedence, as local options are probably more at the "style-developer level" while per-entry ones are more "user-level". Of course, this argument is feeble, because preamble global options are also at the hands of the user, but I would hardly argue they should take precedence over local ones. But, either way, I think a clear and consistent precedence rule of the different scopes should be maintained, and ideally also documented. And my gut feeling says "global -> per-entrytype -> print local options -> per-entry" is the more sensible one.

MWE to illustrate:

\documentclass{article}

\usepackage[
  style=authoryear,
  block=par,
  ]{biblatex}

\begin{filecontents}[overwrite]{\jobname.bib}
@customa{myentry,
  author    = {Buthor},
  title     = {My entry's title},
  date      = {2017-04-05T14:34:04~},
  options   = {date=long},
}
\end{filecontents}

\addbibresource{\jobname.bib}

\DeclareBibliographyDriver{customa}{%
  \printnames{author}%
  \setunit{\printdelim{nametitledelim}}%
  \printfield{title}%
  \setunit{\subtitlepunct}%
  \printfield{subtitle}%
  \newunit\newblock
  \printtext{\mkbibbold{date:}}
  \newblock
  \printtext{d:}
  \printdate[dateformat=ymd]
  \newblock
  \printdate
  \newblock
}

\begin{document}
\cite{myentry}
\printbibliography
\end{document}
  1. The checking and handling of date related conflicting options is unequal across cases and, possibly, too intrusive in others. More flexibility in date option setting may improve the handling of such situations.

Consider the following two cases. An user chooses to set all of their datetypes to format terse, except for urldate for which the iso format is chosen. Besides that, this user sets datezeros=false. Another user chooses all of their dates to comp, but wants datezeros=true. In the first case, biblatex will warn the user of conflicting options, and override the datezeros option and set it to true, and as this is a global option, this will affect all datetypes. In the second case, typically (depending on localization) the datezeros option will be silently not honored.

The second case is probably not of great consequence and is likely intended result anyway. It is also understandable, as it is much harder to check option consistency for things which are being set in the .lbxs. The first one can clearly benefit from the effort being done here, by being able to set datezeros (and other similar options) applying to the scope of the datetype only, which is currently not possible.

MWEs to illustrate:

\documentclass{article}

\usepackage[
  style=authoryear,
  date=terse,
  labeldate=terse,
  urldate=iso,
  eventdate=terse,
  origdate=terse,
  datezeros=false,
  block=par,
  ]{biblatex}

\begin{filecontents}[overwrite]{\jobname.bib}
@customa{myentry,
  author    = {Buthor},
  title     = {My entry's title},
  date      = {2017-04-05T14:34:04~},
  urldate   = {2003-06-08T12:54:07?},
  eventdate = {1994-02-09T03:23:17/1994-04-10T07:02:53},
  origdate  = {1456-11-03T08:39:34%},
}
\end{filecontents}

\addbibresource{\jobname.bib}

\DeclareBibliographyDriver{customa}{%
  \printnames{author}%
  \setunit{\printdelim{nametitledelim}}%
  \printfield{title}%
  \setunit{\subtitlepunct}%
  \printfield{subtitle}%
  \newunit\newblock
  \printtext{\mkbibbold{date:}}
  \newblock
  \printtext{d:}
  \printdate
  \newblock
  \printtext{de:}
  \printdateextra
  \newblock
  \printtext{ld:}
  \printlabeldate
  \newblock
  \printtext{lde:}
  \printlabeldateextra
  \newblock
  \printtext{\mkbibbold{url date:}}
  \newblock
  \printtext{d:}
  \printurldate
  \newblock
  \printtext{\mkbibbold{event date:}}
  \newblock
  \printtext{d:}
  \printeventdate
  \newblock
  \printtext{\mkbibbold{orig date:}}
  \newblock
  \printtext{d:}
  \printorigdate
  \newblock
}

\begin{document}
\cite{myentry}
\printbibliography
\end{document}
\documentclass{article}

\usepackage[
  style=authoryear,
  date=comp,
  labeldate=comp,
  urldate=comp,
  eventdate=comp,
  origdate=comp,
  datezeros=true,
  block=par,
  ]{biblatex}

\begin{filecontents}[overwrite]{\jobname.bib}
@customa{myentry,
  author    = {Buthor},
  title     = {My entry's title},
  date      = {2017-04-05T14:34:04~},
  urldate   = {2003-06-08T12:54:07?},
  eventdate = {1994-02-09T03:23:17/1994-04-10T07:02:53},
  origdate  = {1456-11-03T08:39:34%},
}
\end{filecontents}

\addbibresource{\jobname.bib}

\DeclareBibliographyDriver{customa}{%
  \printnames{author}%
  \setunit{\printdelim{nametitledelim}}%
  \printfield{title}%
  \setunit{\subtitlepunct}%
  \printfield{subtitle}%
  \newunit\newblock
  \printtext{\mkbibbold{date:}}
  \newblock
  \printtext{d:}
  \printdate
  \newblock
  \printtext{de:}
  \printdateextra
  \newblock
  \printtext{ld:}
  \printlabeldate
  \newblock
  \printtext{lde:}
  \printlabeldateextra
  \newblock
  \printtext{\mkbibbold{url date:}}
  \newblock
  \printtext{d:}
  \printurldate
  \newblock
  \printtext{\mkbibbold{event date:}}
  \newblock
  \printtext{d:}
  \printeventdate
  \newblock
  \printtext{\mkbibbold{orig date:}}
  \newblock
  \printtext{d:}
  \printorigdate
  \newblock
}

\begin{document}
\cite{myentry}
\printbibliography
\end{document}
  1. \printdateextra does not include time for a number of datetypes (namely year, terse, and comp), even when datesusetime is set. This appears to be localization related, as it happens by default (thus english.lbx) and does not when we load babel with german, for example, but I haven't tested systematically any other language. True, the documentation says of datesusetime:

This option does nothing if a compact date format is being used (see § 3.1.2.1) as this would be very confusing.

But if this is what is at play here, why then are these times showing for german, and for either language for other \printdate commands, e.g. \printdate itself? I'm not sure what the intended result would be here but, unless I'm missing something, there is some inconsistency in the working of this(these) option(s).

MWE:

\documentclass{article}

% Loading babel with german times appear for '\printdateextra' for all
% datetypes, except for 'year'.
% \usepackage[german]{babel}
% \usepackage{csquotes}

\usepackage[
  style=authoryear,
  alldatesusetime=true,
  block=par,
  ]{biblatex}

\begin{filecontents}[overwrite]{\jobname.bib}
@customa{myentry,
  author    = {Buthor},
  title     = {My entry's title},
  date      = {2017-04-05T14:34:04~},
}
\end{filecontents}

\addbibresource{\jobname.bib}

\DeclareBibliographyDriver{customa}{%
  \printnames{author}%
  \setunit{\printdelim{nametitledelim}}%
  \printfield{title}%
  \setunit{\subtitlepunct}%
  \printfield{subtitle}%
  \newunit\newblock
  \printtext{\mkbibbold{date:}}
  \newblock
  \printtext{d:}
  \printdate[dateformat=year]
  \newblock
  \printdate[dateformat=short]
  \newblock
  \printdate[dateformat=long]
  \newblock
  \printdate[dateformat=terse]
  \newblock
  \printdate[dateformat=comp]
  \newblock
  \printdate[dateformat=ymd]
  \newblock
  \printdate[dateformat=iso]
  \newblock
  \printtext{de:}
  \printdateextra[dateformat=year]
  \newblock
  \printdateextra[dateformat=short]
  \newblock
  \printdateextra[dateformat=long]
  \newblock
  \printdateextra[dateformat=terse]
  \newblock
  \printdateextra[dateformat=comp]
  \newblock
  \printdateextra[dateformat=ymd]
  \newblock
  \printdateextra[dateformat=iso]
  \newblock
}

\begin{document}
\cite{myentry}
\printbibliography
\end{document}
  1. The dateextra information is printed after the year for some date formats (ymd, iso) but at the end of the whole date for the remaining ones. This one is likely intended, but just checking.

MWE:

\documentclass{article}

\usepackage[german]{babel}
\usepackage{csquotes}

\usepackage[
  style=authoryear,
  alldatesusetime=true, % to emphasize the effect
  block=par,
  ]{biblatex}

\begin{filecontents}[overwrite]{\jobname.bib}
@customa{myentry,
  author    = {Buthor},
  title     = {My entry's title},
  date      = {2017-04-05T05:27:00},
}
@customa{myentry2,
  author    = {Buthor},
  title     = {My entry's title to trigger dateextra},
  date      = {2017-05-08T22:45:00},
}
\end{filecontents}

\addbibresource{\jobname.bib}

\DeclareBibliographyDriver{customa}{%
  \printnames{author}%
  \setunit{\printdelim{nametitledelim}}%
  \printfield{title}%
  \setunit{\subtitlepunct}%
  \printfield{subtitle}%
  \newunit\newblock
  \printtext{\mkbibbold{date:}}
  \newblock
  \printtext{de:}
  \printdateextra[dateformat=year]
  \newblock
  \printdateextra[dateformat=short]
  \newblock
  \printdateextra[dateformat=long]
  \newblock
  \printdateextra[dateformat=terse]
  \newblock
  \printdateextra[dateformat=comp]
  \newblock
  \printdateextra[dateformat=ymd]
  \newblock
  \printdateextra[dateformat=iso]
  \newblock
}

\begin{document}
\cite{myentry,myentry2}
\printbibliography
\end{document}

That's what I could gather from my testing session, and thus report. And I reiterate this effort around date options is very welcome and appreciated. So, thank you very much. And I hope this report is useful in polishing it.

PS: I may falter in response time for the next couple of weeks, as they promise to be busy. But I'll be following attentively, and will catch up eventually.

@moewew
Copy link
Collaborator

moewew commented Mar 2, 2020

Thank you very much for the extensive testing and feedback. I will have a look at your reply in detail at some point, but probably not before the coming weekend.

@moewew
Copy link
Collaborator

moewew commented Mar 7, 2020

The low-hanging fruits first.

  1. That was fortunately only a typo in english.lbx (introduced in 5abdeab for truncated date formats ignore time #909). Should be fixed in 7542c6d. Doc changed in ff479ad. You should now get times when they are present and you request them with dateusetime. But in a comp situation the date will simply not compress if the date would look odd otherwise.
  1. "Intended" is a big word for it. The output is what it is at the moment, but I don't recall how much thought went into it. At least to me it is not quite clear where the extradate should be. See also Datetimes. Extradate and multiple works by author in same range. #644. If anyone has a sane suggestion that works across all cases (simple dates and date ranges) and is more consistent, I'll be happy to hear about it. But I suggest this should be discussed in a separate issue.

I'll need to have a think about items 1 and 2.

@gusbrs
Copy link
Contributor Author

gusbrs commented Mar 7, 2020

That was fortunately only a typo in english.lbx.

Fortunately indeed. Thanks for the fix.

"Intended" is a big word for it. It is not quite clear where the extradate should be.

I didn't mean to make any claims about it. What caught my attention was the different handling for it across date types, not the placement per se, and that's why I included it. So, beyond the "just checking" intended, further discussion as you see fit.

I'll need to have a think about items 1 and 2.

Sure, and I guess the most delicate is the UI.

And, of course, it will be very, very difficult for you to do anything about item 4. ;-)

@moewew
Copy link
Collaborator

moewew commented Mar 15, 2020

Mhh, while I like the idea of \DeclareDateOptions (or whatever the name), I'm still having a hard time figuring out how it should interact with the normal date option. That is basically the same problem as item 1 for the 'local' \printdate options in your list above, but worse. So maybe it is more sensible to go for normal options here and rename date<option> to alldates<option> breaking some existing styles/documents (a bit).

The date options this would apply to don't appear to be used all that much and are quite specialist anyway (except maybe for datezeros I seriously doubt that a normal user would run into any trouble).

Some data points from the styles installed on my machine (which should hopefully be all styles on CTAN, if I haven't forgotten one: This time I did check OSCOLA).

julian, gregorianstart and dateeraauto aren't used.

datezeros is used by

timezeros is used by

timezones by

seconds by

datecirca and dateuncertain are used by

dateera is used by

  • biblatex-apa (dateera=secular,)
  • biblatex-apa6 (dateera=christian,)

@gusbrs
Copy link
Contributor Author

gusbrs commented Mar 15, 2020

Mhh, while I like the idea of \DeclareDateOptions (or whatever the name), I'm still having a hard time figuring out how it should interact with the normal date option. That is basically the same problem as item 1 for the 'local' \printdate options in your list above, but worse.

Do you mean here on the technical/implementation side, or on the side of devising a set of rules for their relation? If the later, could you expand the kind of problem is raising your concerns? (If the former, I defer to you, as it is out of my league anyway).

@moewew
Copy link
Collaborator

moewew commented Mar 15, 2020

I guess both. I was mainly thinking of the set of rules for their relation, but I had a particular implementation in mind that would make it quite hard to negotiate between the two levels of global options and the per-date option. But I jut realised how \ExecuteBibliograhyOptions works, so maybe there is a way for a completely different approach at least for options that are not also in per-type scope.

Still if you can walk me through your ideas on the rules of how the options should interact, that would be grand. (In particular how should the different per-type levels interact?)

@gusbrs
Copy link
Contributor Author

gusbrs commented Mar 15, 2020

You are probably seeing things that I don't (this is known to have happened in the past ;-), and I also haven't made up my mind on how this should behave, as this is indeed hard to think all the way through. But I can try to come up with something more systematic and bring it here to help you think it over. (I'll prepare it, but I'll need some days to do so).

Besides that, I feel further deepening this namespace for date options will probably bring even more problems down the road. You probably know that better than I do, and if that is the only alternative, than it's chosen. But, do you think it would be also useful if I extended on why a more sophisticated option interface would be a better long term choice for this task? (even if "for the record"). Or would I be "raining on the wet"? (to use a local expression, hopefully understandable).

@gusbrs
Copy link
Contributor Author

gusbrs commented Mar 18, 2020

@moewe As promised, I tried to systematize my thoughts on this issue, and share them with you. Please read them as meaning "what I would try to do if I was attempting to tackle the problem", which I think is mainly one of user interface design. I do not intend to be "normative" in any way whatsoever. I admittedly don't have a perspective as wide as yours, specially not on the implementation side. So, just pick whatever makes sense to you out of the bunch. I do hope there is something useful there, though.

Combinatorics and option namespace

There are two main dimensions through which date related options vary in biblatex: i) the "base date options", meaning options specifying how a print date command should behave with respect to output for a certain specified date; and ii) "scope" specifications, which determine where the "base options" should be applied.

The "base options" currently comprise: date(format), time(format), dateusetime, dateera, dateeraauto, dateabbrev, datecirca, dateuncertain, julian, gregorianstart, datezeros, timezeros, timezones, seconds.

(Btw, dateabbrev doesn't seem to be included in the localdateoptions branch, at least not in the documentation).

"Scopes" either existent or currently being considered in the localdateoptions branch are:

  • global
  • datetype: date, labeldate, origdate, eventdate, urldate, all (in the default datamodel, but expansible)
  • entrytype: 36 regular types in the default datamodel (but expansible)
  • \print... command
  • entry

It is clear that any definition date behavior at the entry scope cannot really be handled by different combinations of names, as the entries set is at the user's side and tends to be large anyway. \print... scope seems also to require the local handling of the options, thus not of not real consequence to the option namespace. We could argue about the entrytype scope, but the sheer number of types present in the default datamodel makes this not very reasonable to deal based on namespace variation options. Indeed, this is currently not done this way, but with \ExecuteBibliographyOptions[<entrytype>]....

Still, considering only "base options" accross datetypes, the potential set of date related options would mount to 84 options (14 "base options" x (5 default datetypes + a catch "all" value)). biblatex currently doesn't handle all these variations. Handled ones are (total 29): date, labeldate, <datetype>date (3), alldates, time (btw, this one seems to have been forgotten in the Option Scope table), labeltime, <datetype>time (3), alltimes, dateusetime (also not in Option Scope table), labeldateusetime, <datetype>usetime (3), alldatesusetime, dateera, dateeraauto, dateabbrev, datecirca, dateuncertain, julian, gregorianstart, datezeros, timezeros, timezones, seconds.

Not currently handled (as far as I can tell) are (total 55): labeldateera, <datetype>era (3), alldatesera, labeldateeraauto, <datetype>eraauto (3), alldateseraauto, labeldateabbrev, <datetype>dateabbrev, alldatesabbrev, labeldatecirca, <datetype>circa (3), alldatescirca, labeldateuncertain, <datetypes>uncertain (3), alldatesuncertain, and so on for julian, gregorianstart, datezeros, timezeros, timezones, seconds. I guess that's what you called "datecirca and friends" above. It is a large set. And is also here, as you already observed, that lies a tricky backward compatibility issue, as these options were initially conceived to be global only, and thus did not apply the "all-" prefix, thus occupying the "slot" of the standard date, according to current option naming conventions.

It is true that a number of those options may be argued to be meant to be global only, thus reducing the size of the set. However, it seems clear that at least some of those deserve to be more flexible as to the scope they apply. And, once we are at it, why not solve it for all of them? Anyway, if this is the argument, it would also beg the question as to why allow the flexibility at entrytype and entry scopes, but not across datetypes. So, current state of these new scope flexibility would increase total options in 55 (and, as mentioned, this leaves aside entrytype, entry, or \print... scopes). Plus the naming related backwards compatibility issues (I agree with you here though, I also don't expect large breakages to ensue from this). Besides, any new option added would increase the set by 6. Any new datetype increases the amount by 14 (true, this is currently very well handled already).

Scopes and precedence rules

The case of the entrytype scope already implies that the interface for date options must rely, at least partially, on some other interface which is not exclusively reliant on "options names combinations" (anyone for 84x36?). Besides that, the fact that it is already possible to use \ExecuteBibliographyOptions[<entrytype>]... at the entrytype scope, and particularly \print....[key=value] at print time, suggests me that it is already possible to set a local value for a given "base date option", meaning here more generally a value that is set within a group.

If this presumption is correct, it seems to me that the trickiest part of the problem lies not so much in how to "set" these options at different scopes, and more in how to "query" them at the appropriate times. And, of course, also how to establish and enforce proper precedence rules along the different scopes.

Furthermore, given entry scope and print time scope are being considered here, there is really only one place where full context information will be available to decide on scope precedence, which is at \print... time. In particular, only there will we have the print time options and the entrykey. At this point, the datetype is fixed, given how the commands are defined. Perhaps it is possible to split precedence decision into some other places, but this one is certainly a privileged place, and correct precedence will only be amenable to be wrapped up there. Taking the precedence rule I proposed in my test report as a premisse (that is "global -> per-entrytype -> print local options -> per-entry", datetype is given), the following pseudo-code somewhere inside \printdate and friends could enforce proper scope precedence of date options:

dolist over "date base options"
    if "base option" of datetype is set for the entrykey
        set "base option" of datetype to that value for the current print command
    else if "base option" of datetype is set at the print command
        set "base option" of datetype to that value for the current print command
    else if "base option" of datetype is set for the entrytype
        set "base option" of datetype to that value for the current print command
    else
        set "base option" of datetype to the global value (which has a default)

Any other precedence rule could be used in similar fashion here, as long as we are at the right place to "query" the options which are relevant to the context in which a given date is being printed. I'm making a number of assumptions here, and this might well turn up to be naïve when the actual current implementation of date options (code-wise), of which I'm mostly ignorant, is considered. But this is the best version of what you asked me: "[my] ideas on the rules of how the options should interact". I'm not sure I got what you meant by:

In particular how should the different per-type levels interact?

But, if I did, the above should also be a possible answer to that. If the scope precedence decision is done at print time, as suggested above, the different per-type levels simply don't interact. At that point, we know the entrytype of entrykey, so have only one type to consider. We have only to decide among different options' scopes.

Still there are more nuances and elements worth discussing, to which I turn.

Indeed, we might well consider the possibility of handling more scopes in this list. Note that I'm not proposing or suggesting this should be done at this point. I'm just considering what this possibility implies to the user interface design. For if the user interface is prepared to accommodate for some flexibility which we conceivably might need in the future, it is better, for changes in the user interface are bound to be painful.

Cases I could conceive: refsection scope; for \printbibliography or \printbiblist; \AtNextCite; \AtNextCitekey; for fullcite and footfullcite but not for the remaining cite commands. Perhaps I could come up with still others, but my only point is that further scope flexibility might be demanded or required at some point. Still, all theses cases I could think of may be generalized as being of "local" scope, that is within a group (which is different from the sense you use in localdateoptions branch, which I've been calling "print time" scope, as you've seen). Devising a precedence rule with this inclusion becomes even trickier, but I think one expedient regularly used by biblatex might come to the rescue. Namely, for example, \DeclareFieldFormat, \DeclareListFormat, \DeclareDelimFormat and friends, for which the starred version overrides any context or entrytype specific settings for the corresponding format. So, we could have a "weak" stance of the local scope, which honors contextual scope options, and a "strong" one, which overrides them. That given, a precedence rule such as "global -> local -> entrytype -> print time -> entry -> global* -> local*" might be considered (starred meaning the "strong" versions of theses scopes). I wouldn't go so far as saying this is fully general, but it is very general, and this scope list plus precedence rule would pretty much be able to accommodate anything I could conceive.

Some small adjustments to the interface I had initially suggested should be enough to handle this much flexibility. The revised version:

We could have a preamble and document-body \DeclareDateOptions with following syntax:

\DeclareDateOptions[<entrytype>]{<datetype>}{<keyvalue options>}
\DeclareDateOptions*{<datetype>}{<keyvalue options>}

<datetype> and <entrytype> could also receive special value "all" to apply, respectively, to all datetypes or entrytypes. Either one could receive a comma separated list or values. The starred version would apply the "strong" version of the options, overriding entrytype, print time, and entry scopes options. \DeclareDateOptions effects would be restrained to the current group, which means it would have local effects if used in a group, or global ones if used ungrouped (e.g. preamble). What I had suggested for the entry scope user interface still stands, and is still the best I could come up with.

Current options and backward compatibility in face of the new flexibility

As far as I understand, if these macros existed, they could be directly used to set the current load-time/preamble options (which are the only ones currently released, if I'm not mistaken), filling the "code" argument in \DeclareBibliographyOption (presumably, with extended scopes, also in \DeclareTypeOption and \DeclareEntryOption). If this assumption is correct, the formal relation of current date options to this more general interface can be expressed by translating the meaning of current options into their corresponding \DeclareDateOptions incantations.

This is trivial for all options which already grant a datetype scope. Let's tackle this first then:

date=<value>              -> \DeclareDateOptions[all]{date}{dateformat=<value>}
labeldate=<value>         -> \DeclareDateOptions[all]{labeldate}{dateformat=<value>}
<datetype>date=<value>    -> \DeclareDateOptions[all]{<datetype>date}{dateformat=<value>}
alldates=<value>          -> \DeclareDateOptions[all]{all}{dateformat=<value>}

time=<value>              -> \DeclareDateOptions[all]{date}{timeformat=<value>}
labeltime=<value>         -> \DeclareDateOptions[all]{labeldate}{timeformat=<value>}
<datetype>time=<value>    -> \DeclareDateOptions[all]{<datetype>date}{timeformat=<value>}
alltimes=<value>          -> \DeclareDateOptions[all]{all}{timeformat=<value>}

dateusetime=<value>       -> \DeclareDateOptions[all]{date}{dateusetime=<value>}
labeldateusetime=<value>  -> \DeclareDateOptions[all]{labeldate}{dateusetime=<value>}
<datetype>usetime=<value> -> \DeclareDateOptions[all]{<datetype>date}{dateusetime=<value>}
alldatesusetime=<value>   -> \DeclareDateOptions[all]{all}{dateusetime=<value>}

It is also not complicated to translate current meaning of "datecirca and friends":

dateera=<value>        -> \DeclareDateOptions[all]{all}{dateera=<value>}
dateeraauto=<value>    -> \DeclareDateOptions[all]{all}{dateeraauto=<value>}
dateabbrev=<value>     -> \DeclareDateOptions[all]{all}{dateabbrev=<value>}
datecirca=<value>      -> \DeclareDateOptions[all]{all}{datecirca=<value>}
dateuncertain=<value>  -> \DeclareDateOptions[all]{all}{dateuncertain=<value>}
julian=<value>         -> \DeclareDateOptions[all]{all}{julian=<value>}
gregorianstart=<value> -> \DeclareDateOptions[all]{all}{gregorianstart=<value>}
datezeros=<value>      -> \DeclareDateOptions[all]{all}{datezeros=<value>}
timezeros=<value>      -> \DeclareDateOptions[all]{all}{timezeros=<value>}
timezones=<value>      -> \DeclareDateOptions[all]{all}{timezones=<value>}
seconds=<value>        -> \DeclareDateOptions[all]{all}{seconds=<value>}

This means full backwards compatibility with current existing options is easy to achieve. The issue does not arise here, because we don't need these options to refer to a specific datetype scope ("date") as opposed to "alldates", which is the meaning they actually currently carry.

But things do get more interesting for "datecirca and friends", because the added flexibility being envisaged implies some choices that made sense previously might welcome a review now. Item 2 of my test report is the best illustration of this.

For example, setting urldate=iso currently enforces:

\DeclareDateOptions[all]{all}{dateera=astronomical}
\DeclareDateOptions[all]{all}{datezeros=true}
\DeclareDateOptions[all]{all}{timezeros=true}
\DeclareDateOptions[all]{all}{seconds=true}
\DeclareDateOptions[all]{urldate}{timeformat=24h}
\DeclareDateOptions[all]{all}{julian=false}

But it is easy to argue as preferable:

\DeclareDateOptions[all]{urldate}{dateera=astronomical}
\DeclareDateOptions[all]{urldate}{datezeros=true}
\DeclareDateOptions[all]{urldate}{timezeros=true}
\DeclareDateOptions[all]{urldate}{seconds=true}
\DeclareDateOptions[all]{urldate}{timeformat=24h}
\DeclareDateOptions[all]{urldate}{julian=false}

Of course, as things stand, this is not possible. But with added scope flexibility (either with \DeclareDateOptions or extension of the option namespace) it will be. True, this will not correspond to previous behavior, but I would rather classify this change as a "fix" than a "breakage". And it will likely reduce conflicting options warnings.

Conversely, things set in the localized dateformats (defined in the .lbxs) may result in some uncovered corners. For example, when setting date=long or date=comp (assuming english.lbx, no babel loaded), with added scope flexibility now we could say \DeclareDateOptions[all]{date}{datezeros=true} or datezeros=true (as opposed to alldateszeros=true), and those options would be ignored, because behavior is hardcoded in the .lbx. A hardcoded override made sense when datezeros was set across the board to all datetypes. With datetype scope flexibility it arguably becomes a bug (agreed, not one to expect great trouble with).

Well, I guess those were my thoughts on the matter. Again, I hope they are somehow useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants