%% This is part of the OpTeX project, see http://petr.olsak.net/optex \_codedecl \ulink {Hyperlinks <2021-08-31>} % preloaded in format \_doc ---------------------------- \`\dest``[:]` creates a destination of internal links. The destination is declared in the format `:`. If the \^`\hyperlinks` command in not used, then `\dest` does nothing else it is set to `\_destactive`. The \`\_destactive` is implemented by `\_pdfdest` primitive. It creates a box using \`\_destbox``[:]` in which the destination is shifted by \`\_destheight`. The reason is that the destination is exactly at the top border of the PDF viewer but we want to see the line where the destination is. The destination box is positioned differently dependent on the current vertical or horizontal mode. \_cod ---------------------------- \_def\_destheight{1.4em} \_def\_destactive[#1:#2]{\_if$#2$\_else\_ifvmode \_tmpdim=\_prevdepth \_prevdepth=-1000pt \_destbox[#1:#2]\_prevdepth=\_tmpdim \_else \_destbox[#1:#2]% \_fi\_fi } \_def\_destbox[#1]{\_vbox to\_zo{\_kern-\_destheight \_pdfdest name{#1} xyz\_vss}} \_def\_dest[#1]{} \_public \dest ; \_doc ---------------------------- Each hyperlink is created internally by \`\_xlink``{}{}{}{}`. This macro expands to `\_quitvmode{}` by default, i.e.\ no active hyperlink is created, only is printed in horizontal mode (and in a group). If \^`\hyperlinks` is used, then `\_xlink` gets the meaning of \`\_xlinkactive` and hyperlinks are created by the `\pdfstartlink`/% `\pdfendlink` primitives. The has given only when hyperlink is created. If `\_linkcolor` is defined, it has precedence over . \nl The \`\_linkdimens` macro declares the dimensions of link area. \nl A specific action can be defined for each link by the macro `\_action{}`. \OpTeX/ defines only \`\_urlaction``{}`. The default link action (when `\_action` is not defined) is `goto name{:}` (an internal link). It is declared in the \`\_linkactions``{}{}` macro. \nl The `\_pdfstartlink` primitive uses `attr{\_pdfborder{}}`. The \`\_pdfborder``{}` macro expands to `/C[? ? ?] /Border[0 0 .6]` if the `\_border` macro (i.e.\ \`\_refborder`, \`\_citeborder`, \`\_tocborder`, \`\_pgborder`, \`\_urlborder`, \`\_fntborder` or \`\_fnfborder`) is defined. \_cod \_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\_xlink#1#2#3#4{\_quitvmode{#4}} \_def\_linkdimens{height.9em depth.3em} \_def\_linkactions#1#2{\_ifcsname _#1action\_endcsname \_lastnamedcs{#2}\_else goto name{#1:#2}\_fi} \_def\_urlaction #1{user{/Subtype/Link/A <>}} \_def\_pdfborder#1{\_ifcsname _#1border\_endcsname /C [\_csname _#1border\_endcsname] /Border [0 0 .6]\_else /Border [0 0 0]\_fi } \_doc ------------------------------ \`\link``[:]{}{}` creates a link. It is kept here for backward compatibility and it is equivalent to \^`\_xlink{}{}{}{}`. If `\_action` is not defined then `\link` creates internal link do the \^`\dest[:]`. You can have more links with the same `:` but only one \^`\dest` in the document. \nl \`\ilink``[:]{}` is equivalent to \^`\link` but the `` is used from \^`\hyperlinks` declaration (or it is overwriten by `\def\_linkcolor`). \nl \`\ulink``[]{}` creates external link. The `` is detokenized with `\escapechar=-1` before it is used, so `\%`, `\#` etc. can be used in the ``. \_cod ---------------------------- \_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``` activates `\dest`, `\xlink`, so that they create links. Not setting colors (`\hyperlinks{}{}`) is also supported. \_cod ---------------------------- \_def\_hyperlinks#1#2{% \_let\_dest=\_destactive \_let\_xlink=\_xlinkactive \_let\_ilinkcolor=#1\_empty \_let\_elinkcolor=#2\_empty \_public \dest \xlink ;% } \_public \hyperlinks ; \_doc ---------------------------- \`\url``{}` does approximately the same as \^`\ulink``[]{}`, but more work is done before the `\ulink` is processed. The link-version of is saved to `\_tmpa` and the printed version in `\_tmpb`. The printed 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:}`. The special characters declared by `\sdef{_ur:}` 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 `` is printed in \`\_urlfont`. \_cod ---------------------------- \_def\_url#1{{% \_def\_tmpa{#1}\_replstring\_tmpa {\|}{}% \_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 \_textdirection=0 \_ea\_urlA\_tmpb\_fin}% }} \_def\_urlA#1{\_ifx\_fin#1\_else \_urlC{}{#1}\_fi} \_def\_urlB#1{\_ifx\_fin#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 six types of internal links and one type of external link used in \OpTeX/. They are used in the format :. \begitems * `ref: