conversion des scripts de Christophe Devulder (pas fini)
Cette révision appartient à :
192
latex/devuldertex2latex.py
Fichier normal
192
latex/devuldertex2latex.py
Fichier normal
@@ -0,0 +1,192 @@
|
||||
import pyparsing as pyp
|
||||
import io
|
||||
|
||||
def automate(s) :
|
||||
|
||||
conversion = lambda v : str(v*4) + "pt" ## valeur de l'unité de letstate
|
||||
|
||||
pyp.ParserElement.inlineLiteralsUsing(pyp.Suppress)
|
||||
ident = (pyp.Combine(pyp.Word(pyp.alphas)+pyp.Optional(pyp.Word(pyp.nums)))).setName("ident")
|
||||
integer = (pyp.Optional(pyp.oneOf(["+", "-"]), default="+")+pyp.Word(pyp.nums)).setParseAction(lambda toks: int(toks[0]+toks[1])).setName("integer")
|
||||
real = pyp.Combine(pyp.Optional(pyp.oneOf("+ -")) + pyp.Word(pyp.nums) + "." +
|
||||
pyp.Optional(pyp.Word(pyp.nums))).setName("real").setParseAction(lambda toks: float(toks[0]))
|
||||
number = real | integer
|
||||
|
||||
maybelabel = "{" + pyp.Optional(pyp.QuotedString(quoteChar="$", escChar="\\", unquoteResults=False) | ident, default=None) + "}"
|
||||
|
||||
# intro
|
||||
intro = r"\begin{picture}("+ integer + "," + integer + ")"
|
||||
bounding_box = None
|
||||
def assign_bb(s, l, toks) :
|
||||
x, y = toks
|
||||
nonlocal bounding_box
|
||||
bounding_box = (x, y)
|
||||
intro.setParseAction(assign_bb)
|
||||
|
||||
# letstate
|
||||
etats = {}
|
||||
def do_letstate(s, l, toks) :
|
||||
id, x, y = toks
|
||||
nonlocal etats
|
||||
etats[id] = {"id": id, "posx": x, "posy": y, "initial": False, "accepting": False, "label": ""}
|
||||
letstate = (r"\letstate " + ident + "=(" + integer + "," + integer + ")").setParseAction(do_letstate)
|
||||
|
||||
# catégories d'états
|
||||
def do_catetat(s, l, toks) :
|
||||
statut, id, label = toks
|
||||
nonlocal etats
|
||||
if "initial" in statut :
|
||||
etats[id]["initial"] = True
|
||||
elif "final" in statut :
|
||||
etats[id]["accepting"] = True
|
||||
if label is not None :
|
||||
etats[id]["label"] = label
|
||||
drawstate = (pyp.oneOf(["\\drawstate","\\drawinitialstate", "\\drawfinalstate"]) + pyp.Optional("["+ident+"]").suppress() + "(" + ident + ")" + maybelabel ).setParseAction(do_catetat)
|
||||
|
||||
# transitions
|
||||
transitions = []
|
||||
def do_trans(toks) :
|
||||
nature, indication, orig, dest, label = toks
|
||||
nonlocal transitions
|
||||
if "curved" in nature :
|
||||
bend = True
|
||||
else :
|
||||
bend = False
|
||||
transitions.append({"orig": orig, "dest": dest, "label": label, "bend": bend, "indication":indication})
|
||||
trans = (pyp.oneOf(["\\drawcurvedtrans", "\\drawtrans", "\\drawedge"]) + pyp.Optional("["+ident+"]", default=None) + "(" + ident + "," + ident + ")" + maybelabel).setParseAction(do_trans)
|
||||
|
||||
boucles = []
|
||||
def do_loop(toks) :
|
||||
indication, etat, label = toks
|
||||
nonlocal boucles
|
||||
boucles.append({"indication":indication, "orig":etat, "label":label})
|
||||
loop = ("\\drawloop" + pyp.Optional("[" + ident + "]", default=None) + "(" + ident + ")" + maybelabel).setParseAction(do_loop)
|
||||
|
||||
ignorer = ("\\setprofcurve" + "{" + integer + "}") | ("\\setloopdiam" + "{" + integer + "}") | ("\\setstatediam"+"{"+integer+"}")
|
||||
|
||||
statement = letstate | drawstate | trans | loop | ignorer.suppress()
|
||||
|
||||
outro = pyp.Suppress(r"\end{picture}")
|
||||
|
||||
corps = pyp.Forward()
|
||||
corps << pyp.Optional(statement + corps)
|
||||
|
||||
parser = intro + corps + outro
|
||||
try :
|
||||
parser.parseString(s)
|
||||
except pyp.ParseException as e :
|
||||
print(e)
|
||||
print(s)
|
||||
print(e.line)
|
||||
raise e
|
||||
|
||||
os = io.StringIO()
|
||||
print(r"\begin{tikzpicture}[shorten >=1pt,node distance=2cm,auto, ->, initial text={}]", file=os)
|
||||
for id in etats :
|
||||
state = etats[id]
|
||||
print(r"\node[state", end="", file=os)
|
||||
if state["initial"] :
|
||||
print(", initial", end="", file=os)
|
||||
if state["accepting"] :
|
||||
print(", accepting", end="", file=os)
|
||||
print("] (", state["id"], ") at (", conversion(state["posx"]), ",", conversion(state["posy"]), ") {", state["label"], "};", sep="", file=os)
|
||||
for t in transitions :
|
||||
if t["indication"] == "r" :
|
||||
benddir = " right"
|
||||
elif t["indication"] == "l" :
|
||||
benddir = " left"
|
||||
else :
|
||||
benddir = " left"
|
||||
if t["bend"] :
|
||||
bend = "[bend" + benddir + "]"
|
||||
else :
|
||||
bend = ""
|
||||
print(r"\path (", t["orig"], ") edge", bend, " node {", t["label"], "} (", t["dest"], ");", sep="", file=os)
|
||||
for t in boucles :
|
||||
if t["indication"] == "b" :
|
||||
dir = "below"
|
||||
else :
|
||||
dir = "above"
|
||||
print(r"\path (", t["orig"], ") edge[loop ", dir, "] node {", t["label"], "} (", t["orig"], ");", sep="", file=os)
|
||||
print(r"\end{tikzpicture}", file=os)
|
||||
return os.getvalue()
|
||||
|
||||
|
||||
def traiter_automates(nf_i, nf_o) :
|
||||
inst = open(nf_i)
|
||||
outst = open(nf_o, "w")
|
||||
in_auto = False
|
||||
while True :
|
||||
line = inst.readline()
|
||||
if line is None or line == "" :
|
||||
break
|
||||
if line.startswith(r"\begin{picture}") :
|
||||
auto = line
|
||||
in_auto = True
|
||||
elif line.startswith(r"\end{picture}") :
|
||||
auto += line
|
||||
outst.write(automate(auto))
|
||||
auto = ""
|
||||
in_auto = False
|
||||
elif in_auto :
|
||||
auto += line
|
||||
else :
|
||||
outst.write(line)
|
||||
inst.close()
|
||||
outst.close()
|
||||
|
||||
def recup_comment(s) :
|
||||
spl = s.split("%", 1)
|
||||
if len(spl) == 1 :
|
||||
return ""
|
||||
else :
|
||||
return "%" + spl[1]
|
||||
|
||||
def exsol(nf_i, nf_o) :
|
||||
inst = open(nf_i)
|
||||
outst = open(nf_o, "w")
|
||||
while True :
|
||||
line = inst.readline()
|
||||
if line is None or line == "" :
|
||||
break
|
||||
elif line.startswith(r"\begin{ex}") :
|
||||
print(r"\begin{question}" + recup_comment(line), file=outst)
|
||||
elif line.startswith(r"\begin{sol}") :
|
||||
print(r"\end{question}", file=outst)
|
||||
print(r"\begin{corrige}" + recup_comment(line), file=outst)
|
||||
elif line.startswith(r"\end{sol}") :
|
||||
print(r"\end{corrige}", file=outst)
|
||||
inst.readline() # ignorer la ligne suivante
|
||||
else :
|
||||
print(line, end="", file=outst)
|
||||
inst.close()
|
||||
outst.close()
|
||||
|
||||
def resume(nf_i, nf_o) :
|
||||
inst = open(nf_i)
|
||||
outst = open(nf_o, "w")
|
||||
texte = inst.readlines()
|
||||
inst.close()
|
||||
imbrication = 0
|
||||
for k in range(len(texte)) :
|
||||
if texte[k].startswith(r"\begin{enumerate}") :
|
||||
if imbrication == 0 :
|
||||
texte[k] = texte[k].replace("enumerate", "enumq")
|
||||
imbrication += 1
|
||||
elif texte[k].startswith(r"\end{enumerate}") :
|
||||
imbrication -= 1
|
||||
if imbrication == 0 :
|
||||
texte[k] = texte[k].replace("enumerate", "enumq")
|
||||
|
||||
k = len(texte) - 1
|
||||
while k >= 0 :
|
||||
if texte[k].startswith(r"\begin{enumq}[resume]") :
|
||||
texte[k] = texte[k].replace(r"\begin{enumq}[resume]", r"\resume{enumq}")
|
||||
k = k - 1
|
||||
while not texte[k].startswith(r"\end{enumq}") :
|
||||
k = k - 1
|
||||
texte[k] = texte[k].replace(r"\end{enumq}", r"\suspend{enumq}")
|
||||
k = k - 1
|
||||
for l in texte :
|
||||
print(l, end="", file=outst)
|
||||
outst.close()
|
||||
Référencer dans un nouveau ticket
Bloquer un utilisateur