I've developed a catcode with the help of this answer to make some characters of Devanagari script active. I want to redefine characters of Devanagari script as active characters, to result in a different script i.e. IPA (International Phonetic Alphabet). This question cannot be complete without some explanation of orthographic conventions in Devanagari. Forgive me if I go very long.

Devanagari script use diacritics to denote vowels which are following a consonant. eg. If we want to write 'pa' (like in 'pardon') in Devanagari it will be written in two distinct units. Consonant character for 'p' sound and the vowel diacritic for 'a' sound. i.e. प + ा = पा and full vowel signs are used where they are not preceded by consonant sounds. (Like in case of alike, into). Interestingly there is no separate diacritic to show vowel 'अ' if preceded by a consonant which sounds like the vowel sounds in words run, sun. According to the rules every sign by default has an 'अ' vowel in it. If we want to denote the absence of a vowel sound, a different diacritic is attached universally to any consonant. It looks like . eg. If 'p' sound is not followed by any vowel, it is written as प्. So to maintain the orthographic convention and phonetics at the same time I need to add two IPA characters for one Devanagari active character.

I had to explain this, because now the problem will be more clear. I want to transliterate Devanagari into IPA. In that script vowel अ is denoted by ə sign which is evident in my catcode given below. While writing the definitions of the consonant sounds, I've added 'ə' symbol by default. The toughest part which I find is whether I can make this diacritic 'active' like the others and define it in such a way that it would eliminate the default vowel character 'ə' in the definition of the preceding consonant?

\protected\def क{\bgroup\doulo k\futurelet\tmp\viramacheck}
\protected\def ख{\bgroup\doulo kʰ\futurelet\tmp\viramacheck}
\protected\def ग{\bgroup\doulo g\futurelet\tmp\viramacheck}
\protected\def घ{\bgroup\doulo gʱ\futurelet\tmp\viramacheck}
\protected\def ङ{\bgroup\doulo ŋ\futurelet\tmp\viramacheck}
\protected\def च{\bgroup\doulo t͡ʃ\futurelet\tmp\viramacheck}
\protected\def छ{\bgroup\doulo t͡ʃʰ\futurelet\tmp\viramacheck}
\protected\def ज{\bgroup\doulo d͡ʒ\futurelet\tmp\viramacheck}
\protected\def झ{\bgroup\doulo d͡ʒʱ\futurelet\tmp\viramacheck}
\protected\def ञ{\bgroup\doulo ɲ\futurelet\tmp\viramacheck}
\protected\def ट{\bgroup\doulo ʈ\futurelet\tmp\viramacheck}
\protected\def ठ{\bgroup\doulo ʈʰ\futurelet\tmp\viramacheck}
\protected\def ड{\bgroup\doulo ɖ\futurelet\tmp\viramacheck}
\protected\def ढ{\bgroup\doulo ɖʱ\futurelet\tmp\viramacheck}
\protected\def ण{\bgroup\doulo ɳ\futurelet\tmp\viramacheck}
\protected\def त{\bgroup\doulo t̪\futurelet\tmp\viramacheck}
\protected\def थ{\bgroup\doulo t̪ʰ\futurelet\tmp\viramacheck}
\protected\def द{\bgroup\doulo d̪\futurelet\tmp\viramacheck}
\protected\def ध{\bgroup\doulo d̪ʱ\futurelet\tmp\viramacheck}
\protected\def न{\bgroup\doulo n̪\futurelet\tmp\viramacheck}
\protected\def प{\bgroup\doulo p\futurelet\tmp\viramacheck}
\protected\def फ{\bgroup\doulo pʰ\futurelet\tmp\viramacheck}
\protected\def ब{\bgroup\doulo b\futurelet\tmp\viramacheck}
\protected\def भ{\bgroup\doulo bʱ\futurelet\tmp\viramacheck}
\protected\def म{\bgroup\doulo m\futurelet\tmp\viramacheck}
\protected\def य{\bgroup\doulo j\futurelet\tmp\viramacheck}
\protected\def र{\bgroup\doulo ɾ\futurelet\tmp\viramacheck}
\protected\def ल{\bgroup\doulo l\futurelet\tmp\viramacheck}
\protected\def व{\bgroup\doulo w\futurelet\tmp\viramacheck}
\protected\def श{\bgroup\doulo ʃ\futurelet\tmp\viramacheck}
\protected\def ष{\bgroup\doulo ʂ\futurelet\tmp\viramacheck}
\protected\def स{\bgroup\doulo s\futurelet\tmp\viramacheck}
\protected\def ह{\bgroup\doulo h\futurelet\tmp\viramacheck}
\protected\def ळ{\bgroup\doulo ɭ\futurelet\tmp\viramacheck}

\protected\def अ{\bgroup\doulo ə}
\protected\def ा{\bgroup\doulo a}
\protected\def आ{\bgroup\doulo a}
\protected\def ि{\bgroup\doulo i}
\protected\def इ{\bgroup\doulo i}
\protected\def ी{\bgroup\doulo iː}
\protected\def ई{\bgroup\doulo iː}
\protected\def ु{\bgroup\doulo u}
\protected\def उ{\bgroup\doulo u}
\protected\def ू{\bgroup\doulo uː}
\protected\def ऊ{\bgroup\doulo uː}
\protected\def े{\bgroup\doulo e}
\protected\def ए{\bgroup\doulo e}
\protected\def ै{\bgroup\doulo ə͡i}
\protected\def ऐ{\bgroup\doulo ə͡i}
\protected\def ो{\bgroup\doulo o}
\protected\def ओ{\bgroup\doulo o}
\protected\def ौ{\bgroup\doulo ə͡u}
\protected\def औ{\bgroup\doulo ə͡u}
\protected\def ं{\bgroup\doulo ũ}

\protected\def\viramacheck{\ifx\tmp ् \egroup\expandafter\@gobble\else ə\egroup\fi}

Here I've used the definitions given by David Carlisle. Now if I type -

शरद् कमळ् बघ्\\
अभय् नमन् कर्\\
मगन् लव्कर् पळ्\\

the output is

enter image description here

This is exactly what I expected. Great job! But now there are many other vowels too in Devanagari script. In the code provided you can check the vowels (after the comment %VOWELS). When the words with other vowels come, there is a problem. Let's see an example -

मी सकाळी उठून् एक् तास् धाव्तो\\
रात्री पेलाभर् दूध् प्यावे\\

This is shown as -

enter image description here

This is not the right way. When a vowel comes, the default 'ə' should go. In the definitions of vowels there should be one additional rule which can delete the 'ə' added by viramacheck which we have defined. This is how it should look. (I have manually typed it using a different keyboard.) -

enter image description here

  • note that a catcode is simply a number (you are just using 13, denoted equivalently by \active) there is no special catcode processing, after making a character active it acts in the same way as a normal macro, as if preceded by \ . Your question would be clearer (for those of us who can not read the script) if you showed a complete example input phrase and the required typeset transliteration. In general it is hard to redefine combining characters in tex as you can not "go back" it would be easier in luatex if that is a possibility. Jul 1, 2019 at 20:08
  • I have added one example.
    – Niranjan
    Jul 2, 2019 at 5:50
  • you are never closing the groups started by vowels, if you only need the ipa characters in that block you could simplify the code and just switch to th eipa font once at the start and then remove all the \bgroup \egroup and \ipafont commands. Jul 2, 2019 at 6:47
  • Sorry this is not clear to me. Please can you explain? I've no knowledge of TeX primitives. I am just doing all of this by reverse coding.
    – Niranjan
    Jul 2, 2019 at 7:03
  • I may try later, or someone who can read this script may answer:-) Jul 2, 2019 at 7:11

1 Answer 1


If I understand correctly you want something like

enter image description here

Where क looks ahead to add or not add ə depending if the virama combining character follows.


\setmainfont{Nirmala UI}


\protected\defक{\bgroup\ipafont k\futurelet\tmp\viramacheck}
\protected\def\viramacheck{\ifx\tmp ् \egroup\expandafter\@gobble\else ə\egroup\fi}





  • \protected\defक would be safer.
    – egreg
    Jul 1, 2019 at 21:49
  • @egreg yes, done Jul 1, 2019 at 21:57
  • Yes it worked. Thank you so much. I want to add two more if cases, it would be great if you could explain what the parts of this definition mean. I would like to try defining some conditions on my own.
    – Niranjan
    Jul 2, 2019 at 4:02

You must log in to answer this question.

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