# Map "sh", "ch", and "ee" to single letters to simplify the parsing. # Note that "eee" groups are paired off from left end. s/ch/C/g s/sh/S/g s/ee/E/g # Map platformed and half-platformed letters to capitals to simplify the parsing: s/ckh/K/g s/cth/T/g s/cfh/F/g s/cph/P/g # s/ikh/G/g s/ith/H/g s/ifh/M/g s/iph/N/g # s/ck/U/g s/ct/V/g s/cf/X/g s/cp/Y/g # Put down scanning head in "@" state s/$/@/ :x # If in "@" state, copy "[aoy]" group, and switch to "#" state: s/\([aoy][aoy]*\)@/#\1/ s/@/#_/ # If in "#" state, copy next main letter and "e" complements, # insert "}" delimiter, and switch to "%" or "=" state depending on # whether "i"s are allowed or not: s/\([CSEktfpKTFPd]e\)#/=\1}/g s/\([CSEktfpKTFPGHMNUVXY]\)#/=\1}/g s/\([rlgmnsd]\)#/%\1}/g # If in "%" state, attach "i" string to group, go to "=" state: s/\(iii\)%/=\1/ s/\(ii\)%/=\1/ s/\(i\)%/=\1/ s/%/=/ # If in "=" state, insert "{" delimiter, and go back to "@" state: s/=/@{/ tx # We should exit the loop only in the "#" state. # Split "q" prefix and discard scanning head if done: s/^[q]#/{q}/ s/^#/{_}/ # Unfold letter folding: s/U/ck/g s/V/ct/g s/X/cf/g s/Y/cp/g # s/G/ikh/g s/H/ith/g s/M/ifh/g s/N/iph/g # s/K/ckh/g s/T/cth/g s/P/cph/g s/F/cfh/g # s/C/ch/g s/S/sh/g s/E/ee/g