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!

  • 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. tex.stackexchange.com/questions/312154/…. – Ulrike Fischer Feb 9 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 at 2:45
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

  • 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 at 15:52
  • @user41063, Make sure you load footmisc before you redefine @makefnmark, as footmisc also redefines this. – David Purton Feb 10 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 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 at 3:21
  • what a great work! now I make some testing... Thank you! – user41063 Feb 12 at 16:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.