Skip to content

Commit

Permalink
Commit 7
Browse files Browse the repository at this point in the history
- The `\whereapplies` macro now prints "and", instead of a comma, before the
  last page
- All translatable strings have been isolated into the four adjustable macros
  `\hapage`, `\hapages`, `\hadelimiter` and `\halastdelimiter`
- Code review (the `\hereapplies` macro now invokes `\detokenize` before
  checking whether the optional argument was passed)
- The LyX module has been updated
- Documentation
  • Loading branch information
madmurphy committed Aug 23, 2022
1 parent 562fee5 commit d774845
Show file tree
Hide file tree
Showing 6 changed files with 223 additions and 143 deletions.
14 changes: 14 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@ Change Log
==========


## 0.6.0 (2022-08-23)

Changes:

* The `\whereapplies` macro now prints "and", instead of a comma, before the
last page
* All translatable strings have been isolated into the four adjustable macros
`\hapage`, `\hapages`, `\hadelimiter` and `\halastdelimiter`
* Code review (the `\hereapplies` macro now invokes `\detokenize` before
checking whether the optional argument was passed)
* The LyX module has been updated
* Documentation


## 0.5.0 (2022-08-19)

Changes:
Expand Down
84 changes: 50 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,29 @@
Here Applies
============

A LaTeX package for cross-linking concepts to their applications
A LaTeX package for referencing groups of pages that share something in common


Overview
--------

**Here Applies** is a LaTeX package that implements an _informal glossary_ for
cross-linking concepts to their applications. Its core mechanism is identical
to that of a conventional glossary – i.e. some concepts are marked as
“important” and indicized every time they appear in the document – but it does
not produce any nomenclature section, nor relies on the conventions that
normally take part in a glossary.

Besides an indicization mechanism, in fact, a proper glossary should normally
be able to produce a dedicated section – usually at the end of the document –
where the terms are collected in alphabetical order, their definitions are
shown, and the lists of their occurrences are presented. All these things but
the last one, by design, are missing in **Here Applies**.

Instead, the package offers only two macros: `\hereapplies` and `\whereapplies`
(plus their “starred” versions `\hereapplies*` and `\whereapplies*`). In both
cases a “concept identifier” is passed as argument – and this can be any string
invented in the moment, as long as it contains only letters (`\hereapplies`
additionally supports more than one identifier in the form of a comma-separated
list).

Every time `\hereapplies` is invoked again on identical identifiers, the
document is made aware that the same concepts from previous invocations are
occurring in that point. And so, every time the `\whereapplies` macro is
invoked on a known identifier, all the occurrences of the latter within the
entire document will be printed in the form of a linkable page list (e.g. “pp.
1, 5, 8–9, 14–20…”).
**Here Applies** is a LaTeX package that allows to create groups of labels and
reference them altogether. It can be used for creating informal glossaries that
cross-link concepts to their applications, or simply mentioning multiple pages
that share something in common.

The package offers two macros: `\hereapplies` and `\whereapplies` (plus their
“starred” versions `\hereapplies*` and `\whereapplies*`). In both cases an
identifier is passed as argument – and this can be any string invented in the
moment, as long as it contains only letters (`\hereapplies` additionally
supports more than one identifier in the form of a comma-separated list).

Every time `\hereapplies` is invoked with known identifiers, the document is
made aware that the place shares some kind of connection with other places in
which the same identifiers were used. And so, every time the `\whereapplies`
macro is invoked with a known identifier, all the occurrences of the latter
within the entire document will be printed in the form of a linkable page list
(e.g. “pp. 1, 5, 8–9, 14–20…”).

As `\hereapplies` is designed to be invoked in the middle of a chapter or a
section, and that location must be made linkable, the `\phantomsection` macro
Expand Down Expand Up @@ -98,17 +89,17 @@ A minimal tutorial

### Macro `\hereapplies[label]{identifiers}`

The `\hereapplies` macro notifies the document that one or more concepts apply
to a particular point and adds a label to it.
The `\hereapplies` macro notifies the document that one or more identifiers
apply to a particular point and adds a label to it.

If the optional argument is passed the label created will be named accordingly,
otherwise an opaque name will be assigned to it. This argument may contain only
what is legal for `\pageref`.

The `identifiers` argument must be a comma-separated list of identifiers. Each
of these may contain only Latin letters and the "at" sign (`@`). These strings
remain confined within the internal scope of the package and do not create
conflicts with possible macros or labels of the same names.
of these may contain only Latin letters and the "at" sign (`/^[A-Za-z@]+$/`).
These strings will remain confined within the internal scope of the package and
will not create conflicts with possible macros or labels of the same names.

The “starred” version of this macro (`\hereapplies*`) will not invoke the
`\phantomsection` directive.
Expand All @@ -120,8 +111,9 @@ The `\whereapplies` macro prints all the occurrences of an identifier, in the
form “p. …” or “pp. …” (with page range support).

The `identifier` argument may contain only Latin letters and the "at" sign
(`@`). This string remains confined within the internal scope of the package
and does not create conflicts with possible macros or labels of the same name.
(`/^[A-Za-z@]+$/`). This string will remain confined within the internal scope
of the package and will not create conflicts with possible macros or labels of
the same name.

If the same `identifier` is not passed to `\hereapplies` at least once
throughout the document, `\whereapplies` will print “**??**”.
Expand All @@ -130,6 +122,30 @@ The “starred” version of this macro (`\whereapplies*`) will use `\pageref*`
instead of `\pageref` for generating the page list.


Internationalization
--------------------

Currently the localization of **Here Applies** is not automatic. It is possible
however to control the strings generated by overwriting the four macros
`\hapage`, `\hapages`, `\hadelimiter` and `\halastdelimiter`.

For example, writing at the beginning of a document

``` tex
% German translation of **Here Applies**
% English: `p.\ `
\gdef\hapage{S.\ }
% English: `pp.\ `
\gdef\hapages{S.\ }
% English: `\ and\ `
\gdef\halastdelimiter{\ und\ }
% English: `,\ ` (exactly like in German -- leave it)
% \gdef\hadelimiter{,\ }
```

will translate “pp. 2, 4 and 6” into “S. 2, 4 und 6”.


Get involved
------------

Expand Down
Binary file modified hereapplies-example.pdf
Binary file not shown.
98 changes: 64 additions & 34 deletions hereapplies.sty
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
%
% hereapplies.sty
%
% A LaTeX package for cross-linking concepts to their applications
% A LaTeX package for referencing groups of pages that share something in
% common
%
% https://github.com/madmurphy/hereapplies.sty
%
% Version 0.5.0
% Version 0.6.0
%
% Copyright (C) 2022 madmurphy <madmurphy333@gmail.com>
%
Expand Down Expand Up @@ -65,12 +66,27 @@
% \end{document}
%
%
\ProvidesPackage{hereapplies}
\ProvidesPackage{hereapplies}[2022/08/23 Here Applies]
\RequirePackage{hyperref}
\RequirePackage{refcount}
%
%
%
% TRANSLATABLE STRINGS
% ====================
%
%
% The abbreviation of one single page
\providecommand{\hapage}{p.\ }
% The abbreviation of two or more pages
\providecommand{\hapages}{pp.\ }
% The delimiter between page numbers
\providecommand{\hadelimiter}{,\ }
% The delimiter before the last page number
\providecommand{\halastdelimiter}{\ and\ }
%
%
%
% PRIVATE ENVIRONMENT
% ===================
%
Expand All @@ -84,12 +100,12 @@
% Macro `\@ha@makeoccurrencelist{hypermacro}{labels}`
% *****************************************************************************
%
% Generate the list of page numbers with page range support
% Generate the list of page numbers (with page range support)
%
% This macro is for internal purposes only. When invoked, it scans the
% comma-separated list of labels provided (`labels`) and checks which labels
% refer to duplicate page numbers and which page numbers can be grouped
% together.
% This macro is for internal purposes. When invoked, it scans the
% comma-separated list of labels provided (`labels`), checks which labels refer
% to duplicate page numbers and which page numbers can be grouped together, and
% finally prints a list.
%
% The `hypermacro` argument is the macro from the `hyperref` package that will
% process the label name. This should be either `T@pageref` -- equivalent to
Expand All @@ -102,6 +118,10 @@
\def\@ha@tmp@@currp{-1}%
% Reset the current range offset
\def\@ha@tmp@@prangeoffs{-1}%
% Ensure no comma before the first page number
\def\@ha@tmp@@psep{}%
% Ensure no text before the last page number if it is also the first one
\def\@ha@tmp@@lastpsep{}%
% Iterate through the `labels` argument
\@for\@ha@tmp@@thislabel:=#2\do{%
% Store the page number associated with this label
Expand All @@ -128,16 +148,22 @@
% Was the previous page part of a contiguous range?
\ifnum\@ha@tmp@@prangeoffs=-1%
% The previous page was a standalone page
% Print "[p], "
{\csname #1\endcsname{\@ha@tmp@@currlbl}, }%
% Print "[, ]<p>"
{\@ha@tmp@@psep\csname
#1\endcsname{\@ha@tmp@@currlbl}}%
\else%
% The previous page was part of a contiguous range
% Print "[p--q], "
{\csname #1\endcsname{\@ha@tmp@@currrangelbl}--\csname
#1\endcsname{\@ha@tmp@@currlbl}, }%
% Print "[, ]<p--q>"
{\@ha@tmp@@psep\csname
#1\endcsname{\@ha@tmp@@currrangelbl}--\csname
#1\endcsname{\@ha@tmp@@currlbl}}%
% Reset the current range offset
\def\@ha@tmp@@prangeoffs{-1}%
\fi%
% Ensure a comma before the next page number
\let\@ha@tmp@@psep\hadelimiter%
% Ensure " and " before the last page number
\let\@ha@tmp@@lastpsep\halastdelimiter%
\fi%
\fi%
% Prepare the next page number
Expand All @@ -153,12 +179,13 @@
% Was the previous page part of a contiguous range?
\ifnum\@ha@tmp@@prangeoffs=-1%
% The previous page was a standalone page
% Print "[p], "
{\csname #1\endcsname{\@ha@tmp@@currlbl}}%
% Print "[ and ]<p>"
{\@ha@tmp@@lastpsep\csname #1\endcsname{\@ha@tmp@@currlbl}}%
\else%
% The previous page was part of a contiguous range
% Print "[p--q], "
{\csname #1\endcsname{\@ha@tmp@@currrangelbl}--\csname
% Print "[ and ]<p--q>"
{\@ha@tmp@@lastpsep\csname
#1\endcsname{\@ha@tmp@@currrangelbl}--\csname
#1\endcsname{\@ha@tmp@@currlbl}}%
\fi%
\fi%
Expand All @@ -176,9 +203,9 @@
% op.
%
% The `identifier` argument may contain only Latin letters and the "at" sign
% (`@`). This string remains confined within the internal scope of the package
% and does not create conflicts with possible macros or labels of the same
% name.
% (`/^[A-Za-z@]+$/`). This string remains confined within the internal scope of
% the package and does not create conflicts with possible macros or labels of
% the same name.
%
\newcommand{\@ha@newidentifier}[1]{%
% Was this identifier already initialized?
Expand All @@ -189,7 +216,7 @@
% Set the starred output to "??" - it will be updated by the .haN file
\expandafter\gdef\csname @ha@prop@@soutput@#1\endcsname{\textbf{??}}%
% Use "p." for the preamble when there is only one occurrence
\expandafter\gdef\csname @ha@prop@@preamble@#1\endcsname{p.~}%
\global\expandafter\let\csname @ha@prop@@preamble@#1\endcsname\hapage%
% Increase the counter of identifiers
\stepcounter{@ha@identifier@counter}%
% Store the current value of the counter of identifiers
Expand Down Expand Up @@ -245,9 +272,9 @@
% `soutput`, `uoutput`.
%
% The `identifier` argument may contain only Latin letters and the "at" sign
% (`@`). This string remains confined within the internal scope of the package
% and does not create conflicts with possible macros or labels of the same
% name.
% (`/^[A-Za-z@]+$/`). This string remains confined within the internal scope of
% the package and does not create conflicts with possible macros or labels of
% the same name.
%
\newcommand{\@ha@getpropat}[2]{%
% Make sure that the identifier is initialized
Expand All @@ -274,14 +301,16 @@
{\edef\tmp{\noexpand\@ha@newidentifier{\@ha@tmp@@id}}\tmp}%
% Is this the first time this identifier is mentioned?
\ifcsname @ha@prop@@labels@\@ha@tmp@@id\endcsname%
% This is *not* the first time
% This is *not* the first time this identifier is mentioned
% Add this label to the list
\expandafter\g@addto@macro\csname
@ha@prop@@labels@\@ha@tmp@@id\endcsname{,#1}%
% Use "pp." for the preamble when there are multiple occurrences
\expandafter\gdef\csname
@ha@prop@@preamble@\@ha@tmp@@id\endcsname{pp.~}%
\global\expandafter\let\csname
@ha@prop@@preamble@\@ha@tmp@@id\endcsname\hapages%
\else%
% This is the first time
% This is the first time this identifier is mentioned
% Set up the list with this label as value
\expandafter\gdef\csname
@ha@prop@@labels@\@ha@tmp@@id\endcsname{#1}%
\fi%
Expand All @@ -299,7 +328,7 @@
%
\newcommand{\starred@hereapplies}[2][]{%
% Check whether the macro has been called with one or two arguments
\ifx&#1&%
\if\relax\detokenize{#1}\relax%
% The macro has been called with only one argument
% Assign a unique number to the unnamed occurrence
\stepcounter{@ha@unlabeled@counter}%
Expand All @@ -309,6 +338,7 @@
}\tmp}%
\else%
% The macro has been called with two arguments
% Call `\starred@labeled@hereapplies` with the same arguments
\starred@labeled@hereapplies{#1}{#2}%
\fi%
}
Expand All @@ -331,8 +361,8 @@
%
% The `identifiers` argument must be a comma-separated list of identifiers.
% Each of these may contain only Latin letters and the "at" sign (`@`). These
% strings remain confined within the internal scope of the package and do not
% create conflicts with possible macros or labels of the same names.
% strings will remain confined within the internal scope of the package and
% will not create conflicts with possible macros or labels of the same names.
%
% The starred version of this macro (`\hereapplies*`) does not invoke the
% `\phantomsection` directive.
Expand All @@ -350,8 +380,8 @@
% with page range support
%
% The `identifier` argument may contain only Latin letters and the "at"
% sign (`@`). This string remains confined within the internal scope of the
% package and does not create conflicts with possible macros or labels of the
% sign (`@`). This string will remain confined within the internal scope of the
% package and will not create conflicts with possible macros or labels of the
% same name.
%
% If the same `identifier` is not passed to `\hereapplies` at least once
Expand All @@ -363,5 +393,5 @@
\newcommand{\whereapplies}{%
% Check if a star is present in the invocation of the command
\@ifstar{\@ha@getpropat{soutput}}{\@ha@getpropat{uoutput}}%
}
}%

Loading

0 comments on commit d774845

Please sign in to comment.