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}
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}
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}
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}
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}