85 lines
2.3 KiB
Python
85 lines
2.3 KiB
Python
#!/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() |