Skip to main content

Technical Documentation

Conversion Methodology

Full algorithm documentation for our Krutidev-to-Unicode and Unicode-to-Krutidev converters. This page explains every step of the conversion process, including edge cases and known limitations.

By KrutiDevTools TeamLast updated:

Overview

Krutidev is a font-level encoding, not a character encoding. It stores Hindi text as ASCII characters that only render as Devanagari when the Krutidev font is active. Converting Krutidev to Unicode means replacing each ASCII character or character sequence with the corresponding Unicode Devanagari code point.

The conversion is a multi-phase process: character mapping, nukta normalization, matra repositioning, and reph handling. Each phase must execute in the correct order. Skipping or reordering phases produces incorrect output for any text containing chhoti i matra (ि) or reph (र्).

Phase 1: Character Mapping

The core of the conversion is a pair of parallel arrays: one containing Krutidev patterns (194 entries), the other containing the corresponding Unicode patterns. The converter iterates through the arrays and replaces every occurrence of each Krutidev pattern with its Unicode equivalent.

Array ordering is critical. The arrays are sorted so that longer patterns appear before shorter ones. Without this, "Fk" () would never be matched because "F" (थ्) appears earlier and consumes the "F" before the algorithm sees "Fk". Our arrays place multi-character entries like "Fk", "[k", "?k", "Hk", ".k", "/k", "vks", "vkS", "vk" before their single-character substrings.

The replacement loop for each pattern continues until no more instances exist in the text. This is necessary because some patterns can appear adjacent or overlapping in complex text. A single-pass replacement would miss instances created by prior replacements in the same iteration.

Phase 2: Nukta Normalization (Unicode to Krutidev only)

Unicode represents nukta characters (borrowed Urdu/Arabic sounds) in two ways: as a precomposed character (e.g., क़ = U+0958) or as a base character plus a combining nukta (e.g., + = U+0915 + U+093C). Both represent the same sound and should produce the same Krutidev output.

Before running the main mapping, we normalize all decomposed nukta sequences to their precomposed equivalents: + becomes क़, + becomes ख़, + becomes ग़, + becomes ज़, + becomes ड़, + becomes ढ़, + becomes फ़, + becomes य़. This ensures consistent matching in the mapping phase regardless of how the input was encoded.

Phase 3: Chhoti I Matra Repositioning

The chhoti i matra (ि, U+093F) is the most complex aspect of Krutidev conversion. In Unicode, matras come after their base consonant: कि = + ि. In Krutidev, the chhoti i matra is typed before the consonant: "f" (ि) + "d" () = "fd" which renders as "कि" in the font.

Krutidev to Unicode: After the main mapping, any remaining "f" characters are chhoti i matras that need repositioning. The algorithm finds each "f", takes the next character (the consonant), and swaps them: "fX" becomes "Xि". For consonant clusters with halant (e.g., "f" before a halant+consonant sequence), the "f" must move past the entire cluster, not just the adjacent character.

Unicode to Krutidev: The reverse operation moves ि from after the consonant to before it (as "f"). When the consonant has a preceding halant+consonant (a conjunct), the "f" must move to before the entire cluster, not just the immediate consonant.

Phase 4: Reph Handling

Reph is the half- that sits above the following consonant cluster: "र्म" (rma) shows above . In Unicode, reph is represented as + (ra + halant) before the base consonant. In Krutidev, reph is represented as "Z" placed after the base consonant and its matras.

Krutidev to Unicode: After all other processing, any remaining "Z" characters are reph markers. The algorithm finds each "Z", looks backward past any matras to find the base consonant, and moves the reph to before the consonant as "र्". The matra list used for backward scanning includes: ा ि ी ु ू ृ े ै ो ौ ं ँ ः ॅ.

Unicode to Krutidev: The reverse operation finds each "र्" (ra + halant), takes the following consonant and its matras, and places "Z" after the entire group.

Phase 5: Additional Special Cases

Several Krutidev characters require individual handling outside the main mapping:

  • Character Ç (0xC7): Maps to "fa" (chhoti i matra + anusvara). Requires the same repositioning as regular chhoti i matra but with an additional anusvara after the consonant.
  • Character É (0xC9): Maps to "र्fa" (reph + chhoti i matra + anusvara). Combines both reph and matra repositioning in a single character.
  • Character Ê (0xCA): Maps to "Z" (long i matra + reph). The reph repositioning phase handles the Z component.
  • Character ± (0xB1): Maps to "Z" (reph + anusvara). The anusvara stays in place while Z undergoes reph repositioning.
  • Character Æ (0xC6): Maps to "र्f" (reph + chhoti i matra). Both repositioning phases apply.

Known Limitations

No Krutidev converter is 100% accurate for all possible inputs. These are the known edge cases where our converter (and all existing converters) may produce imperfect output:

  • Rare conjuncts: Conjuncts not in the mapping table (e.g., some Vedic Sanskrit combinations) pass through unconverted. The mapping covers the 40+ most common Hindi conjuncts.
  • Mixed-language text: English words embedded in Krutidev text may be partially converted if they happen to contain character sequences that match Krutidev patterns. For mixed-language documents, we recommend reviewing the output to check that English words converted correctly.
  • Custom Krutidev variants: Some organizations have modified Krutidev fonts with custom character mappings. Our converter uses the standard Kruti Dev 010 mapping. Non-standard variants may produce incorrect output for their custom characters.
  • Nested reph+matra combinations: Extremely complex constructions with reph, chhoti i matra, and anusvara stacked on the same consonant cluster may occasionally produce incorrect character ordering. This affects fewer than 0.1% of real-world texts.

Comparison with Other Implementations

Most online Krutidev converters use the same fundamental algorithm: mapping arrays + special-case handling. The differences are in implementation quality:

  • Chunking: Some converters split input at 7,000 characters and process each chunk separately. This can break words that span chunk boundaries. Our implementation processes the full text without chunking.
  • Speed: Several converters require a round-trip to a server, adding latency. Our converter produces output instantly with no wait time.
  • Deprecated APIs: Some competitors use document.execCommand("copy") for clipboard access, which is deprecated and fails in modern browsers. We use the modern navigator.clipboard API with a fallback.

Related Pages

Frequently Asked Questions

Why does the order of replacement matter?
Because shorter patterns are substrings of longer ones. If you replace "d" () before "Dk" (), the "d" inside "Dk" gets replaced first, producing "k" instead of "". By processing "Dk" before "d", the two-character sequence is matched and replaced as a unit. Our arrays are sorted longest-first within each equivalence class to prevent these partial-match errors.
Does the converter handle all Hindi characters?
Our mapping table covers 194+ character pairs, including all standard Devanagari consonants, vowels, matras, numbers (0-9), punctuation, and the most common conjuncts (क्ष, त्र, ज्ञ, श्र, and 40+ others). Characters not in the Krutidev font - like the rupee sign, Vedic extensions, or rare Unicode-only conjuncts - pass through unchanged. See our benchmark page for specific test results.
How does this compare to the government NIC converter?
The NIC (National Informatics Centre) converter uses the same fundamental mapping approach - character substitution arrays with special-case handling for matras and reph. The primary difference is implementation quality: NIC tools have arbitrary size limits and lack error handling for edge cases. Our converter handles unlimited text and includes comprehensive special-case processing for chhoti i matra clusters and nested reph constructions.
Can I contribute corrections to the mapping table?
Yes. If you find a character that converts incorrectly, report it through our contact page with the input text, expected output, and actual output. We verify all reports against the Krutidev 010 font glyph table and update the mapping arrays. Every correction is documented in the benchmark with a new test case.