3

Plz, consider the following code:

\documentclass[a4paper,12pt]{article}
\usepackage{fontspec}
\usepackage{realscripts}
\usepackage[english]{babel}
\babelfont[english]{rm}[Ligatures=TeX,Numbers={Proportional,OldStyle}]{<myfont>}

\frenchspacing

\ExplSyntaxOn
\cs_new:Nn \__realscripts_numtosup:n
  {
    \str_set:Nn \l_tmpa_str {#1}
    \str_map_inline:Nn \l_tmpa_str
      {
        \str_if_in:nnTF {0123456789} {##1}
          {
            \int_set:Nn \l_tmpa_int {##1}
            \if_case:w \l_tmpa_int ⁰
              \or: ¹
              \or: ²
              \or: ³
              \or: ⁴
              \or: ⁵
              \or: ⁶
              \or: ⁷
              \or: ⁸
              \or: ⁹
            \fi:
          }
          { {\addfontfeature{VerticalPosition=Superior}##1} }
      }
  }

\cs_generate_variant:Nn \__realscripts_numtosup:n { x }

\DeclareDocumentCommand \realsuperscript {m} {
  \fontspec_if_fontspec_font:TF
  {
    \fontspec_if_opentype:TF
    { \fontspec_if_feature:nTF {+sups}
      { \__realscripts_numtosup:x{#1} }
      { \fakesuperscript{#1} }
    }
    { \fontspec_if_aat_feature:nnTF {10} {1}
      { \__realscripts_numtosup:x{#1} }
      { \fakesuperscript{#1} }
    }
  }
  { \fakesuperscript{#1} }
}
\ExplSyntaxOff

\begin{document}
\null\vfill
In text numbers: 0123456789

To be\footnote{xxx}. or not to be\footnote{xxx}: that is the question\footnote{xxx}:
Whether ‘tis nobler in the mind to suffer\footnote{xxx}
The slings and arrows of outrageous fortune\footnote{xxx},
Or to take arms against a sea of troubles\footnote{xxx},
And by opposing end them\footnote{xxx}? To die: to sleep\footnote{xxx};
No more\footnote{xxx}; and by a sleep\footnote{xxx} to say we end\footnote{xxx}
The heart-ache\footnote{xxx} and the thousand natural shocks\footnote{xxx}
That flesh is heir to, ‘tis a consummation\footnote{xxx}
Devoutly to be wish’d\footnote{xxx}. To die, to sleep\footnote{xxx};

A{\addfontfeatures{VerticalPosition=Superior}0123456789}.

A{\textsuperscript{9876543210}}.

A{\addfontfeatures{VerticalPosition=Superior}321}.

A{\textsuperscript{321}}.

\end{document}

The resulting .pdf in the following pic:

enter image description here

Obviously, I set a paroxysmal kerning between number 1 and period only for testing reasons. You'll note the kerning works with the last line of the code, but it's not applied to superscript notes marker. Why?

Update

I tried the following code:

\documentclass[a4paper,12pt]{article}
\usepackage{fontspec}
\usepackage{realscripts}
\usepackage[english]{babel}
\babelfont[english]{rm}[Ligatures=TeX,Numbers={Proportional,OldStyle}]{Source Serif Pro}

\directlua {
  fonts.handlers.otf.addfeature {
    name = "supkern",
    type = "kern",
    data = {
      ["one.superior"] = { ["period"] =  -250 },
    },
  }
}

\frenchspacing

\ExplSyntaxOn
\cs_new:Nn \__realscripts_numtosup:n
  {
    \str_set:Nn \l_tmpa_str {#1}
    \str_map_inline:Nn \l_tmpa_str
      {
        \str_if_in:nnTF {0123456789} {##1}
          {
            \int_set:Nn \l_tmpa_int {##1}
            \if_case:w \l_tmpa_int ⁰
              \or: ¹
              \or: ²
              \or: ³
              \or: ⁴
              \or: ⁵
              \or: ⁶
              \or: ⁷
              \or: ⁸
              \or: ⁹
            \fi:
          }
          { {\addfontfeature{VerticalPosition=Superior}##1} }
      }
  }

\cs_generate_variant:Nn \__realscripts_numtosup:n { x }

\DeclareDocumentCommand \realsuperscript {m} {
  \fontspec_if_fontspec_font:TF
  {
    \fontspec_if_opentype:TF
    { \fontspec_if_feature:nTF {+sups}
      { \__realscripts_numtosup:x{#1} }
      { \fakesuperscript{#1} }
    }
    { \fontspec_if_aat_feature:nnTF {10} {1}
      { \__realscripts_numtosup:x{#1} }
      { \fakesuperscript{#1} }
    }
  }
  { \fakesuperscript{#1} }
}
\ExplSyntaxOff

\begin{document}
\null\vfill
In text numbers: 0123456789

To be\footnote{xxx}. or not to be\footnote{xxx}: that is the question\footnote{xxx}:
Whether ‘tis nobler in the mind to suffer\footnote{xxx}
The slings and arrows of outrageous fortune\footnote{xxx},
Or to take arms against a sea of troubles\footnote{xxx},
And by opposing end them\footnote{xxx}? To die: to sleep\footnote{xxx};
No more\footnote{xxx}; and by a sleep\footnote{xxx} to say we end\footnote{xxx}
The heart-ache\footnote{xxx} and the thousand natural shocks\footnote{xxx}
That flesh is heir to, ‘tis a consummation\footnote{xxx}
Devoutly to be wish’d\footnote{xxx}. To die, to sleep\footnote{xxx};

A{\addfontfeatures{VerticalPosition=Superior}0123456789}.

A{\textsuperscript{9876543210}}.

A{\addfontfeatures{VerticalPosition=Superior}321}.

A{\textsuperscript{321}}.

A{\addfontfeature{RawFeature=+sups}1.}

A{\addfontfeature{RawFeature=+supkern;+sups}1.}

\end{document}

but \directlua doesn't produce any result and the last two line unnecessary, for period is itself superscrit. What's wrong?

Further update

Try this code:

\documentclass[a4paper,12pt]{book}
\usepackage{fontspec}
\directlua {
  fonts.handlers.otf.addfeature {
    name = "supkern",
    type = "kern",
    data = {
      ["¹"] = { ["."] =  -180,
                [","] =  -180 },
    },
  }
}

\usepackage[english]{babel}
\babelfont[english]{rm}[Ligatures=TeX,Numbers={Proportional,OldStyle},RawFeature=+supkern,RawFeature=+calt]{Source Serif Pro}
\usepackage{realscripts}
\usepackage{perpage}
\MakePerPage{footnote}
\usepackage[bottom,hang,stable,norule]{footmisc} % perpage
\renewcommand{\footnotemargin}{0.01em}
\renewcommand{\hangfootparskip}{0pt}
\renewcommand{\footnotelayout}{\hspace{1em}}

\makeatletter
\def\@makefnmark{\unpenalty{\footnotemarkfont\textsuperscript{\@thefnmark}}}
\makeatother
\ExplSyntaxOn
\bool_new:N \l__realscripts_punct_found_bool
\tl_new:N \l__realscripts_footnote_text_tl
\cs_set_eq:NN \__realscripts_footnote:n \footnote
\cs_new_protected:Nn \__realscripts_footnote_with_punct:
  {
    \bool_set_false:N \l__realscripts_punct_found_bool
    \str_map_inline:nn { ., }
      {
        \token_if_eq_meaning:NNT \l_peek_token ##1
          {
            \footnotemark
            \l_peek_token
            \footnotetext { \l__realscripts_footnote_text_tl }
            \bool_set_true:N \l__realscripts_punct_found_bool
            \str_map_break:
          }
      }
    \bool_if:NTF \l__realscripts_punct_found_bool
      { \use_none:n }
      { \__realscripts_footnote:n { \l__realscripts_footnote_text_tl } }
  }
\cs_new_protected:Nn \__realscripts_footnote_with_punct:n
  {
    \tl_set:Nn \l__realscripts_footnote_text_tl {#1}
    \peek_after:Nw \__realscripts_footnote_with_punct:
  }
\cs_new_protected:Nn \__realscripts_numtosup:n
  {
    \str_set:Nn \l_tmpa_str {#1}
    \str_map_inline:Nn \l_tmpa_str
      {
        \str_if_in:nnTF { 0123456789 } {##1}
          {
            \int_set:Nn \l_tmpa_int {##1}
            \if_case:w \l_tmpa_int ⁰
              \or: ¹
              \or: ²
              \or: ³
              \or: ⁴
              \or: ⁵
              \or: ⁶
              \or: ⁷
              \or: ⁸
              \or: ⁹
            \fi:
          }
          { { \addfontfeature {VerticalPosition=Superior} ##1 } }
      }
  }
\cs_generate_variant:Nn \__realscripts_numtosup:n { x }
\DeclareDocumentCommand \realsuperscript { m } {
  \fontspec_if_fontspec_font:TF
  {
    \fontspec_if_opentype:TF
    { \fontspec_if_feature:nTF {+sups}
      { \__realscripts_numtosup:x{#1} }
      { \fakesuperscript{#1} }
    }
    { \fontspec_if_aat_feature:nnTF {10} {1}
      { \__realscripts_numtosup:x{#1} }
      { \fakesuperscript{#1} }
    }
  }
  { \fakesuperscript{#1} }
}
\DeclareDocumentCommand \footnote { +m }
  {
    \__realscripts_footnote_with_punct:n {#1}
  }
\ExplSyntaxOff

\begin{document}

\chapter{Test chapter}

«text»\footnote{Footnote text}.

A\footnote{Footnote text}.

A\footnote{Footnote text},

A\footnote{Footnote text};

A\footnote{Footnote text}.

\end{document}

You'll realize that something strange happens: no footnote 1!

user41063
  • 1,967
  • It would be better if you would make an example with a real font that exists also on our systems and not with a <myfont>. You can add special kerns with fonts.handlers.otf.addfeature, see e.g. https://tex.stackexchange.com/questions/312154/how-to-adjust-font-features-in-luatex. – Ulrike Fischer Feb 09 '19 at 23:17
  • 1
    The kerning is not applied to footnote marks because the marker is wrapped in a box. LaTeX defines \def\@makefnmark{\hbox{\@textsuperscript{\normalfont\@thefnmark}}} – Henri Menke Feb 10 '19 at 02:45

1 Answers1

4

I updated my answer to your previous question before seeing this one. For the sake of getting the right things in the right place, here's my answer reproduced.

Your kerning problem is caused by the fact that the footnote mark is set inside an \hbox. This destroys the kerning between 'A' and '¹'. Consider this code using my patched \realsuperscript macro from below:

A{\addfontfeatures{VerticalPosition=Superior}1}.
A{\textsuperscript{1}}.
A\footnote{1}.}

When we show this we get:

.\TU/SourceSerifPro(0)/m/n/12 A
.\TU/SourceSerifPro(1)/m/n/12 ¹
.\TU/SourceSerifPro(0)/m/n/12 .
.\glue(\spaceskip) 3.72801 plus 4.19398 minus 0.31067
.\TU/SourceSerifPro(0)/m/n/12 A
.\kern-1.68 (font)
.\TU/SourceSerifPro(0)/m/n/12 ¹
.\TU/SourceSerifPro(0)/m/n/12 .
.\glue(\spaceskip) 3.72801 plus 4.19398 minus 0.31067
.\TU/SourceSerifPro(0)/m/n/12 A
.\penalty 10000
.\hbox(9.936+0.0)x4.44, direction TLT
..\TU/SourceSerifPro(0)/m/n/12 ¹
.\insert253, natural size 12.00003; split(8.4,3.60004); float cost 20000
..\hbox(8.4+3.60004)x390.0, glue set 367.63995fil, direction TLT
...\localpar
....\localinterlinepenalty=0
....\localbrokenpenalty=0
....\localleftbox=null
....\localrightbox=null
...\hbox(8.28+0.0)x18.00003, glue set 14.30003fil, direction TLT
....\glue 0.0 plus 1.0fil minus 1.0fil
....\hbox(8.28+0.0)x3.7, direction TLT
.....\TU/SourceSerifPro(0)/m/n/10 ¹
...\hbox(8.4+0.0)x0.0, direction TLT
....\rule(8.4+0.0)x0.0
...\TU/SourceSerifPro(0)/m/n/10 
...\penalty 10000
...\rule(0.0+3.60004)x0.0
...\penalty 10000
...\glue(\parfillskip) 0.0 plus 1.0fil
...\glue(\rightskip) 0.0
.\TU/SourceSerifPro(0)/m/n/12 .

We can see that

  1. In the first case there is a font change and no kerning is inserted.
  2. In the second case there is no font change and kerning is inserted.
  3. In the third case there is a \penalty and and then '¹' is placed inside an \hbox and therefore no kerning is inserted even though there is no font change.
  4. I the third case the \hbox with the footnote mark and the final period is separated by the float material for the footnote text. Therefore any kerning between '¹' and '.' is lost.

So to work around this two things are needed:

  1. Adjust the \@makefnmark macro (previously adjusted from the default by the realscripts package) to remove the penalty and not to use the \hbox. This could have unwanted side effects, of course :).
  2. Use A\footnotemark.\footnotetext{…} instead of A\footnote{…}.

The first could be achieved by using something like:

\makeatletter
\def\@makefnmark{\unpenalty{\footnotemarkfont\textsuperscript{\@thefnmark}}}
\makeatother

I have had a go at redefining \footnote to test for punctuation and automatically deal with the second point.

MWE

Here's a full MWE (I added some directlua to add kerning between '¹' and '.' and ',' as Source Sans Serif does not include this). It also shows how to patch things to make it work with the perpage and stable options of the footmisc package.

\documentclass[a4paper,12pt]{book}
\usepackage{fontspec}
\directlua {
  fonts.handlers.otf.addfeature {
    name = "supkern",
    type = "kern",
    data = {
      ["¹"] = { ["."] =  -180,
                [","] =  -180 },
      ["²"] = { ["."] =  -180,
                [","] =  -180 },
      ["³"] = { ["."] =  -180,
                [","] =  -180 },
      ["⁵"] = { ["."] =  -180,
                [","] =  -180 },
    },
  }
}
\usepackage{realscripts}
\usepackage[english]{babel}
\babelfont[english]{rm}[Ligatures=TeX,Language=Default,Numbers={Proportional,OldStyle},RawFeature=+supkern]{Source Serif Pro}
\usepackage[perpage,bottom,hang,stable,norule]{footmisc}
\renewcommand{\footnotemargin}{0.01em}
\renewcommand{\hangfootparskip}{0pt}
\renewcommand{\footnotelayout}{\hspace{1em}}
\usepackage{xpatch}
\makeatletter
\def\@makefnmark{\unpenalty{\footnotemarkfont\textsuperscript{\@thefnmark}}}
\ifFN@perpage
  \xpatchcmd{\footnotemark}
    {\ifFN@pp@towrite
       \FN@pp@writetemp
       \FN@pp@towritefalse
     \fi}
    {}
    {}
    {}
  \xpretocmd{\@footnotetext}
    {\ifFN@pp@towrite
       \FN@pp@writetemp
       \FN@pp@towritefalse
     \fi}
    {}
    {}
  \ifFN@stablefootnote
    \xpatchcmd{\FN@sf@@footnotemark}
      {\ifFN@pp@towrite
         \FN@pp@writetemp
         \FN@pp@towritefalse
       \fi}
      {}
      {}
      {}
  \fi
\fi
\makeatother
\ExplSyntaxOn
\bool_new:N \l__realscripts_punct_found
\tl_new:N \l__realscripts_footnote_text_tl
\cs_set_eq:NN \__realscripts_footnote:n \footnote
\cs_new_protected:Nn \__realscripts_footnote_with_punct:
  {
    \bool_set_false:N \l__realscripts_punct_found
    \str_map_inline:nn { ., }
      {
        \token_if_eq_meaning:NNT \l_peek_token ##1
          {
            \footnotemark
            \l_peek_token
            \footnotetext { \l__realscripts_footnote_text_tl }
            \bool_set_true:N \l__realscripts_punct_found
            \str_map_break:
          }
      }
    \bool_if:NTF \l__realscripts_punct_found
      {
        \use_none:n
      }
      {
        \__realscripts_footnote:n { \l__realscripts_footnote_text_tl }
      }
  }
\cs_new_protected:Nn \__realscripts_footnote_with_punct:n
  {
    \tl_set:Nn \l__realscripts_footnote_text_tl {#1}
    \peek_after:Nw \__realscripts_footnote_with_punct:
  }
\cs_new_protected:Nn \__realscripts_numtosup:n
  {
    \str_set:Nn \l_tmpa_str {#1}
    \str_map_inline:Nn \l_tmpa_str
      {
        \str_if_in:nnTF {0123456789} {##1}
          {
            \int_set:Nn \l_tmpa_int {##1}
            \if_case:w \l_tmpa_int ⁰
              \or: ¹
              \or: ²
              \or: ³
              \or: ⁴
              \or: ⁵
              \or: ⁶
              \or: ⁷
              \or: ⁸
              \or: ⁹
            \fi:
          }
          { { \addfontfeature {VerticalPosition=Superior} ##1 } }
      }
  }
\cs_generate_variant:Nn \__realscripts_numtosup:n { x }
\DeclareDocumentCommand \realsuperscript { m }
  {
    \fontspec_if_fontspec_font:TF
      {
        \fontspec_if_opentype:TF
          {
            \fontspec_if_feature:nTF { +sups }
              { \__realscripts_numtosup:x {#1} }
              { \fakesuperscript {#1} }
          }
          { 
            \fontspec_if_aat_feature:nnTF {10} {1}
              { \__realscripts_numtosup:x {#1} }
              { \fakesuperscript {#1} }
          }
      }
      { \fakesuperscript {#1} }
  }
\DeclareDocumentCommand \footnote { +m }
  {
    \__realscripts_footnote_with_punct:n {#1}
  }
\ExplSyntaxOff
\begin{document}
\chapter{Test chapter}

«text»\footnote{Footnote text}.

A\footnote{Footnote text}.

A\footnote{Footnote text},

A\footnote{Footnote text};

A\footnote{Footnote text}.
\end{document}

output

David Purton
  • 25,884
  • The matter is complicated. Your code works well, however it interferes with other note management packages: for example if you use footmisc, you return to the starting situation ... no kerning – user41063 Feb 10 '19 at 15:52
  • @user41063, Make sure you load footmisc before you redefine @makefnmark, as footmisc also redefines this. – David Purton Feb 10 '19 at 22:31
  • I tried, but it does not seem to work even when first loading the packages dedicated to managing the notes as footmisc – user41063 Feb 11 '19 at 15:37
  • @user41063, I included a redefinition of \footnote and also the footmisc package to show that it does work. – David Purton Feb 12 '19 at 03:21
  • what a great work! now I make some testing... Thank you! – user41063 Feb 12 '19 at 16:59
  • If my test are correct, your last code works fine with many footmisc options, except if you enter the option perpage – user41063 Feb 12 '19 at 18:28
  • It works by removing the perpage option and entering directly a code like \makeatletter \@newctr{footnote}[page] \makeatother – user41063 Feb 12 '19 at 20:13
  • Full compatibility with packege perpage with option \MakePerPage{footnote} – user41063 Feb 12 '19 at 22:52
  • @user41063, to make it work with \usepackage[perpage]{footmisc} a little more patching is required. – David Purton Feb 13 '19 at 13:44
  • Plz, consider my last update! – user41063 Feb 13 '19 at 18:48
  • @user41063, there were two additional problems. Using the perpage package causes problems (which I didn't bother to investigate, as you can use the perpage option of footmisc). And another adjustment is needed for the stable option of footmisc. Any more mystery footnote customisations? This shows the importance of providing a MWE that includes everything that is relevant. Since you are messing with the internals of footnotes, anything that affects footnotes is important. – David Purton Feb 14 '19 at 00:16
  • You're right, but not always it's possible to forecast all situation. In any case, another mystery. The code doesn't work with hyperref, for instance with: \usepackage[pdfencoding=unicode]{hyperref} \hypersetup{ pdftitle={Pdftitle}, pdfauthor={Pdfauthor}, hidelinks } \usepackage{bookmark} – user41063 Feb 14 '19 at 17:57
  • It request hyperfootnotes=false option to work. But let me test again – user41063 Feb 14 '19 at 18:58
  • Yes, hyperref also messes with footnotes. – David Purton Feb 14 '19 at 19:53
  • In the next day I'll test the code in some other big files of mine. Thank you a lot for your great job and your helpfullness. Why don't you think to create a package managing these typographycal aspects of footnotes? There are no packages with this function, if not fnpct, which however is not very elastic (applies an equal kerning for all the superscript) and is currently also broken ... – user41063 Feb 14 '19 at 22:24
  • @user41063, I think it's time to tie this question off. (Maybe mark it as answered). hyperref is going to be problematic and deserves a new question, which more people will see. You could use a MWE example like this: \documentclass{article} \usepackage[colorlinks]{hyperref} \begin{document} AVA A\href{www.example.com}{V}A \end{document} and ask if it is possible to preserve the automatic font kerning. I think if it is possible, it will require some kind of Lua magic that is beyond my skill. When you ask the question, link back to this one for context, but use the smaller MWE. – David Purton Feb 15 '19 at 01:12
  • I'll consider a package. I've found it quite an interesting challenge to make it work. But it would need to be made a fair bit more flexible and customisable to make such a package useful. And hyperref is definitely a challenge that would be useful, but I have no idea how to solve the problem. Similar issues also surface just with colour: A\textcolor{red}{V} also destroys kerning. But you could work around that one by using fontspec colouring. – David Purton Feb 15 '19 at 01:31
  • ok, consider this thread closed. In case, I will post other questions. Of course, a package should be flexible and compatible with many other packages. I only observe that my problem stems from the fact that, despite being a very advanced typographic composition system, LaTeX does not adequately manage the kerning built inside the font, which is certainly a flaw. Thanks again for your help – user41063 Feb 15 '19 at 19:37