2020-09-24 09:57:54 +10:00
|
|
|
# Copyright Mirage authors & contributors <https://github.com/mirukana/mirage>
|
2019-12-19 22:46:16 +11:00
|
|
|
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
|
|
|
2019-12-19 00:50:53 +11:00
|
|
|
"""QPL (Qt Property Language) theme files to QML converter.
|
|
|
|
|
|
|
|
QPL is a custom configuration format currently used for theme files.
|
|
|
|
This is a big hack and will be replaced in the future by a standard language.
|
|
|
|
"""
|
|
|
|
|
2019-07-23 17:14:02 +10:00
|
|
|
import re
|
|
|
|
from typing import Generator
|
|
|
|
|
|
|
|
PROPERTY_TYPES = {"bool", "double", "int", "list", "real", "string", "url",
|
|
|
|
"var", "date", "point", "rect", "size", "color"}
|
|
|
|
|
|
|
|
|
|
|
|
def _add_property(line: str) -> str:
|
2019-12-19 00:50:53 +11:00
|
|
|
"""Return a QML property declaration line from a QPL property line."""
|
|
|
|
|
2019-07-24 16:14:34 +10:00
|
|
|
if re.match(r"^\s*[a-zA-Z\d_]+\s*:$", line):
|
2019-07-23 17:14:02 +10:00
|
|
|
return re.sub(r"^(\s*)(\S*\s*):$",
|
|
|
|
r"\1readonly property QtObject \2: QtObject",
|
|
|
|
line)
|
|
|
|
|
|
|
|
types = "|".join(PROPERTY_TYPES)
|
|
|
|
if re.match(fr"^\s*({types}) [a-zA-Z\d_]+\s*:", line):
|
2019-07-24 16:14:34 +10:00
|
|
|
return re.sub(r"^(\s*)(\S*)", r"\1property \2", line)
|
2019-07-23 17:14:02 +10:00
|
|
|
|
|
|
|
return line
|
|
|
|
|
|
|
|
|
|
|
|
def _process_lines(content: str) -> Generator[str, None, None]:
|
2019-12-19 00:50:53 +11:00
|
|
|
"""Yield lines of real QML from lines of QPL."""
|
|
|
|
|
2019-07-23 17:14:02 +10:00
|
|
|
skip = False
|
|
|
|
indent = " " * 4
|
|
|
|
current_indent = 0
|
|
|
|
|
|
|
|
for line in content.split("\n"):
|
|
|
|
line = line.rstrip()
|
|
|
|
|
|
|
|
if not line.strip() or line.strip().startswith("//"):
|
|
|
|
continue
|
|
|
|
|
|
|
|
start_space_list = re.findall(r"^ +", line)
|
|
|
|
start_space = start_space_list[0] if start_space_list else ""
|
|
|
|
|
|
|
|
line_indents = len(re.findall(indent, start_space))
|
|
|
|
|
|
|
|
if not skip:
|
|
|
|
if line_indents > current_indent:
|
|
|
|
yield "%s{" % (indent * current_indent)
|
|
|
|
current_indent = line_indents
|
|
|
|
|
|
|
|
while line_indents < current_indent:
|
|
|
|
current_indent -= 1
|
|
|
|
yield "%s}" % (indent * current_indent)
|
|
|
|
|
|
|
|
line = _add_property(line)
|
|
|
|
|
|
|
|
yield line
|
|
|
|
|
|
|
|
skip = any((line.endswith(e) for e in "([{+\\,?:"))
|
|
|
|
|
|
|
|
while current_indent:
|
|
|
|
current_indent -= 1
|
|
|
|
yield "%s}" % (indent * current_indent)
|
|
|
|
|
|
|
|
|
|
|
|
def convert_to_qml(theme_content: str) -> str:
|
2019-12-19 00:50:53 +11:00
|
|
|
"""Return valid QML code with imports from QPL content."""
|
|
|
|
|
2020-03-28 22:48:27 +11:00
|
|
|
theme_content = theme_content.replace("\t", " ")
|
|
|
|
|
2019-07-23 17:14:02 +10:00
|
|
|
lines = [
|
|
|
|
"import QtQuick 2.12",
|
2019-12-18 20:00:27 +11:00
|
|
|
'import "../Base"',
|
2019-07-23 17:14:02 +10:00
|
|
|
"QtObject {",
|
2019-12-18 08:59:53 +11:00
|
|
|
" function hsluv(h, s, l, a) { return utils.hsluv(h, s, l, a) }",
|
|
|
|
" function hsl(h, s, l) { return utils.hsl(h, s, l) }",
|
|
|
|
" function hsla(h, s, l, a) { return utils.hsla(h, s, l, a) }",
|
2019-07-23 17:14:02 +10:00
|
|
|
" id: theme",
|
|
|
|
]
|
|
|
|
lines += [f" {line}" for line in _process_lines(theme_content)]
|
|
|
|
lines += ["}"]
|
2019-12-19 00:50:53 +11:00
|
|
|
|
2019-07-23 17:14:02 +10:00
|
|
|
return "\n".join(lines)
|