Skip to content

Instantly share code, notes, and snippets.

@Yaulendil
Last active November 6, 2019 23:11
Show Gist options
  • Save Yaulendil/b500d38011b9957e1c8b905f47431b73 to your computer and use it in GitHub Desktop.
Save Yaulendil/b500d38011b9957e1c8b905f47431b73 to your computer and use it in GitHub Desktop.
A String converter for a pseudo Middle English style, c. AD 1150.
"""Small Module providing text "conversion" into a pseudo-Middle-English style.
Based mostly, but loosely, on the orthography of Middle English c. AD 1150.
"""
from functools import partial
from re import compile
from typing import Any, Callable, Dict, Match, Union
__all__ = ("antiquate", "SubMap")
DEBUG: bool = False
SubMap = Dict[str, Union[str, Dict[str, Union[str, Any]]]]
table_chars: SubMap = {
# Ash:
"A[Ee]": "Æ",
"a[Ee]": "æ",
# OE Ligature:
"O[Ee]": "Œ",
"o[Ee]": "œ",
# Eth:
"D[Hh]": "Ð",
"d[Hh]": "ð",
# Thorn:
"T[Hh]": "Þ",
"t[Hh]": "þ",
# Wynn:
"W[Hh]?": "Ƿ",
"w[Hh]?": "ƿ",
# Yogh:
"G[Hh]": "Ȝ",
"g[Hh]": "ȝ",
# Z and Soft C to S:
"Z|C(?=[EeIi])": "S",
"z|c(?=[EeIi])": "s",
# (Probably) Soft G:
"(?<=[AaEeIiOoUu])G(?=[EeIi])": "J",
"(?<=[AaEeIiOoUu])g(?=[EeIi])": "j",
# Long Vowels:
r"(?i)(?<!\b)[aio]\we[dnsþ]?\b": {
r"(?i)((?<!s)e(!þ)(?=\w$))|(e$)|(e(?=[^dnsþ]$))": "",
"A": "Æ",
"a": "æ",
"I": "Y",
"i": "y",
"O": "Œ",
"o": "œ",
},
# U/V:
"U": "V",
"u": "v",
r"(?<!\b)v": "u",
# Middle English "-ing":
r"(?<=\w{2}[CcGgLlYy])ING(?=S?\W)": "INGE",
r"(?<=\w{3})ING(?=S?\W)": "YNGE",
r"(?i)(?<=\w{2}[cgly])ing(?=s?\W)": "inge",
r"(?i)(?<=\w{3})ing(?=s?\W)": "ynge",
# Long S:
r"s(?!\b)": "ſ",
}
def _prepare(d: SubMap, _db=False) -> Callable[[str], str]:
calls = [
partial(compile(k).sub, _prepare(v, DEBUG) if isinstance(v, dict) else v)
for k, v in d.items()
]
def run(text: Union[Match, str]) -> str:
if isinstance(text, Match):
text = text.group()
pre = text
for call in calls:
text = call(text)
if _db:
print(pre, "->", text)
return text
return run
_main: Callable[[str], str] = _prepare(table_chars)
def antiquate(text: str) -> str:
"""Convert a String into pseudo Middle English."""
return _main(text)
if __name__ == "__main__":
from sys import stdin
for line in stdin:
print(antiquate(line.strip()))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment