Ligatures are known to the Western European languages, however it isn't that common to spot vertical or complex form of them. As an exercise in typography I tried to get some complex ligatures in Devanāgarī script.

I've downloaded the chandas.ttf file (Southern style; uttara.ttf would serve well as a test case) with complex ligatures in it as well as the Sanskrit 2003 font which doesn't contain complex ligatures to show common form of writing.

I've opened the font in FontForge where we can see those ligatures and their names. Ligatures are properly mapped, so we can use them. I only changed some letters to fit transliteration schemes: Y as nj or J, G as ng and I am using Lexilogos and Sanscript to get the portion of words.

a preview of complex ligatures in FontForge

Note: In case you are wondering what I am trying to achieve I can say that I try to convert transliterated words sorted in Xindy (Sanskrit, Pāḷi, hopefully even Tamiḻ and Siṇhala later) and I am checking what options I have to display index entries. As mapping is not supported in LuaTeX, I am trying to prepare standalone Lua scripts which will replace Latin letters.

In theory, I have two problems now:

1) How to turn off those complex ligatures locally in document and how to get regular form of writing, if needed? To preview a common form I used different font in the example below. After using otfinfo -f chandas.ttf we know there are three features, but it is not helping if we turn them off.

2) How to get complex ligatures in LuaLaTeX? As far as I know the support for Indic languages is very limited. Under normal circumstances I am using \char to get a specific glyph, but those complex ligatures are not mapped as Unicode glyphs in the private use areas (PUA). I would be able to use \XeTeXglyph and the glyph's slot, but it is not easy as well. FontForge is showing 3417 (0x0D59) for DNjYa glyph, but the actual position got from XeTeX (\the\XeTeXglyphindex"DNjYa") is 2510 (0x09CE). What a day!

A bonus. There is even more fun, if we try to get two complex ligatures next to each other (I cannot say if it is correct linguistically, it is not almost certainly), e.g. DNjJ+DNjJa, the middle letters form ligature earlier while typing it. The solution is to use \mbox{}, see the last line in the example.

I enclose an example and a preview of my efforts. We can run xelatex and lualatex. If you are interested, an encoding table can be obtained from http://www.sanskritweb.net/cakram/chandas-encoding.pdf and a preview of all ligatures from http://www.sanskritweb.net/cakram/saMyoga-pattra.pdf

% run: xelatex or lualatex mal-sanskrit.tex
% Possible addtion for LuaLaTeX (1 line):
% Possible addition for XeLaTeX (3 lines):
Correct form in Xe\LaTeX, incorrect in Lua\LaTeX\ (2 lines):\par
ड्ण्ज्ञ​ (common form; using different font [Sanskrit2003.ttf])\par % ड्ण्ज्ञ
ड्ण्ज्ञ​ (glyph DNjYa; DNjnja [Lexilogos] or DNjJa [Harvard-Kyoto])\par\medskip
  % Y as nj or J, G as ng
ड्ण्ज्ञ​ (a form of ligature; Devanāgarī script)\par
ड्ण्ज्ञ​ (incorrect form; Latin script)\par
ड्\mbox{}ण्\mbox{}ज्ञ​ (incorrect form; separated glyphs, \verb.\mbox.)\par\medskip
3417 as \XeTeXglyph"0D59\ versus % 3417
\the\XeTeXglyphindex"DNjYa"\ as % 2510
\XeTeXglyph2510\ or\ \XeTeXglyph"09CE\ (getting slot number)\par
ड्ण्ज्ञ्ड्ण्ज्ञ / ड्ण्ज्ञ्\mbox{}ड्ण्ज्ञ (DNjJ DNjJa)

output from xelatex

output from lualatex

  • I will confess up front to having no particular knowledge of the exigencies of the writing systems you're dealing with. That said, if you work with Lua(La)TeX you could try using the selnolig package to suppress certain ligatures on either a document-wide or a more limited scale. The package currently onlz provides rules to suppress ligatures selectively for English and German documents. However, it should be adaptable to any writing system.
    – Mico
    Commented May 6, 2014 at 9:13
  • @Mico Thank you for your feedback! I'd love to test it, but I am not getting those complex ligatures in LuaLaTeX at the moment. I am one step behind.
    – Malipivo
    Commented May 6, 2014 at 9:17
  • 9
    While your question subjects are often quite esoteric, relevant for only a narrow segment of the general TeX population, I am always impressed at their depth and even more so at the difficulties faced by people who work in a multilingual typesetting environment. +1 Commented May 6, 2014 at 10:09
  • @StevenB.Segletes Thank you for your comment! I am new in those areas/languages, well, the problems are challenges.
    – Malipivo
    Commented May 6, 2014 at 12:04
  • 5
    Many of these consonant clusters never occur in Sanskrit (some I doubt are even pronounceable), so it's better to stick to ligatures that actually occur in the language. These are also the ones the font designers are likely to have spent effort on (if they were choosing wisely). Commented May 3, 2015 at 16:44

1 Answer 1


It may be the meaning(s) of the term 'ligature' could be the driver behind the question.

This is a comment with images, so not an answer. The original post (also not an answer, more of an observation) is kept down below, for continuity.

Assuming the question is about indexing transliterated content, then there is a method that involves no decomposition of displayed material.

A string of glyphs is given to a renderer, and the renderer displays it appropriately. The string of glyphs remains available, though, so reverting the display back into its input is not required.

For example, to explore the structure of the orthography, the string संयुक्त व्यंजन, which is what Google returns when "conjunct consonants in Hindi" is entered (and which Google transliterates the pronunciation of as "sanyukt vyanjan"), can be transliterated on a glyph-by-glyph basis as:

saṇya̺uka̺ta va̺yaṇjana

glyphs transliteration

using a mapping methodology whereby the inherent 'a' vowel attached to each consonant is shown, and also shown where it is switched off by the orthography rules:

  • before another vowel
  • in between two consonants where it is not needed
  • at the end of a word

Here, arbitrarily, the inverted under-bridge combining diacritical mark is being used (via a font mapping file) as a visual representation of the switched-off vowel in the first two cases.

The \index command can then take this transliteration string, like any other string, and do its usual work:

indexing example


\setmainfont[Script=Devanagari]{Noto Serif Devanagari}
\newfontface\translitd[Mapping=devanagari-to-latin,Scale=1.1,Colour=red]{Noto Sans}
\newfontfamily\englishfont{Noto Serif}

संयुक्त व्यंजन
{\normalsize\textenglish{sanyukt vyanjan}}

{\translitd संयुक्त}\index{{\translitd संयुक्त}}
{\translitd व्यंजन}\index{{\translitd व्यंजन}}


'.map' file, to compile into a '.tec' file with teckit_compile.exe:

; TECkit mapping for TeX input conventions <-> Unicode characters

LHSName "devanagari-to-latin"


; ligatures from Knuth's original CMR fonts
U+002D U+002D           <>  U+2013  ; -- -> en dash
U+002D U+002D U+002D    <>  U+2014  ; --- -> em dash

U+0027          <>  U+2019  ; ' -> right single quote
U+0027 U+0027   <>  U+201D  ; '' -> right double quote
U+0022           >  U+201D  ; " -> right double quote

U+0060          <>  U+2018  ; ` -> left single quote
U+0060 U+0060   <>  U+201C  ; `` -> left double quote

U+0021 U+0060   <>  U+00A1  ; !` -> inverted exclam
U+003F U+0060   <>  U+00BF  ; ?` -> inverted question

; additions supported in T1 encoding
U+002C U+002C   <>  U+201E  ; ,, -> DOUBLE LOW-9 QUOTATION MARK
U+003C U+003C   <>  U+00AB  ; << -> LEFT POINTING GUILLEMET
U+003E U+003E   <>  U+00BB  ; >> -> RIGHT POINTING GUILLEMET

U+0924 <> U+0074 U+0061 ;  ta 
U+094D <> U+033A ; strikeout previous
U+0915 <> U+006B U+0061 ; ka
U+0941 <> U+033A U+0075 ; -u
U+092F <> U+0079 U+0061 ; ya
U+0902 <> U+006E U+0323 ; n.
U+0938 <> U+0073 U+0061 ; sa
U+0928 <> U+006E U+0061 ; na
U+091C <> U+006A U+0061 ; ja
U+0935 <> U+0076 U+0061 ; va

I would ordinarily expect the reader to want a 'normal' index, as well. Something like:

normal index


Original post

Looks OK for normal words (in xelatex and in the browser), if I have not misunderstood the question.


Since lualatex does not do conjunct consonants in the first place, there is no need to 'de-ligature' them to create the index entries.

For indexing by (automated) transliteration, again, xelatex is easier, using a font-map (or l3 regex replace).

\setmainfont[Script=Devanagari]{Noto Serif Devanagari}
\newfontfamily\englishfont{Noto Serif}

संयुक्त व्यंजन

{\normalsize\textenglish{sanyukt vyanjan}}

\noindent   शुक्ल ख्मेर मुख्य अंग्रेज़ी \\ 
    अच्छा छुट्टी ठ्रेइन बुद्ध विद्यार्थी

\noindent {\normalsize\textenglish{shukla khmer mukhya angrezî \\ achchhâ chhuTTî trein buddha vidyârthî}

ल् +    म = ल्म     फ़िल्म  \textenglish{film}

Test words from https://en.wikibooks.org/wiki/Hindi/Consonant_combinations

  • I think this is not the question — my understanding of the question is that it asks how to disable conjuncts in xelatex and get the weird/unnatural form without ligatures (which no one except the OP apparently wants). Commented Oct 6, 2019 at 13:11
  • @ShreevatsaR Oh. I thought the base question was how to eventually index transliterated forms based on disabling conjuncts with lua code, but the first step of getting conjuncts in lualatex wasn't working (actually, I found inserting a space between characters reverts them to 'raw' form in a utf-8 editor, so that could be one method for lua-indexing - but a regex might be easier; manual indexing is best, though, in the long run).
    – Cicada
    Commented Oct 6, 2019 at 13:48
  • Your interpretation may be right (about the motivation behind the question), because otherwise what the OP wants (as asked in the question) seems really weird. :-) Commented Oct 6, 2019 at 14:05

You must log in to answer this question.

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