1

I am trying to replace the glue space with a stretched version of a glyph in Xetex, using Xetexinterchartoks. Below is a sample:

\documentclass[10pt,a4paper]{article}
\usepackage{graphicx}
\newcommand \stretchit{
    \makeatletter   
    \XeTeXinterchartokenstate 1%
    \newXeTeXintercharclass \mycharclassA%
    \newXeTeXintercharclass \mycharclassB%
    \XeTeXcharclass `\A \mycharclassA
    \XeTeXcharclass `\B \mycharclassB   
    \chardef\mylinechar=`= %
    \def\mystretchedchar{%
    \nobreak%
    \leavevmode%
        %MainScenario 
        %\dimen0=\XeTeXglyphbounds2 \the\XeTeXcharglyph\mylinechar%"0640%
        %\dimen1=\XeTeXglyphbounds4 \the\XeTeXcharglyph\mylinechar%"0640
        %\leaders\hrule height \dimen0 depth \dimen1 \hskip 0pt plus 05.em%
        %Alternative Scenario #1 
        \hskip 0pt plus 05.em %
        \dimen0=\lastskip%
        \unskip   
        \typeout{DIMEN2= \the\dimen0***and last skip=\the\lastskip }%
        %Alternative Scenario #2
        \setbox0=\hbox{\leaders\hrule height \dimen0 depth \dimen1 \hskip 0pt plus 05.em} %testing: hfil,   
        \dimen0=\wd0%      
        %The actual drawing
        \typeout{DIMEN2= \the\dimen0***and last skip=\the\lastskip }%
        \resizebox{\dimen0}{\height}{\mylinechar}% this: \clipbox{0pt}{\mylinechar} might clip some strange whitespaces around the glyph
    \makeatother
    }
    \XeTeXinterchartoks \mycharclassA \mycharclassB = {\mystretchedchar}

}
\begin{document}
\stretchit{}
Test test test testABTest test test testTestTesttesttest testTest test test test test test test
\end{document}

But the width of glue is always reported zero, while of course it is not zero in the output. I guess that might be due to the stage that I calculate glue width when it is still zero.

It is possible to fill the space with \hrule with a number of characters (or a line as in the MainScenario) but what I want is the stretched version of a glyph.

PS: Actually what I need to fill in the gap with is a glyph (Kashida) that looks the same as a horizontal line, the MainScenario draw a line as a substitute but then there would be dents in junction of this ruler/line with other glyphs. I noticed that the stretched glyph does not have this problem (probably due to font hinting things). That is why I want to find a solution for stretching the glyph as much as the glue.

Thanks

3
  • 2
    unrelated but beware % at ends of lines, you have lots of unneeded ones but m} % will add a space as it is not immediately after the } Mar 3, 2017 at 14:57
  • 1
    Your question isn't totally clear but I suspect you want \skip0=\lastskip not \dimen0=\lastskip as if you put a skip into a dimen register you lose the plus and minus components. Mar 3, 2017 at 15:03
  • @DavidCarlisle, not actually. I simply wanted to find out how much the glue was stretched (finally fixed) so can fill in that space (as you did in you answer) with a stretched character. Also, thanks for educating about %
    – Shahryar
    Mar 3, 2017 at 19:42

1 Answer 1

2

You need to measure the stretched width after the paragraph has been broken into lines, not at the point the chardef tokens are inserted. This means that you need two runs of latex to make it work.

enter image description here

\documentclass[10pt,a4paper]{article}
\usepackage{graphicx}

\makeatletter   %would do nothing inside `\newcommand`
\newcount\zzcount
% don't do new... allocations inside another macro
    \newXeTeXintercharclass \mycharclassA%
    \newXeTeXintercharclass \mycharclassB%
    \XeTeXcharclass `\A \mycharclassA
    \XeTeXcharclass `\B \mycharclassB   
    \chardef\mylinechar=`= %
    \def\mystretchedchar{%
    \leavevmode
    \global\advance\zzcount\@ne
     \pdfsavepos
     \edef\tmp{\write\@auxout{\gdef\expandafter\string\csname TESTA\romannumeral\zzcount\endcsname{\noexpand\the\pdflastxpos}}}%
     \tmp
     \hspace{0pt plus 5em}%
     \pdfsavepos
     \edef\tmp{\write\@auxout{\gdef\expandafter\string\csname TESTB\romannumeral\zzcount\endcsname{\noexpand\the\pdflastxpos}}}%
     \tmp
     \expandafter\ifx\csname TESTA\romannumeral\zzcount\endcsname\relax\else
     \llap{\resizebox{\dimexpr
\csname TESTA\romannumeral\zzcount\endcsname sp - 
\csname TESTB\romannumeral\zzcount\endcsname sp
\relax}{\height}{\mylinechar}}%
     \fi
    }
    \makeatother

\newcommand \stretchit{%%%%
    \XeTeXinterchartokenstate 1 %%% leave space after 1
    \XeTeXinterchartoks \mycharclassA \mycharclassB = {\mystretchedchar}%%%
}
\begin{document}
\stretchit{}
Test test test testABTest test test testTestTesttesttest testTest test test test test test test

zz Test test test testABTest test test testTestTesttesttest testTest test test test test test test zzzz zzzz 

zzzz Test test test testABTest test test testTestTesttesttest testTest test test test test test test zzzz zzzz zzzz zzzz zzzz zzzz 


\end{document}
3
  • Many thanks! It works quite nice in left-to-right and one case situation. However, I wonder if you can suggest how I can use it for many cases situation? As you mentioned "new command name for each time", (probably that is why with more than one case it fails with the above solution, TESTA and TESTB become same). But I have no idea how to implement it , regarding that I want to put that between all two adjacent characters in the document (that is how Kashida works in Persian/Arabic/Urdu) Also, the above solution does not work in BiDi in \setRL mode. TESTA becomes zero in aux. Any idea?
    – Shahryar
    Mar 3, 2017 at 19:38
  • 1
    @Shahryar I extended with a counter that makes a new name each time (look in the aux file to see the names), it should work in a RTL context I think although you may need to do the subtraction in the other order. Mar 3, 2017 at 21:08
  • Fantastic! The behavior in RTL is a little bit strange. In the aux TESTB comes before TESTA! and the first value is zero: \gdef \TESTBi{0} \gdef \TESTAi{24259131}. The output of the first run and subsequent runs is also different. I would try to play with this today. If I come to a solution I would edit my post to reflect it. Otherwise I think I should post a new question because the above one is not related to this problem. Thanks for providing the two solutions and two steps ahead.
    – Shahryar
    Mar 4, 2017 at 10:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .