%% %% This is file `xepersian-hm.sty', %% generated with the docstrip utility. %% %% The original source files were: %% %% xepersian-hm.dtx (with options: `xepersian-hm-sty') %% %% Copyright (C) 2020 Hossein Movahhedian %% %% It may be distributed and/or modified under the LaTeX Project Public License, %% version 1.3c or higher (your choice). The latest version of %% this license is at: http://www.latex-project.org/lppl.txt %% \NeedsTeXFormat{LaTeX2e} \RequirePackage{expl3}[2020-03-06] \@ifpackagelater{expl3}{2020-03-06} {} {% \PackageError{xepersian-hm}{Support package l3kernel too old} {% Please install an up to date version of l3kernel\MessageBreak using your TeX package manager or from CTAN.\MessageBreak \MessageBreak Loading xtemplate will abort!% }% \endinput } \RequirePackage{l3keys2e} \RequirePackage{graphicx}[2019-11-30] \RequirePackage{zref-savepos}[2020-03-03] \RequirePackage{xcolor}[2016/05/11] \RequirePackage{xepersian} \ProvidesExplPackage {xepersian-hm} {2020-09-04} {1.1a} { Fixes~issues~in~xepersian~package } \def\XePersianHM{XePersianHM} \box_new:N \l_xephm_ksh_box \int_const:Nn \c_xephm_ksh_int {"0640} % kashida \int_const:Nn \c_xephm_lrm_int {"200E} % left-right-mark \int_const:Nn \c_xephm_zwj_int {"200D} % zero-width joiner \int_const:Nn \c_xephm_two_int {2} \int_const:Nn \c_xephm_four_int {4} \tl_const:Nn \c_xephm_skip_a_tl { 0 em plus 0.5 em } \tl_const:Nn \c_xephm_skip_b_tl { 0.14 em plus 5.5 em } \int_new:N \l_xephm_counter_int \int_new:N \l_xephm_kashida_slot_int \int_new:N \l_xephm_line_break_penalty_int \int_new:N \l_xephm_min_penalty_int \int_new:N \l_xephm_low_penalty_int \int_new:N \l_xephm_med_penalty_int \int_new:N \l_xephm_high_penalty_int \int_new:N \l_xephm_max_penalty_int \tl_new:N \l_xephm_line_break_tl \tl_new:N \l_xephm_main_font_full_tl \tl_new:N \l_xephm_main_font_name_tl \tl_new:N \l_xephm_font_full_tl \tl_new:N \l_xephm_font_name_tl \tl_new:N \l_xephm_skip_default_tl \tl_new:N \l_xephm_active_ligs_tl \tl_new:N \l_xephm_gap_filler_tl \tl_new:N \l_xephm_use_color_tl \tl_new:N \l_xephm_color_tl \tl_new:N \l_xephm_color_rgb_tl \dim_new:N \l_xephm_diff_pos_dim \bool_set_false:N \l_xephm_kashida_fix_bool \bool_set_false:N \l_xephm_ligature_bool \bool_set_false:N \l_xephm_linebreakpenalty_bool \bool_set_false:N \l_xephm_color_bool \int_set:Nn \l_xephm_min_penalty_int { 0 } \int_set:Nn \l_xephm_low_penalty_int { 8 } \int_set:Nn \l_xephm_med_penalty_int { 15 } \int_set:Nn \l_xephm_high_penalty_int { 25 } \int_set:Nn \l_xephm_max_penalty_int { 10000 } \tl_set:Nn \l_xephm_stretch_glyph_tl { glyph } \tl_set:Nn \l_xephm_stretch_leaders_glyph_tl { leaders+glyph } \tl_set:Nn \l_xephm_stretch_leaders_hrule_tl { leaders+hrule } \tl_set:Nn \l_xephm_stretch_off_tl { Off } \tl_set:Nn \l_xephm_stretch_on_tl { On } \tl_set:Nn \l_xephm_fnt_kayhan_tl { kayhan } \tl_set:Nn \l_xephm_fnt_kayhannavaar_tl { kayhannavaar } \tl_set:Nn \l_xephm_fnt_kayhanpook_tl { kayhanpook } \tl_set:Nn \l_xephm_fnt_kayhansayeh_tl { kayhansayeh } \tl_set:Nn \l_xephm_fnt_khoramshahr_tl { khoramshahr } \tl_set:Nn \l_xephm_fnt_khorramshahr_tl { khorramshahr } \tl_set:Nn \l_xephm_fnt_niloofar_tl { niloofar } \tl_set:Nn \l_xephm_fnt_paatch_tl { paatch } \tl_set:Nn \l_xephm_fnt_riyaz_tl { riyaz } \tl_set:Nn \l_xephm_fnt_roya_tl { roya } \tl_set:Nn \l_xephm_fnt_shafigh_tl { shafigh } \tl_set:Nn \l_xephm_fnt_shafighKurd_tl { shafighKurd } \tl_set:Nn \l_xephm_fnt_shafighUzbek_tl { shafighUzbek } \tl_set:Nn \l_xephm_fnt_shiraz_tl { shiraz } \tl_set:Nn \l_xephm_fnt_sols_tl { sols } \tl_set:Nn \l_xephm_fnt_tabriz_tl { tabriz } \tl_set:Nn \l_xephm_fnt_titr_tl { titr } \tl_set:Nn \l_xephm_fnt_titre_tl { titre } \tl_set:Nn \l_xephm_fnt_traffic_tl { traffic } \tl_set:Nn \l_xephm_fnt_vahid_tl { vahid } \tl_set:Nn \l_xephm_fnt_vosta_tl { vosta } \tl_set:Nn \l_xephm_fnt_yaghut_tl { yaghut } \tl_set:Nn \l_xephm_fnt_yagut_tl { yagut } \tl_set:Nn \l_xephm_fnt_yas_tl { yas } \tl_set:Nn \l_xephm_fnt_yekan_tl { yekan } \tl_set:Nn \l_xephm_fnt_yermook_tl { yermook } \tl_set:Nn \l_xephm_fnt_zar_tl { zar } \tl_set:Nn \l_xephm_fnt_ziba_tl { ziba } \tl_set:Nn \l_xephm_fnt_default_tl { default } \tl_set:Nn \l_xephm_fnt_noskip_tl { noskip } \tl_set:Nn \l_xephm_lig_aalt_tl { aalt } % Access All Alternatives \tl_set:Nn \l_xephm_lig_ccmp_tl { ccmp } % Glyph Composition/Decomposition \tl_set:Nn \l_xephm_lig_dlig_tl { dlig } % Discretionary Ligatures \tl_set:Nn \l_xephm_lig_fina_tl { fina } % Final (Terminal) Forms \tl_set:Nn \l_xephm_lig_init_tl { init } % Initial Forms \tl_set:Nn \l_xephm_lig_locl_tl { locl } % Localized Forms \tl_set:Nn \l_xephm_lig_medi_tl { medi } % Medial Forms \tl_set:Nn \l_xephm_lig_rlig_tl { rlig } % Required Ligatures \tl_set:Nn \l_xephm_lig_default_tl { default } \tl_set:Nn \l_xephm_col_default_tl { magenta } \clist_set:Nn \l_xephm_lig_aalt_clist { } % Access All Alternatives \clist_set:Nn \l_xephm_lig_ccmp_clist { } % Glyph Composition/Decomposition \clist_set:Nn \l_xephm_lig_dlig_clist { FDF2 = الله , FDF3 = اکبر , FDFB = جلجلاله } % Discretionary Ligatures \clist_set:Nn \l_xephm_lig_fina_clist { } % Final (Terminal) Forms \clist_set:Nn \l_xephm_lig_init_clist { } % Initial Forms \clist_set:Nn \l_xephm_lig_locl_clist { } % Localized Forms \clist_set:Nn \l_xephm_lig_medi_clist { } % Medial Forms \clist_set:Nn \l_xephm_lig_rlig_clist { } % Required Ligatures \clist_set:Nn \l_xephm_lig_default_clist { } \clist_set:Nn \l_xephm_lig_names_clist { \l_xephm_lig_aalt_tl , { \l_xephm_lig_aalt_clist } , \l_xephm_lig_ccmp_tl , { \l_xephm_lig_ccmp_clist } , \l_xephm_lig_dlig_tl , { \l_xephm_lig_dlig_clist } , \l_xephm_lig_fina_tl , { \l_xephm_lig_fina_clist } , \l_xephm_lig_init_tl , { \l_xephm_lig_init_clist } , \l_xephm_lig_locl_tl , { \l_xephm_lig_locl_clist } , \l_xephm_lig_medi_tl , { \l_xephm_lig_medi_clist } , \l_xephm_lig_rlig_tl , { \l_xephm_lig_rlig_clist } , } \msg_new:nnn { xepersian-hm } { error-kashida-character-is-not-available-in-the-main-font } { Sorry,~ kashida~ character~ is~ not~ available~ in~ the~ main~ font~#1! } \msg_new:nnn { xepersian-hm } { error-value-not-available-for-kashida-option } { Sorry,~ value~ `#1'~ is~ not~ available~ for~ `Kashida'~ option~ yet~! } \msg_new:nnn { xepersian-hm } { error-specify-value-for-kashida-option } { Sorry,~ you~ must~ specify~ a~ value~ for~ `Kashida'~ option~ yet~! } \msg_new:nnn { xepersian-hm } { warning-experimental-feature } { Please~ note~ that~ the~ feature~ `#1'~ is~ still~ experimental~ and~ is~ not~ regarded~ as~ stable. } \msg_new:nnn { xepersian-hm } { hm-series-font-not-found } { Either~ the~ font~`#1'~ is~ not~ installed~ on~ your~ system~ or~ does~ not~ belong~ to~ HM~Series~fonts.~ Please~ note~ that~ the~ option~ `Kashida=leaders+glyph'~ is~ currently~ only~ supported~ by~ HM~Series~fonts.~ If~ you~ know~ of~ any~ other~ font~ that~ supports~ this~ option,~ please~ let~ me~ know~ to~ add~ it~ to~ the~ list~ of~ corresponding~ fonts.~ } \keys_define:nn { xepersian-hm } { Kashida .code:n = { \tl_set:Nn \l_tmpa_tl { #1 } \tl_case:NnTF \l_tmpa_tl { \l_xephm_stretch_glyph_tl { \msg_warning:nnn { xepersian-hm } { warning-experimental-feature } { Kashida=glyph } \tl_set:Nx \l_xephm_gap_filler_tl { \l_xephm_stretch_glyph_tl } \AtBeginDocument { \tl_set:Nx \l_xephm_main_font_full_tl { \tex_fontname:D \tex_the:D \tex_font:D } \tl_set:Nx \l_xephm_main_font_name_tl { \l_xephm_main_font_full_tl } \regex_replace_once:nnN { ^"([^/]+)/.* } { \1 } \l_xephm_main_font_name_tl } \bool_set_true:N \l_xephm_kashida_fix_bool } \l_xephm_stretch_leaders_glyph_tl { \tl_set:Nx \l_xephm_gap_filler_tl { \l_xephm_stretch_leaders_glyph_tl } \bool_set_true:N \l_xephm_kashida_fix_bool } \l_xephm_stretch_leaders_hrule_tl { \tl_set:Nx \l_xephm_gap_filler_tl { \l_xephm_stretch_leaders_hrule_tl } \bool_set_true:N \l_xephm_kashida_fix_bool } \l_xephm_stretch_off_tl { \tl_set:Nx \l_xephm_gap_filler_tl { \l_xephm_stretch_off_tl } \bool_set_false:N \l_xephm_kashida_fix_bool } \l_xephm_stretch_on_tl { \tl_set:Nx \l_xephm_gap_filler_tl { \l_xephm_stretch_leaders_glyph_tl } \bool_set_true:N \l_xephm_kashida_fix_bool } } { } { \tl_set:Nx \l_xephm_gap_filler_tl { #1 } } \tl_if_empty:NT \l_xephm_gap_filler_tl { \msg_error:nn { xepersian-hm } { error-specify-value-for-kashida-option } } } , linebreakpenalty .code:n = { \int_set:Nn \l_tmpa_int { #1 } \int_case:nnTF \l_tmpa_int { \l_xephm_min_penalty_int { \int_set:Nn \l_xephm_line_break_penalty_int { \l_xephm_min_penalty_int } } \l_xephm_low_penalty_int { \int_set:Nn \l_xephm_line_break_penalty_int { \l_xephm_low_penalty_int } } \l_xephm_med_penalty_int { \int_set:Nn \l_xephm_line_break_penalty_int { \l_xephm_med_penalty_int } } \l_xephm_high_penalty_int { \int_set:Nn \l_xephm_line_break_penalty_int { \l_xephm_high_penalty_int } } \l_xephm_max_penalty_int { \int_set:Nn \l_xephm_line_break_penalty_int { \l_xephm_max_penalty_int } } } { } { \int_set:Nn \l_xephm_line_break_penalty_int { #1 } } \bool_set_true:N \l_xephm_linebreakpenalty_bool } , kashidastretch .code:n = { \tl_set:Nn \l_tmpa_tl { #1 } \tl_case:NnTF \l_tmpa_tl { \l_xephm_fnt_kayhan_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.14 em plus 0.5 em } } \l_xephm_fnt_kayhannavaar_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.129 em plus 0.5 em } } \l_xephm_fnt_kayhanpook_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.133 em plus 0.5 em } } \l_xephm_fnt_kayhansayeh_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.135 em plus 0.5 em } } \l_xephm_fnt_khoramshahr_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.128 em plus 0.5 em } } \l_xephm_fnt_khorramshahr_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.13 em plus 0.5 em } } \l_xephm_fnt_niloofar_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.132 em plus 0.5 em } } \l_xephm_fnt_paatch_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.127 em plus 0.5 em } } \l_xephm_fnt_riyaz_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.125 em plus 0.5 em } } \l_xephm_fnt_roya_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.142 em plus 0.5 em } } \l_xephm_fnt_shafigh_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.143 em plus 0.5 em } } \l_xephm_fnt_shafighKurd_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.126 em plus 0.5 em } } \l_xephm_fnt_shafighUzbek_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.123 em plus 0.5 em } } \l_xephm_fnt_shiraz_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.122 em plus 0.5 em } } \l_xephm_fnt_sols_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.124 em plus 0.5 em } } \l_xephm_fnt_tabriz_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.119 em plus 0.5 em } } \l_xephm_fnt_titr_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.12 em plus 0.5 em } } \l_xephm_fnt_titre_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.121 em plus 0.5 em } } \l_xephm_fnt_traffic_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.124 em plus 0.5 em } } \l_xephm_fnt_vahid_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.134 em plus 0.5 em } } \l_xephm_fnt_vosta_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.136 em plus 0.5 em } } \l_xephm_fnt_yaghut_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.138 em plus 0.5 em } } \l_xephm_fnt_yagut_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.137 em plus 0.5 em } } \l_xephm_fnt_yas_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.126 em plus 0.5 em } } \l_xephm_fnt_yekan_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.141 em plus 0.5 em } } \l_xephm_fnt_yermook_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.139 em plus 0.5 em } } \l_xephm_fnt_zar_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.116 em plus 0.5 em } } \l_xephm_fnt_ziba_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.119 em plus 0.5 em } } \l_xephm_fnt_default_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.14 em plus 0.5 em } } \l_xephm_fnt_noskip_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0 em plus 0.5 em } } } { } { \tl_set:Nn \l_xephm_skip_default_tl { #1 } } } , kashidastretch .default:n = \tl_set:Nn \l_xephm_skip_default_tl { 0 em plus 0.5 em } , ligatures .code:n = { \tl_set:Nn \l_tmpa_tl { #1 } \tl_case:NnTF \l_tmpa_tl { \l_xephm_lig_aalt_tl { \tl_set:Nx \l_xephm_active_ligs_tl { \l_xephm_lig_aalt_tl } } \l_xephm_lig_ccmp_tl { \tl_set:Nx \l_xephm_active_ligs_tl { \l_xephm_lig_ccmp_tl } } \l_xephm_lig_dlig_tl { \tl_set:Nx \l_xephm_active_ligs_tl { \l_xephm_lig_dlig_tl } } \l_xephm_lig_fina_tl { \tl_set:Nx \l_xephm_active_ligs_tl { \l_xephm_lig_fina_tl } } \l_xephm_lig_init_tl { \tl_set:Nx \l_xephm_active_ligs_tl { \l_xephm_lig_init_tl } } \l_xephm_lig_locl_tl { \tl_set:Nx \l_xephm_active_ligs_tl { \l_xephm_lig_locl_tl } } \l_xephm_lig_medi_tl { \tl_set:Nx \l_xephm_active_ligs_tl { \l_xephm_lig_medi_tl } } \l_xephm_lig_rlig_tl { \tl_set:Nx \l_xephm_active_ligs_tl { \l_xephm_lig_rlig_tl } } \l_xephm_lig_default_tl { \tl_set:Nx \l_xephm_active_ligs_tl { \l_xephm_lig_default_tl } } } { } { \tl_set:Nn \l_xephm_active_ligs_tl { #1 } } \bool_set_true:N \l_xephm_ligature_bool } , ligatures .default:n = \tl_set:Nn \l_xephm_active_ligs_tl { \l_xephm_lig_default_tl } , color .code:n = { \tl_set:Nn \l_tmpa_tl { #1 } \tl_if_empty:NTF \l_tmpa_tl { \tl_set:Nx \l_xephm_color_tl { \l_xephm_col_default_tl } } { \tl_set:Nx \l_xephm_color_tl { \l_tmpa_tl } } \bool_set_true:N \l_xephm_color_bool } , } \ProcessKeysOptions { xepersian-hm } \bool_if:NTF \l_xephm_kashida_fix_bool { \tex_input:D { xepersian-hm-kashida.tex } \NewDocumentCommand \KashidaHMFixOn {} { \bool_set_true:N \l_xephm_kashida_fix_bool } \NewDocumentCommand \KashidaHMFixOff {} { \bool_set_false:N \l_xephm_kashida_fix_bool } \tex_let:D \KashidaOn \KashidaHMFixOn \tex_let:D \KashidaOff \KashidaHMFixOff \tl_if_empty:NT \l_xephm_skip_default_tl { \tl_set:Nn \l_xephm_skip_default_tl { 0.14 em plus 0.5 em } } } { \tl_set:NV \l_xephm_skip_default_tl \c_xephm_skip_a_tl } \makeatletter \newif\if@Kashida@on %% Becuase Vafa Khalighi has copied the above code (injecting the character uni+200E) in xepersian-23.0 %% (https://tug.org/svn/texlive/trunk/Master/texmf-dist/tex/xelatex/xepersian/kashida-xepersian.def?revision=55165&view=co), %% the following line of code is not needed in xepersian anymore. %% % \newif\if@Kashida@XB@fix \makeatother \endinput %% %% %% End of file `xepersian-hm.sty'.