mirror of
https://github.com/enzet/map-machine.git
synced 2025-04-29 10:17:23 +02:00
222 lines
7.1 KiB
Python
222 lines
7.1 KiB
Python
"""Automate OpenStreetMap wiki editing."""
|
|
import re
|
|
from pathlib import Path
|
|
from typing import Optional
|
|
|
|
from map_machine.doc.doc_collections import Collection
|
|
|
|
from map_machine.map_configuration import MapConfiguration
|
|
from map_machine.osm.osm_reader import Tags
|
|
from map_machine.pictogram.icon import Icon, ShapeExtractor
|
|
from map_machine.scheme import Scheme
|
|
from map_machine.workspace import Workspace
|
|
|
|
WORKSPACE: Workspace = Workspace(Path("temp"))
|
|
|
|
SCHEME: Scheme = Scheme.from_file(WORKSPACE.DEFAULT_SCHEME_PATH)
|
|
EXTRACTOR: ShapeExtractor = ShapeExtractor(
|
|
WORKSPACE.ICONS_PATH, WORKSPACE.ICONS_CONFIG_PATH
|
|
)
|
|
|
|
HEADER_PATTERN: re.Pattern = re.compile("==?=?.*==?=?")
|
|
HEADER_2_PATTERN: re.Pattern = re.compile("== .* ==")
|
|
HEADER_PATTERNS: list[re.Pattern] = [
|
|
re.compile("==\\s*Example.*=="),
|
|
re.compile("==\\s*See also\\s*=="),
|
|
]
|
|
RENDERING_HEADER_PATTERN: re.Pattern = re.compile("==\\s*Rendering.*==")
|
|
ROENTGEN_HEADER_PATTERN: re.Pattern = re.compile("===.*Röntgen.*===")
|
|
|
|
|
|
class WikiTable:
|
|
"""SVG table with icon combinations."""
|
|
|
|
def __init__(self, collection: Collection, page_name: str):
|
|
self.collection: Collection = collection
|
|
self.page_name: str = page_name
|
|
|
|
def generate_wiki_table(self) -> tuple[str, list[Icon]]:
|
|
"""Generate Röntgen icon table for the OpenStreetMap wiki page."""
|
|
icons: list[Icon] = []
|
|
text: str = '{| class="wikitable"\n'
|
|
|
|
if self.collection.column_key is not None:
|
|
text += f"! {{{{Key|{self.collection.column_key}}}}}"
|
|
else:
|
|
text += "! Tag || Icon"
|
|
|
|
if self.collection.row_tags:
|
|
text += "\n"
|
|
for current_tags in self.collection.row_tags:
|
|
text += "|-\n"
|
|
text += "| "
|
|
if current_tags:
|
|
for key, value in current_tags.items():
|
|
if value == "*":
|
|
text += f"{{{{Key|{key}}}}}<br />"
|
|
else:
|
|
text += f"{{{{Tag|{key}|{value}}}}}<br />"
|
|
text = text[:-6]
|
|
text += "\n"
|
|
icon, _ = MapConfiguration(
|
|
SCHEME, ignore_level_matching=True
|
|
).get_icon(
|
|
EXTRACTOR, current_tags | self.collection.tags, set()
|
|
)
|
|
icons.append(icon.main_icon)
|
|
text += (
|
|
"| "
|
|
f"[[Image:Röntgen {icon.main_icon.get_name()}.svg|32px]]\n"
|
|
)
|
|
text += "|}\n"
|
|
return text, icons
|
|
|
|
if not self.collection.column_values:
|
|
self.collection.column_values = [""]
|
|
else:
|
|
make_vertical: bool = False
|
|
for column_value in self.collection.column_values:
|
|
if column_value and len(column_value) > 2:
|
|
make_vertical = True
|
|
for column_value in self.collection.column_values:
|
|
text += " ||"
|
|
if column_value:
|
|
tag: str = (
|
|
f"{{{{TagValue|"
|
|
f"{self.collection.column_key}|{column_value}}}}}"
|
|
)
|
|
text += " " + (
|
|
f"{{{{vert header|{tag}}}}}" if make_vertical else tag
|
|
)
|
|
text += "\n"
|
|
|
|
for row_value in self.collection.row_values:
|
|
text += "|-\n"
|
|
if row_value:
|
|
text += f"| {{{{Tag|{self.collection.row_key}|{row_value}}}}}\n"
|
|
else:
|
|
text += "|\n"
|
|
for column_value in self.collection.column_values:
|
|
current_tags: Tags = dict(self.collection.tags) | {
|
|
self.collection.row_key: row_value
|
|
}
|
|
if column_value:
|
|
current_tags |= {self.collection.column_key: column_value}
|
|
icon, _ = MapConfiguration(SCHEME).get_icon(
|
|
EXTRACTOR, current_tags, set()
|
|
)
|
|
if not icon:
|
|
print("Icon was not constructed.")
|
|
text += (
|
|
"| "
|
|
f"[[Image:Röntgen {icon.main_icon.get_name()}.svg|32px]]\n"
|
|
)
|
|
icons.append(icon.main_icon)
|
|
|
|
text += "|}\n"
|
|
|
|
return text, icons
|
|
|
|
|
|
def generate_new_text(
|
|
old_text: str,
|
|
table: WikiTable,
|
|
) -> tuple[Optional[str], list[Icon]]:
|
|
"""
|
|
Generate Röntgen icon table for the OpenStreetMap wiki page.
|
|
|
|
:param old_text: previous wiki page text
|
|
:param table: wiki table generator
|
|
:return: new wiki page text
|
|
"""
|
|
wiki_text: str
|
|
icons = []
|
|
|
|
if table.collection.row_key or table.collection.row_tags:
|
|
wiki_text, icons = table.generate_wiki_table()
|
|
else:
|
|
processed = set()
|
|
icon, _ = MapConfiguration(SCHEME).get_icon(
|
|
EXTRACTOR, table.collection.tags, processed
|
|
)
|
|
if not icon.main_icon.is_default():
|
|
wiki_text = (
|
|
f"[[Image:Röntgen {icon.main_icon.get_name()}.svg|32px]]\n"
|
|
)
|
|
icons.append(icon.main_icon)
|
|
elif icon.extra_icons:
|
|
wiki_text = (
|
|
f"Röntgen icon set has additional icon for the tag: "
|
|
f"[[Image:Röntgen {icon.extra_icons[0].get_name()}.svg|32px]]."
|
|
f"\n"
|
|
)
|
|
icons.append(icon.extra_icons[0])
|
|
else:
|
|
wiki_text = ""
|
|
|
|
lines: list[str] = old_text.split("\n")
|
|
|
|
# If rendering section already exists.
|
|
|
|
start: Optional[int] = None
|
|
end: int = -1
|
|
|
|
for index, line in enumerate(lines):
|
|
if HEADER_2_PATTERN.match(line):
|
|
if start is not None:
|
|
end = index
|
|
break
|
|
if RENDERING_HEADER_PATTERN.match(line):
|
|
start = index
|
|
|
|
if start is not None:
|
|
return (
|
|
"\n".join(lines[: start + 2])
|
|
+ "\n=== [[Röntgen]] icons in [[Map Machine]] ===\n"
|
|
+ f"\n{wiki_text}\n"
|
|
+ "\n".join(lines[end:])
|
|
), icons
|
|
|
|
# If Röntgen rendering section already exists.
|
|
|
|
start: Optional[int] = None
|
|
end: int = -1
|
|
|
|
for index, line in enumerate(lines):
|
|
if HEADER_PATTERN.match(line):
|
|
if start is not None:
|
|
end = index
|
|
break
|
|
if ROENTGEN_HEADER_PATTERN.match(line):
|
|
start = index
|
|
|
|
if start is not None:
|
|
return (
|
|
"\n".join(lines[: start + 2])
|
|
+ f"\n{wiki_text}\n"
|
|
+ "\n".join(lines[end:])
|
|
), icons
|
|
|
|
# Otherwise.
|
|
|
|
headers: list[Optional[int]] = [None, None]
|
|
|
|
for index, line in enumerate(lines):
|
|
for i, pattern in enumerate(HEADER_PATTERNS):
|
|
if pattern.match(line):
|
|
headers[i] = index
|
|
|
|
filtered = list(filter(lambda x: x is not None, headers))
|
|
header: int
|
|
|
|
if filtered:
|
|
header = filtered[0]
|
|
else:
|
|
lines += [""]
|
|
header = len(lines)
|
|
|
|
return (
|
|
"\n".join(lines[:header])
|
|
+ "\n== Rendering ==\n\n=== [[Röntgen]] icons in [[Map Machine]] "
|
|
"===\n\n" + wiki_text + "\n" + "\n".join(lines[header:])
|
|
), icons
|