Initial commit
This commit is contained in:
85
formatter.py
Normal file
85
formatter.py
Normal file
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
INDENT = " " * 4
|
||||
|
||||
CLASS_START_RE = re.compile(
|
||||
r"^\s*(?:partial\s+)?(?:package|model|connector|record|function|block|type|operator)\b"
|
||||
)
|
||||
|
||||
SECTION_RE = re.compile(
|
||||
r"^\s*(?:equation|algorithm|initial\s+equation|initial\s+algorithm|protected|public)\b"
|
||||
)
|
||||
|
||||
IF_RE = re.compile(r"^\s*if\b.*\bthen\b")
|
||||
ELSEIF_RE = re.compile(r"^\s*elseif\b.*\bthen\b")
|
||||
ELSE_RE = re.compile(r"^\s*else\b")
|
||||
FOR_RE = re.compile(r"^\s*for\b.*\bloop\b")
|
||||
WHEN_RE = re.compile(r"^\s*when\b.*\bthen\b")
|
||||
ELSEWHEN_RE = re.compile(r"^\s*elsewhen\b.*\bthen\b")
|
||||
|
||||
END_RE = re.compile(r"^\s*end\b")
|
||||
|
||||
|
||||
def format_modelica(text: str) -> str:
|
||||
lines = text.replace("\t", " ").splitlines()
|
||||
out = []
|
||||
indent = 0
|
||||
|
||||
for raw in lines:
|
||||
stripped = raw.strip()
|
||||
|
||||
if not stripped:
|
||||
out.append("")
|
||||
continue
|
||||
|
||||
# Closing constructs outdent before printing
|
||||
if END_RE.match(stripped):
|
||||
indent = max(indent - 1, 0)
|
||||
|
||||
# else / elseif / elsewhen align with matching if/when
|
||||
elif ELSE_RE.match(stripped) or ELSEIF_RE.match(stripped) or ELSEWHEN_RE.match(stripped):
|
||||
indent = max(indent - 1, 0)
|
||||
|
||||
# Sections stay at model level, not one level deeper
|
||||
elif SECTION_RE.match(stripped):
|
||||
indent = max(indent - 1, 0)
|
||||
|
||||
out.append(f"{INDENT * indent}{stripped}")
|
||||
|
||||
# Increase indent only for real blocks
|
||||
if CLASS_START_RE.match(stripped):
|
||||
indent += 1
|
||||
elif IF_RE.match(stripped):
|
||||
indent += 1
|
||||
elif FOR_RE.match(stripped):
|
||||
indent += 1
|
||||
elif WHEN_RE.match(stripped):
|
||||
indent += 1
|
||||
elif ELSEIF_RE.match(stripped) or ELSE_RE.match(stripped) or ELSEWHEN_RE.match(stripped):
|
||||
indent += 1
|
||||
elif SECTION_RE.match(stripped):
|
||||
indent += 1
|
||||
|
||||
return "\n".join(out) + "\n"
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: python format_mo.py input.mo [output.mo]")
|
||||
sys.exit(1)
|
||||
|
||||
input_file = Path(sys.argv[1])
|
||||
output_file = Path(sys.argv[2]) if len(sys.argv) > 2 else input_file
|
||||
|
||||
text = input_file.read_text(encoding="utf-8")
|
||||
formatted = format_modelica(text)
|
||||
output_file.write_text(formatted, encoding="utf-8")
|
||||
|
||||
print(f"Formatted {output_file}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user