17

I want to create a macro like \mymacro that has four arguments; first and fourth arguments are any letters, second argument is a character and the third argument is a length. When I say

\mymacro{م}
{ـ} % this is the Kashida
{100pt}
{ن}

I want as many Kashidas as possible to fill that 100pt length completely so that there is no white space. This will produce something like مــــــــــــــــــــــن.

Here is a minimal example:

\documentclass{article}
\usepackage{fontspec}
\setmainfont[ExternalLocation,Scale=3]{amiri-regular}
\begin{document}
مــــــــــــــــــــــن
\end{document}

Edit: I already tried David's solution myself:

\documentclass{article}
\usepackage{fontspec}
\setmainfont[ExternalLocation,Scale=3,Script=Arabic]{amiri-regular}
\usepackage{bidi}
\setRTL
\chardef\myzwj="200D
\newcommand\mymacro[4]{\makebox[#3]{#1\myzwj\leaders\hbox{#2}\hfill\myzwj#4}}
\begin{document}
مــــــــــــــــــــــن

\mymacro{م}
{ـ} % this is the Kashida
{100pt}
{ن}

\end{document}

But I get some space in between (this is something I need to avoid). See the following image:

enter image description here

To answer Heiko's question:

If the space is not an integer multiple of a base unit, where does the unoccupied space go?

The macro should be smart enough to calculate how many Kashida's can go in 100pt. Say in 100pt you can have 15.5 Kashidas, the macro should put 15.5 Kashidas to fill that 100pt length completely (no white space at all).

  • If the space is not an integer multiple of a base unit, where does the unoccupied space go? – Heiko Oberdiek Sep 21 '14 at 13:51
  • As @HeikoOberdiek comments on my answer, your ــــــ sequence has been ligatured in clumps of 4 (I think) producing a wavy line, is that needed (in which case you would want to \leaders in groups of 4, or is it supposed to make one arc? – David Carlisle Sep 21 '14 at 13:59
  • @HeikoOberdiek: I have updated the question and tried to answer your question. – Aditya Sep 21 '14 at 14:06
  • does the 100pt include the width of the letters at the extremities? – user4686 Sep 21 '14 at 14:07
  • @jfbu: No, only the length that you want to fill with Kashida. – Aditya Sep 21 '14 at 14:09
16

Or possibly with \beginL etc added to force direction.

\documentclass{article}
\usepackage{fontspec}
\setmainfont[ExternalLocation,Scale=3]{amiri-regular}
\newcommand\mymacro[4]{\makebox[#3]{#1\leaders\hbox{#2}\hfill#4}}
\begin{document}
مــــــــــــــــــــــن

\mymacro{م}
{ـ} % this is the Kashida
{100pt}
{ن}

\end{document}

adding some overprinting to account for a non integer number of filler characters, and a bit of negative space

enter image description here

\documentclass{article}
\usepackage{fontspec}
\setmainfont[ExternalLocation,Scale=3]{amiri-regular}
\newcommand\mymacro[4]{#4\kern-1pt\rlap{#2}%
                       \makebox[#3]{\leaders\hbox{#2}\hfill}%
                       \llap{#2}\kern-1pt#1}
\begin{document}
مــــــــــــــــــــــن

\mymacro{م}
{ـ} % this is the Kashida
{100pt}
{ن}

\end{document}
| improve this answer | |
  • Unhappily \leader and friends can't be used, because that separates the glyphs from each other. The result is quite a straight line. But a closer look reveals a little more than five larger arcs in the long line of the question. An arc is formed by four characters (ligature? I can't copy and paste it). – Heiko Oberdiek Sep 21 '14 at 13:50
  • @HeikoOberdiek surely it's either leaders or going into the font and setting up some kind of arbitrary length ligature sequence? – David Carlisle Sep 21 '14 at 13:55
  • @DavidCarlisle: Please see my edited question. Thanks – Aditya Sep 21 '14 at 14:05
  • @VafaKhalighi updated:-) – David Carlisle Sep 21 '14 at 14:23
  • @DavidCarlisle: Perfect. Is that 1pt negative kern done by trial and error or there are some reasons behind it? – Aditya Sep 21 '14 at 14:31
17
+100

This answer provides the line by scaling the line character. A closer look at the character bounding box reveals, that there is some slanted part sticking to the left and right. Scaling would also alter the angle of the slanted part. Therefore the implementation constructs the line with three parts:

  • begin part by clipping the rest of the glyph
  • scaled main middle part of the glyph
  • end part by clipping the rest of the glyph

Example:

\documentclass{article}
\usepackage{fontspec}
\setmainfont[ExternalLocation,Scale=3]{amiri-regular}

\usepackage{graphicx}
\usepackage{trimclip}
\usepackage[RTLdocument]{bidi}

\newcommand*{\mymacro}[4]{%
  \leavevmode
  #1%
  \llap{\clipbox{-1ex 0pt {\width} 0pt}{#2}}%
  \resizebox{#3}{\height}{\clipbox{0pt}{#2}}%
  \rlap{\clipbox{{\width} 0pt -1ex 0pt}{#2}}%
  #4%
}

\begin{document}

% show bounding box:
\setlength{\fboxsep}{0pt}
\setlength{\fboxrule}{.1pt}
\scalebox{4}{\fbox{ـ}}

\medskip

مــــــــــــــــــــــن

\mymacro{م}{ـ}{100pt}{ن}

\mymacro{م}{ـ}{200pt}{ن}

\end{document}

Result straight

Variation with slightly scaled wavy line

The next example adds a line glyph at a time until the length is smaller or equal the required length. Then the line is scaled to the required length.

Since the length is not a linear function of the number of glyphs, the example adds one glyph at a time and tests the length.

\documentclass{article}
\usepackage{fontspec}
\setmainfont[ExternalLocation,Scale=3]{amiri-regular}

\usepackage{graphicx}
\usepackage{trimclip}
\usepackage[RTLdocument]{bidi}

\makeatletter
\newcommand*{\mymacro}[4]{%
  \leavevmode
  #1%
  \ifdim#3>\z@ % 0pt
    \begingroup
      \def\glyphline{#2}%
      \settowidth{\dimen@}{\glyphline}%
      \let\next@glyphline\glyphline
      \@whiledim#3>\dimen@\do{%
        \let\glyphline\next@glyphline
        \expandafter
        \def\expandafter\next@glyphline\expandafter{\glyphline#2}%
        \settowidth{\dimen@}{\next@glyphline}%
      }%
      \llap{\clipbox{-1ex 0pt {\width} 0pt}{\glyphline}}%
      \resizebox{#3}{\height}{\clipbox{0pt}{\glyphline}}%
      \rlap{\clipbox{{\width} 0pt -1ex 0pt}{\glyphline}}%
    \endgroup
  \fi
  #4%
}
\makeatother

\begin{document}

مــــــــــــــــــــــن

\mymacro{م}{ـ}{50pt}{ن}

\mymacro{م}{ـ}{100pt}{ن}

\mymacro{م}{ـ}{150pt}{ن}

\mymacro{م}{ـ}{200pt}{ن}

\end{document}

Result wavy

Because of the scaling, the length of a wave vary a little among macro invocations with different line lengths.

| improve this answer | |
  • This is super. This provides better quality than pasting the character n times. I do not know if I can put some bounty for this question; if I can, then I will give you 100 bounties. Thanks again. – Aditya Sep 21 '14 at 14:54
  • By the way, if you delete all your \beginR, \endR, \beginL, and \endL and put \usepackage[RTLdocument]{bidi} after \usepackage{trimclip}, then your example works fine. I patched trimclip xetex driver few months ago in bidi package. – Aditya Sep 21 '14 at 15:00
  • 1
    @VafaKhalighi Thanks, I have updated the examples using \usepackage[RTLdocument]{bidi}. – Heiko Oberdiek Sep 21 '14 at 15:11

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.