%% This is part of the OpTeX project, see http://petr.olsak.net/optex

\_codedecl \ref {References <2022-01-22>} % preloaded in format

   \_doc ----------------------------
   \`\_Xpage` `{<gpageno>}{<pageno>}` saves the parameter pair into \`\_currpage`.
   Resets `\_lfnotenum`; it is used if footnotes are numbered from one at each page.
   \_cod ----------------------------

\_def\_Xpage#1#2{\_def\_currpage{{#1}{#2}}\_lfnotenum=0 }

   \_doc ----------------------------
   Counter for the number of unresolved references \`\_unresolvedrefs`.
   It is set but unused in OpTeX versions 1.04+. You can add the report, for
   example:
   \begtt
   \_addto\_byehook{\_ifnum\_unresolvedrefs>0 \_opwarning
      {There are \_the\_unresolvedrefs\_space unresolved references}\_fi}
   \endtt
   \_cod ----------------------------

\_newcount\_unresolvedrefs
\_unresolvedrefs=0

   \_doc ----------------------------
   \`\_Xlabel` `{<label>}{<text>}` saves the <text> to `\_lab:<label>` and saves
   `{<gpageno>}{<pageno>}` to `\_pgref:<label>`.
   \_cod ----------------------------

\_def\_Xlabel#1#2{\_sdef{_lab:#1}{#2}\_sxdef{_pgref:#1}{\_currpage}}

   \_doc ----------------------------
   \`\label``[<label>]` saves the declared label to \`\_lastlabel` and
   \`\wlabel``{<text>}` uses the `\_lastlabel` and activates
   `\_wref\_Xlabel{<label>}{<text>}`.
   \_cod ----------------------------

\_def\_label[#1]{\_isempty{#1}\_iftrue \_global\_let \_lastlabel=\_undefined
  \_else \_isdefined{l0:#1}%
     \_iftrue \_slideshook\_opwarning{Duplicated label [#1], ignored}\_else \_xdef\_lastlabel{#1}\_fi
  \_fi \_ignorespaces
}
\_let \_slideshook=\_relax % redefined if \slides + \slideshow.
\_def\_wlabel#1{%
  \_ifx\_lastlabel\_undefined \_else
     \_dest[ref:\_lastlabel]%
     \_printlabel\_lastlabel
     \_ewref \_Xlabel {{\_lastlabel}{#1}}%
     \_sxdef{_lab:\_lastlabel}{#1}\_sxdef{l0:\_lastlabel}{}%
     \_global\_let\_lastlabel=\_undefined
  \_fi
}
\_public \label \wlabel ;

   \_doc ----------------------------
   \`\ref``[<label>]{<given-text>}` prints (linked) `<given-text>`.
   The missing optional `{<given-text>}` is replaced by `{@}`. The `@` is
   replaced by `<implicit-text>` from saved `\lab:<label>` using \^`\_reftext` macro.
   If the reference is backward then we know `\lab:<label>` without any need
   to read REF file. On the other hand, if the reference is forwarded, then we
   doesn't know `\_lab:<label>` in the first run of \TeX/ and we print a warning and
   do `\_openref`.
   \nl
   \`\pgref``[<label>]{<given-text>}` prints `<given-text>` where `@` is
   replaced by <pageno>. Data in the format `{<gpageno>}{<pageno>}`
   are read from `\_pgref:<label>` by \`\_pgrefB``{<gpageno>}{<pageno>}{<given-text>}`.
   \nl
   \`\_lastreflabel` keeps the value of the last label read by \^`\ref` or \^`\pgref`.
   You can use it for example by definig a macro `\pg` by `\def\pg{\pgref[\_lastreflabel]}`
   and then you need not repeat the same label in typical situations and you
   can write for instance: `see section \ref[lab] at page \pg.`
   \_cod ----------------------------

\_def\_ref[#1]{\_xdef\_lastreflabel{#1}\_isnextchar\_bgroup{\_refA}{\_refA{@}}}
\_def\_refA #1{\_isdefined{_lab:\_lastreflabel}%
  \_iftrue \_ilink[ref:\_lastreflabel]{\_reftext{\_csname _lab:\_lastreflabel\_endcsname}{#1}}%
  \_else \_reftext{??}{#1}\_opwarning{label [\_lastreflabel] unknown. Try to TeX me again}%
     \_incr\_unresolvedrefs \_openref
  \_fi
}
\_def\_pgref[#1]{\_xdef\_lastreflabel{#1}\_isnextchar\_bgroup{\_pgrefA}{\_pgrefA{@}}}
\_def\_pgrefA #1{\_isdefined{_pgref:\_lastreflabel}%
  \_iftrue \_ea\_ea\_ea\_pgrefB \_csname _pgref:\_lastreflabel\_endcsname{#1}%
  \_else \_reftext{??}{#1}\_opwarning{pg-label [\_lastreflabel] unknown. Try to TeX me again}%
  \_incr\_unresolvedrefs \_openref
  \_fi
}
\_def\_pgrefB #1#2#3{\_ilink[pg:#1]{\_reftext{#2}{#3}}}

\_public \ref \pgref ;

   \_doc -----------------------------
   \`\_reftext``{<implicit-text>}{<given-text>}` expands to the <given-text>
   but the optional `@` in the `<given-text>` is replaced by the `<implicit-text>` first.
   \_cod -----------------------------

\_def\_reftext  #1#2{\_isatin #2@\_iffalse #2\_else\_reftextA{#1}#2\_fin \_fi}
\_def\_reftextA #1#2@#3\_fin {#2#1#3}
\_def\_isatin #1@#2\_iffalse {\_ifx\_fin#2\_fin}

   \_doc -----------------------------
   Default \`\_printlabel` is empty macro (labels are not printed).
   The \`\showlabels` redefines it as box with zero dimensions and
   with left lapped `[<label>]` in blue 10pt `\tt` font shifted up by 1.7ex.
   \_cod -----------------------------

\_def\_printlabel#1{}
\_def\_showlabels {%
   \_def\_printlabel##1{\_vbox to\_zo{\_vss\_llap{\_labelfont[##1]}\_kern1.7ex}}%
   \_fontdef\_labelfont{\_setfontsize{at10pt}\setfontcolor{blue}\_tt}
}
\_public \showlabels ;

\_endcode %------------------------------------------


If the references are \"forward" (i.~e. the `\ref` is used first, the destination
is created later) or if the reference text is page number then we must read
`.ref` file first in order to get appropriate information.
See section \ref[ref-file] for more information about `.ref` file concept.

\_endinput

2022-01-22 ... extended format for \ref, \pgref
2021-04-13 ... \_slideshook introduced (used by \slides)
2020-03-03 ... released
