summaryrefslogtreecommitdiff
path: root/macros/optex/base/hyperlinks.opm
diff options
context:
space:
mode:
Diffstat (limited to 'macros/optex/base/hyperlinks.opm')
-rw-r--r--macros/optex/base/hyperlinks.opm203
1 files changed, 124 insertions, 79 deletions
diff --git a/macros/optex/base/hyperlinks.opm b/macros/optex/base/hyperlinks.opm
index 95fae3846b..ef205f3aa2 100644
--- a/macros/optex/base/hyperlinks.opm
+++ b/macros/optex/base/hyperlinks.opm
@@ -1,6 +1,6 @@
%% This is part of the OpTeX project, see http://petr.olsak.net/optex
-\_codedecl \ulink {Hyperlinks <2021-04-17>} % preloaded in format
+\_codedecl \ulink {Hyperlinks <2021-05-14>} % preloaded in format
\_doc ----------------------------
\`\dest``[<type>:<spec>]` creates a destination of internal links. The
@@ -25,78 +25,81 @@
\_public \dest ;
\_doc ----------------------------
- \`\link``[<type>:<spec>]{<color>}{<text>}` creates an internal link to \^`\dest`
- with the same `<type>:<spec>`. You can have more links with the same
- `<type>:<spec>` but only one `\dest` in the document. If \^`\hyperlinks`
- command is not used, then `\link` only prints `<text>` else its meaning is set to
- `\_linkactive`.
- The \`\_linkactive` is implemented by `\_pdfstartlink...\_pdfendlink`
- primitives. The `<color>` is the color of the link text generated by
- the `\_linkactive` macro.
- The `<color>` parameter can be overwritten by definition of
- `\_<type>linkcolor`. For example `\def\_toclinkcolor{\Red}` means that
- links from table of contents are in red. This is similar concept as
- `\_def\_tocborder`.
+ Each hyperlink is created internally by \`\_xlink``{<type>}{<spec>}{<color>}{<text>}`.
+ This macro expands to `\_quitvmode{<text>}` by default, i.e.\ no active
+ hyperlink is created, only <text> is printed in horizontal mode.
+ If \^`\hyperlinks` is used, then `\_xlink` gets meaning of
+ \`\_xlinkactive` and hyperlinks are created using `\pdfstartlink`,
+ `\pdfendlink` primitives. The <text> has given <color> only when
+ hyperlink is created. But if `\_<type>linkcolor` is defined, it has
+ precedence.
\nl
- \`\ilink``[<type>:<spec>]{<text>}` is equivalent to `\_link` but
- the `<color>` is used from \^`\hyperlinks` declaration
- (or it is overwriten by `\def\_<type>linkcolor`).
+ The \`\_linkdimens` macro declares the dimensions of link area.
\nl
- \`\_linkdimens` are default dimensions of the link area.
- \_cod ----------------------------
+ A specific action can be defined for each link <type> by the macro
+ `\_<type>action{<spec>}`. \OpTeX/ defines only \`\_urlaction``{<url>}`.
+ The default link action (when `\_<type>action` is not defined) is
+ `goto mame{<type>:<spec>}` (creates an internal link). It is declared in the
+ \`\_linkactions``{<type>}{<spec>}` macro.
+ \nl
+ The `\_pdfstartlink` primitive uses `attr{\_pdfborder{<type>}}`. The
+ \`\_pdfborder``{<type>}` macro expands to `/C[? ? ?] /Border[0 0 .6]` if the
+ `\_<type>border` macro (i.e.\ \`\_refborder`, \`\_citeborder`, \`\_tocborder`,
+ \`\_pgborder`, \`\_urlborder`, \`\_fntborder` or \`\_fnfborder`)
+ is defined.
+ \_cod
-\_protected\_def\_linkactive[#1:#2]#3#4{\_leavevmode\_pdfstartlink \_linkdimens
- attr{\_pdfborder{#1}} goto name{#1:#2}\_relax
- {\_localcolor\_trycs{_#1linkcolor}{#3}#4}\_pdfendlink
+\_protected\_def\_xlinkactive#1#2#3#4{\_quitvmode
+ \_pdfstartlink \_linkdimens attr{\_pdfborder{#1}}\_linkactions{#1}{#2}\_relax
+ {\_localcolor\_trycs{_#1linkcolor}{#3}#4}\_pdfendlink
}
-\_protected\_def\_link[#1]#2#3{\_leavevmode{#3}}
-\_def\_ilink[#1]#2{\_link[#1]{}{#2}}
+\_protected\_def\_xlink#1#2#3#4{\_quitvmode{#4}}
+
\_def\_linkdimens{height.9em depth.3em}
-\_public \ilink \link ;
- \_doc ----------------------------
- \`\ulink``[<url>]{<text>}` creates external link. It prints only the `<text>` by default but
- the \^`\hyperlinks` declaration defines it as \`\_urlactive``[url:<url>]{<text>}`.
- The external link is created by the `\_pdfstartlink...\pdfendlink` primitives.
- The `<url>` is detokenized with `\escapechar=-1` before it is used, so
- `\%`, `\#` etc. can be used in the `<url>`.
- \_cod ----------------------------
+\_def\_linkactions#1#2{\_ifcsname _#1action\_endcsname
+ \_lastnamedcs{#2}\_else goto name{#1:#2}\_fi}
+\_def\_urlaction #1{user{/Subtype/Link/A <</Type/Action/S/URI/URI(#1)>>}}
-\_protected\_def\_urlactive[#1:#2]#3#4{\_leavevmode{\_escapechar=-1
- \_pdfstartlink \_linkdimens attr{\_pdfborder{#1}}%
- user{/Subtype/Link/A <</Type/Action/S/URI/URI(\_detokenize{#2})>>}\_relax
- {\_localcolor\_trycs{_#1linkcolor}{#3}#4}\_pdfendlink}%
+\_def\_pdfborder#1{\_ifcsname _#1border\_endcsname
+ /C [\_csname _#1border\_endcsname] /Border [0 0 .6]\_else /Border [0 0 0]\_fi
}
-\_def\_ulink[#1]#2{\_leavevmode{#2}}
-\_public \ulink ;
- \_doc ----------------------------
- The `\_pdfstartlink` primitive uses `attr{\_pdfborder{<type>}}` in its parameter
- (see \^`\_linkactive` or \^`\_urlactive` macros). The \`\_pdfborder``{<type>}`
- macro expands to `/C[? ? ?] /Border[0 0 .6]` if the
- `\_<type>border` macro (i.e.\ \`\_refborder`, \`\_citeborder`, \`\_tocborder`,
- \`\_pgborder`, \`\_urlborder`, \`\_fntborder` or \`\_fnfborder`)
- is defined. Users can define it in
- order to create colored frames around active links. For example
- `\def\_tocborder{1 0 0}` causes red frames in TOC (not printed, only visible
- in PDF viewers).
+ \_doc ------------------------------
+ \`\link``[<type>:<spec>]{<color>}{<text>}` creates a link. It is
+ kept here for backward compatibility and it is
+ equivalent to \^`\_xlink{<type>}{<spec>}{<color>}{<text>}`.
+ If `\_<type>action` is not defined then
+ `\link` creates internal link do the \^`\dest[<type>:<spec>]`.
+ You can have more links with the same `<type>:<spec>` but only one \^`\dest`
+ in the document.
+ \nl
+ \`\ilink``[<type>:<spec>]{<text>}` is equivalent to \^`\link` but
+ the `<color>` is used from \^`\hyperlinks` declaration
+ (or it is overwriten by `\def\_<type>linkcolor`).
+ \nl
+ \`\ulink``[<url>]{<text>}` creates external link.
+ The `<url>` is detokenized with `\escapechar=-1` before it is used, so
+ `\%`, `\#` etc. can be used in the `<url>`.
\_cod ----------------------------
-\_def\_pdfborder#1{\_ifcsname _#1border\_endcsname
- /C [\_csname _#1border\_endcsname] /Border [0 0 .6]\_else /Border [0 0 0]\_fi
-}
+\_def\_link[#1:#2]{\_xlink{#1}{#2}}
+\_def\_ilink[#1:#2]#3{\_xlink{#1}{#2}\_ilinkcolor{#3}}
+\_def\_ulink[#1]#2{{\_escapechar=-1 \_ea}\_expanded
+ {\_noexpand\_xlink{url}{\_detokenize{#1}}}\_elinkcolor{#2}}
+
+\_public \ilink \ulink \link ;
\_doc ----------------------------
- \`\hyperlinks``{<ilink_color>}{<ulink_color>}` activates `\dest`, `\link`,
- `\ilink`, `\ulink` in order they create links. These macros are redefined
- here to their \"active" version.
+ \`\hyperlinks``{<ilink_color>}{<ulink_color>}` activates `\dest`, `\xlink`,
+ in order they create links.
\_cod ----------------------------
\_def\_hyperlinks#1#2{%
- \_let\_dest=\_destactive \_let\_link=\_linkactive
- \_def\_ilink[##1]##2{\_link[##1]{#1}{##2}}%
- \_def\_ulink[##1]##2{\_urlactive[url:##1]{#2}{##2}}%
- \_public \dest \ilink \ulink \link ;%
+ \_let\_dest=\_destactive \_let\_xlink=\_xlinkactive
+ \_let\_ilinkcolor=#1%
+ \_let\_elinkcolor=#2%
+ \_public \dest \xlink ;%
}
\_public \hyperlinks ;
@@ -104,38 +107,64 @@
\`\url``{<url>}` does approximately the same as \^`\ulink``[<url>]{<url>}`, but
more work is done before the `\ulink` is processed. The link-version of <url>
is saved to `\_tmpa` and the printed version in `\_tmpb`. The printed
- version is modified in order to set breakpoints to special places of the
- `<url>`. For example `//` is replaced by `\_urlskip/\_urlskip/\_urlbskip`
- where `\urlskip` adds a small nonbreakable glue between these two slashes and
- before them and `\_urlbskip` adds a breakable glue after them.
+ version is processed in four steps: 1.~the `\|` are replaced by `[||]` (we
+ suppose that such string does not exist in any URL). 2.~it is detokenized with
+ `\escapechar=-1`. 3.~muti-strings and spaces are replaced by strings in
+ braces `{...}`. 4.~internal penalties and skips are put between characters
+ using \`\_urlA`, \`\_urlB` and \`\_urlC`. The step~4 do following:
+ The \`\_urlxskip` is inserted between each pair of \"normal characters",
+ i.e.\ characters not declared by `\sdef{_ur:<character>}`.
+ The special characters declared by `\sdef{_ur:<character>}` are replaced
+ by the body of their corresponding macro.
+ The \`\_urlskip`, \`\_urlbskip`, \`\_urlgskip`
+ are typical skips used for special characters, their meaning is
+ documented in the code below. You can change them.
+ Default values: penalty 9990 is inserted between each pair of normal
+ chararacters, penalty 100 is inserted after special charcters, nobreak before special
+ characters. The URL can be broken at any place using these default
+ values. If you want to disable breaking between normal characters, say
+ `\let\_urlxskip=\nobreak`.
\nl
The text version of the `<url>` is printed in \`\_urlfont`.
\_cod ----------------------------
\_def\_url#1{{%
\_def\_tmpa{#1}\_replstring\_tmpa {\|}{}%
- {\_escapechar=-1 \_ea}\_ea\_edef\_ea\_tmpa\_ea{\_detokenize\_ea{\_tmpa}}%
- \_def\_tmpb{#1}\_replstring\_tmpb {\|}{\_urlbskip}%
- \_replstring\_tmpb {//} {{\_urlskip\_urlslashslash\_urlbskip}}%
- \_replstring\_tmpb {/} {{\_urlskip/\_urlbskip}}%
- \_replstring\_tmpb {.} {{\_urlskip.\_urlbskip}}%
- \_replstring\_tmpb {?} {{\_urlskip?\_urlbskip}}%
- \_replstring\_tmpb {=} {{\_urlskip=\_urlbskip}}%
- \_ea\_replstring\_ea\_tmpb \_ea{\_string &} {{\_urlbskip\_char`\& \_urlskip}}%
- \_ea\_replstring\_ea\_tmpb \_ea{\_bslash|} {{\_penalty0}}%
- \_ea\_ulink \_ea[\_tmpa] {\_urlfont\_tmpb\_null}%
+ \_def\_tmpb{#1}\_replstring\_tmpb {\|}{[||]}%
+ {\_escapechar=-1 \_ea}\_ea\_edef\_ea\_tmpb\_ea{\_detokenize\_ea{\_tmpb}}%
+ \_replstring\_tmpb{[||]}{{gb|}}%
+ \_replstring\_tmpb{ }{{ }}%
+ \_replstring\_tmpb{://}{{://}}%
+ \_ea\_ulink \_ea[\_ea{\_tmpa}] {\_urlfont \_ea\_urlA\_tmpb\_end}%
}}
-\_def\_urlfont{\_tt}
-\_def\_urlskip{\_null\_nobreak\_hskip0pt plus0.05em\_relax}
-\_def\_urlbskip{\_penalty100 \_hskip0pt plus0.05em\_relax}
-\_def\_urlslashslash{/\_urlskip/}
+\_def\_urlA#1{\_ifx\_end#1\_else \_urlC{}{#1}\_fi}
+\_def\_urlB#1{\_ifx\_end#1\_else \_urlC{\_urlxskip}{#1}\_fi}
+\_def\_urlC#1#2{%
+ \_ifcsname _ur:#2\_endcsname \_lastnamedcs \_ea\_ea\_ea \_urlA
+ \_else #1#2\_ea\_ea\_ea \_urlB \_fi
+}
+\_sdef{_ur:://}{\_urlskip:\_urlskip/\_urlskip/\_urlbskip}
+\_sdef{_ur:/}{\_urlskip/\_urlbskip}
+\_sdef{_ur:.}{\_urlskip.\_urlbskip}
+\_sdef{_ur:?}{\_urlskip?\_urlbskip}
+\_sdef{_ur:=}{\_urlskip=\_urlbskip}
+\_sdef{_ur:-}{\_urlskip-\_urlbskip}
+\_sdef{_ur:&}{\_urlskip\_char`\&\_urlbskip}
+\_sdef{_ur:gb|}{\_urlgskip}
+
+\_def\_urlfont{\_tt} % url font
+\_def\_urlxskip{\_penalty9990\_hskip0pt plus0.03em\_relax} % skip between normal characters
+\_def\_urlskip{\_null\_nobreak\_hskip0pt plus0.1em\_relax} % skip before :// / . ? = - &
+\_def\_urlbskip{\_penalty100 \_hskip0pt plus0.1em\_relax} % skip after :// / . ? = - &
+\_def\_urlgskip{\_penalty-500\_relax} % "goodbreak" penalty generated by \|
\_public \url ;
\_endcode % ----------------------------------------
-There are four types of internal links and one type of external link:
+There are six types of internal links and one type of external link used
+in \OpTeX/. They are used in the format <type>:<spec>.
\begitems
* `ref:<label>` -- the destination is created when `\label[<label>]` is used,
@@ -146,20 +175,36 @@ There are four types of internal links and one type of external link:
see also the section \ref[output].
* `cite:<bibpart>/<bibnum>` -- the destination is created in bibliography reference,
see section \ref[bib].
+* `fnt:<gfnotenum>` -- link form text to footnote, see also section~\ref[fnotes].
+* `fnf:<gfnotenum>` -- link from footnote to text, see also section~\ref[fnotes].
* `url:<url>` -- used by `\url` or `\ulink`,
see also the end of this section.
\enditems
-The `<tocrefnum>`, `<gpageno>`, and `<bibnum>` are numbers starting from one and
-globally incremented by one in the whole document. The registers \^`\tocrefnum`,
-\^`\gpageno` and \^`\bibnum` are used for these numbers.
+The `<tocrefnum>`, `<gpageno>`, `<bibnum>`, and `<gfnotenum>` are numbers starting
+from one and globally incremented by one in the whole document. The registers \^`\tocrefnum`,
+\^`\gpageno`, \^`\bibnum`, and \^`\_gfnotenum` are used for these numbers.
When a chap/sec/secc title is prefixed by `\label[<label>]`, then both types
of internal links are created at the same destination place:
`toc:<tocrefnum>` and `ref:<label>`.
+The color for active links can be declared by `\def\_<type>linkcolor`, the
+border around link can be declared by `\def\_<type>border`. These macros are
+not declared by default, so color for active links are given only by
+\^`\hyperlinks` macro and borders are invisible.
+For example `\def\_toclinkcolor{\Red}` means that links from table of
+contents are in red.
+Another example `\def\_tocborder{1 0 0}` causes red frames in TOC
+(not printed, only visible in PDF viewers).
+
+
\_endinput
+2021-05-14 \_xlink introduced, \link, \ilink, \ulink re-implemented.
+2021-05-12 \url: triplet :// instead //, \_urlslashslash removed.
+2021-05-11 \url reimplemented, \_urlxskip added.
+2021-04-30 \url: \detokenize of \tmpb added, bug fix.
2021-04-17 attr{\_pdfborder{...}} instead expanding \_pdfborder to attr{...}
2021-04-02 The possibility of \def\_toclinkcolor introduced, \localcolor moved
2021-01-27 \public \link added to \hyperlinks, bug fixed.