Emphasizing Arabic text characters

The following can be improved in various ways (e.g. using tikz is probably a bit overkill and also doesn't work well in RTL mode; there should be a way to select the glyphs which gets a frame and to change the colors; glue and other nodes are currently ignored, so it works only for single words) but it shows that it is basically possible to inspect the words, get the dimensions and draw something which doesn't interfere with the font shaping:

\documentclass[a4paper,12pt,twoside]{book}

\usepackage [bidi=basic,layout=lists.tabular]{babel}
\babelprovide[import=ar,mapdigits,main]{arabic}
\babelprovide[import=en,language=Default]{english}

\babelfont{rm}{Latin Modern Roman}
\babelfont[arabic]{rm}[Renderer=HarfBuzz]{amiri}
\babelfont[english]{rm}{Times New Roman}


\usepackage{tikz}

\newsavebox\myword

\usepackage{luacode}
\begin{luacode}
function frameword (boxnum)
   local head = tex.box[boxnum].head
   local colortable={"yellow","red","blue","green"}
   local GLYPH           = node.id("glyph")
   local widthtable={}
   local heighttable={}
   local depthtable={}
   for n in node.traverse(head) do
    local id = n.id
    if id == GLYPH then
      table.insert(widthtable,n.width);
      table.insert(heighttable,n.height);
      table.insert(depthtable,n.depth);
      texio.write_nl (" WIDTH ".. n.width .. " CHAR " .. n.char)
    else
      texio.write_nl ("????")
    end
   end
    for i = table.getn(widthtable), 1, -1 do
     color = colortable[math.fmod(i,4)+1]
     tex.sprint("\\printrectangle{"..color.."}{".. widthtable[i] .."}{" .. heighttable[i].."}{" .. depthtable[i] .."}")
    end
end
\end{luacode}
\begin{document}
جنوب 



\newcommand\printrectangle[4]{\tikz[overlay]\draw[#1,opacity=0.5](0,-#4sp)rectangle(#2sp,#3sp);\hspace{#2sp}}
\savebox\myword{\textdir TRT جنوب} 



\leavevmode\foreignlanguage{english}{\directlua{frameword(\the\myword)}\llap{\usebox\myword}}

\end{document}

enter image description here


Robert's answer with babel, added \arbboxi, \arbboxr, \arbboxl and \arbboxb for isolated, beginning, end, middle form of letters. boxes are drawn with TikZ you can customize them with boxstyle as you like using \tikzset{boxstyle/.append style={...}}

\documentclass[a4paper,12pt,twoside]{book}

\usepackage [bidi=basic,layout=lists.tabular]{babel}
\babelprovide[import=ar,mapdigits,main]{arabic}

\babelfont{rm}{Amiri}

\usepackage{tikz}
\usepackage{ulem}
    
\newcommand{\ulinei}[1]{\uline{#1}}
\newcommand{\ulinel}[1]{^^^^200d\uline{^^^^200d#1}}
\newcommand{\uliner}[1]{\uline{#1^^^^200d}^^^^200d}
\newcommand{\ulineb}[1]{^^^^200d\uline{^^^^200d#1^^^^200d}^^^^200d}

\tikzset{boxstyle/.style={draw=red,inner sep=0pt,fill=yellow}}

\newcommand{\arbboxi}[1]{%
\tikz[baseline=(x.base)]\node(x)[boxstyle]{#1};%
}
\newcommand{\arbboxl}[1]{%
  ^^^^200d\tikz[baseline=(x.base)]\node(x)[boxstyle]{^^^^200d#1};%
}
\newcommand{\arbboxr}[1]{%
  \tikz[baseline=(x.base)]\node(x)[boxstyle]{#1^^^^200d};^^^^200d%
}
\newcommand{\arbboxb}[1]{%
  ^^^^200d\tikz[baseline=(x.base)]\node(x)[boxstyle]{^^^^200d#1^^^^200d};^^^^200d%
}
    
\begin{document}

\Large

جنوب 

\hrulefill

\uliner{ج}نوب
ج\ulineb{ن}وب
جن\ulinel{و}ب
جنو\ulinei{ب}

\hrulefill

\arbboxr{ج}نوب
ج\arbboxb{ن}وب
جن\arbboxl{و}ب
جنو\arbboxi{ب}

\tikzset{boxstyle/.append style={dashed,draw=blue,font=\bfseries,fill=green}}

\hrulefill

\arbboxr{ج}نوب
ج\arbboxb{ن}وب
جن\arbboxl{و}ب
جنو\arbboxi{ب}
    
\end{document}
 

enter image description here

Update 24/02/2020

I have created a command \FormatChar (thanks to @David Carlisle https://tex.stackexchange.com/a/529439/54817) you can apply any commands for a character in Arabic word, the command can also be used with xelatex.

\documentclass[a4paper,12pt,twoside]{book}

\usepackage [bidi=basic,layout=lists.tabular]{babel}
\babelprovide[import=ar,mapdigits,main]{arabic}

\babelfont{rm}{Amiri}

\usepackage{tikz}
\usepackage{ulem}

\def\connecti{i}
\def\connectr{r}
\def\connectl{l}
\def\connectb{b}

\makeatletter
\def\FormatChar#1#2#3#4{%
\let\joineri\@firstofone%
\let\joinerii\@firstofone%
\def\formatcs{#1}%
\def\temp{#3}%
\if\temp\connectb%
\else
 \if\temp\connectr%
 \let\joinerii\@gobble%
 \else
   \if\temp\connectl%
   \let\joineri\@gobble%
   \else    
      \if\temp\connecti%
      \let\joineri\@gobble\let\joinerii\@gobble%
      \else
      \@latex@error
      {\temp is not available for contextual forms}
      \fi%
   \fi%
 \fi%   
\fi%
\xFormatChar{#2}#4}%
\def\xFormatChar#1#2{\ifnum#1=1\joineri{^^^^200d}%
\formatcs{\joineri{^^^^200d}#2\joinerii{^^^^200d}}%
\joinerii{^^^^200d}\expandafter\@gobbletwo%
    \else#2\fi\xFormatChar{\numexpr#1-1\relax}}
\makeatother
    
\tikzset{charboxstyle/.style={draw=red,inner sep=0pt,fill=yellow}}
    
\newcommand{\charbox}[1]{%
\tikz[baseline=(x.base)]\node(x)[charboxstyle]{#1};%
}

\begin{document}

%\FormatChar{#1}{#2}{#3}{#4} 
% #1: Command
% #2: Position of char (number)
% #3: Contextual forms r , l , b , i
% #4: Word
    
\Huge

\FormatChar{\uline}{1}{l}
{جنوب}
%
\FormatChar{\textcolor{blue}}{2}{b}
{جنوب}
%
\FormatChar{\textcolor{red}}{3}{r}
{جنوب}
%
\FormatChar{\charbox}{4}{i}
{جنوب}
%
\tikzset{charboxstyle/.append style={dashed,draw=blue,fill=green,text=orange}}
%
\FormatChar{\charbox}{1}{l}
{جنوب}

\end{document}

enter image description here

Update 28/02/2020

For multiple letters macro \FormatChars can be used (thanks to @egreg https://tex.stackexchange.com/a/529602/54817 )

\documentclass{article}
\usepackage{tikz}
\usepackage{xparse}
\usepackage{ulem}
\usepackage [bidi=basic]{babel}
\babelprovide[import=ar,main]{arabic}

\babelfont{rm}{Amiri}
    
\tikzset{charboxstyle/.style={draw=red,inner sep=0pt,fill=yellow}}

\newcommand{\charbox}[1]{%
\tikz[baseline=(x.base)]\node(x)[charboxstyle]{#1};%
}

\ExplSyntaxOn

\NewDocumentCommand{\FormatChars}{m >{\SplitArgument{1}{-}}m O{i} m}
 {
  \cs_set_nopar:Npn \inputcs { #1 }
  \cs_set_nopar:Npn \joinb {^^^^200d}
  \cs_set_nopar:Npn \joine {^^^^200d}
  \str_case:nnF { #3 }
   {
    { i } { \let\joinb\relax\let\joine\relax }
    { r } { \let\joine\relax }
    { l } { \let\joinb\relax }
    { b } { }
   }
   {
  \msg_error:nn {}{#2~is~not~available~for~contextual~forms,~try~with~r,~l,~or~b} 
   } 
      % #2 is passed as two braced arguments
  \_FormatChars:nnn #2 { #4 }
 }

\cs_new_protected:Nn \_FormatChars:nnn
 {
  % let's analyze the first two args
  \tl_if_novalue:nTF { #2 }
   {% no hyphen in the argument
    \___FormatChars:nnn { #1 } { #1 } { #3 }
   }
   {
    \bool_lazy_or:nnTF { \tl_if_blank_p:n { #1 } } { \tl_if_blank_p:n { #2 } }
     {% argument is -n or m- or -
      \tl_if_blank:nTF { #1 }
       {
        \tl_if_blank:nTF { #2 }
         {% argument is -
          \joinb\inputcs{\joinb #3\joine}\joine
         }
         {% argument is -n
          \___FormatChars:nnn { 1 } { #2 } { #3 }
         }
       }
       {% argument is m-
        \___FormatChars:nnn { #1 } { -1 } { #3 }
       }
     }
     {% argument is m-n
      \___FormatChars:nnn { #1 } { #2 } { #3 }
     }
   }
 }

\cs_new_protected:Nn \___FormatChars:nnn
 {
  \int_compare:nTF { #1 > #2 > 0 }
   {
    #3
   }
   {
    \tl_range:nnn { #3 } { 1 } { #1 - 1 }
    \joinb\inputcs{\joinb \tl_range:nnn { #3 } { #1 } { #2 }\joine }\joine
    \tl_range:nnn { #3 } { #2 + 1 } { -1 }
   }
 }

\ExplSyntaxOff


\begin{document}

%\FormatChars{#1}{#2}[#3]{#4} 

% #1  : command to apply on range ex : \uline 
% #2  : range of letters ex : 2-6
% #3  : type of connection : i , r , l , b (default i)
% #4  : word    

\Huge

\FormatChars{\uline}{1-3}
{جنوب}
%
\FormatChars{\textcolor{blue}}{2-3}[r]
{جنوب}
%
\FormatChars{\textcolor{red}}{2-}[r]
{جنوب}
%
\FormatChars{\charbox}{4}
{جنوب}
%
\tikzset{charboxstyle/.append style={draw=blue,fill=black,text=white}}
%
\FormatChars{\charbox}{-2}[l]
{جنوب}

\end{document}

enter image description here


EDIT: I added below a rather primitive approach for drawing frames. Then, in the document itself, I added the invisible ^^^^200d mark at the appropriate places.

Not an answer, but only a suggestion. In my opinion, coloring the glyphs is the way to go in Arabic typographically speaking. Underlining may also be considered.

\documentclass[12pt]{article}

\usepackage[novoc]{arabluatex}

\newcommand{\ulinel}[1]{^^^^200d\uline{^^^^200d#1}}
\newcommand{\uliner}[1]{\uline{#1^^^^200d}^^^^200d}
\newcommand{\ulineb}[1]{^^^^200d\uline{^^^^200d#1^^^^200d}^^^^200d}

\NewDocumentCommand{\arbbox}{O{white} O{white} m}{%
  \fboxsep=0pt%
  \fcolorbox{#1}{#2}{#3}%
}

\begin{document}

\begin{arab}
  ^ganUb
  ^gan\arbcolor[blue]{U}b
  ^gan\ulinel{U}b
  ^ga\ulineb{n}Ub
  ^gan‍\arbbox[red][yellow]{‍U}b
\end{arab}

\end{document}

enter image description here

Tags:

Arabic