mirror of
https://github.com/enzet/map-machine.git
synced 2025-04-30 10:47:29 +02:00
173 lines
4.8 KiB
Python
173 lines
4.8 KiB
Python
"""
|
|
Automate OpenStreetMap wiki editing.
|
|
"""
|
|
import re
|
|
from pathlib import Path
|
|
from typing import Optional
|
|
|
|
from map_machine.map_configuration import MapConfiguration
|
|
from map_machine.osm.osm_reader import Tags
|
|
from map_machine.pictogram.icon import ShapeExtractor
|
|
from map_machine.scheme import Scheme
|
|
from map_machine.workspace import Workspace
|
|
|
|
WORKSPACE: Workspace = Workspace(Path("temp"))
|
|
|
|
SCHEME: Scheme = Scheme(WORKSPACE.DEFAULT_SCHEME_PATH)
|
|
EXTRACTOR: ShapeExtractor = ShapeExtractor(
|
|
WORKSPACE.ICONS_PATH, WORKSPACE.ICONS_CONFIG_PATH
|
|
)
|
|
|
|
HEADER_PATTERN: re.Pattern = re.compile("==?=?.*==?=?")
|
|
SEE_ALSO_HEADER_PATTERN: re.Pattern = re.compile("==\\s*See also\\s*==")
|
|
EXAMPLE_HEADER_PATTERN: re.Pattern = re.compile("==\\s*Example\\s*==")
|
|
RENDERING_HEADER_PATTERN: re.Pattern = re.compile(
|
|
"===\\s*\\[\\[Röntgen]] icons\\s*==="
|
|
)
|
|
|
|
|
|
def generate_table(
|
|
tags: Tags,
|
|
row_key: str,
|
|
row_values: list[str],
|
|
column_key: str,
|
|
column_values: list[str],
|
|
) -> str:
|
|
"""
|
|
Generate Röntgen icon table for the OpenStreetMap wiki page.
|
|
|
|
:param tags: core tags
|
|
:param row_key: tag key to be used in rows
|
|
:param row_values: list of tag values to be used in rows
|
|
:param column_key: tag key to be used in columns
|
|
:param column_values: list of tag values to be used in columns
|
|
"""
|
|
text: str = '{| class="wikitable"\n'
|
|
|
|
if column_key is not None:
|
|
text += f"! {{{{Key|{column_key}}}}}"
|
|
else:
|
|
text += "! Tag || Icon"
|
|
|
|
if not column_values:
|
|
column_values = [""]
|
|
else:
|
|
for column_value in column_values:
|
|
text += " ||"
|
|
if column_value:
|
|
text += (
|
|
" {{vert header|"
|
|
f"{{{{TagValue|{column_key}|{column_value}}}}}"
|
|
"}}"
|
|
)
|
|
text += "\n"
|
|
|
|
processed: set[str] = set()
|
|
|
|
for row_value in row_values:
|
|
text += "|-\n"
|
|
if row_value:
|
|
text += f"| {{{{Tag|{row_key}|{row_value}}}}}\n"
|
|
else:
|
|
text += "|\n"
|
|
for column_value in column_values:
|
|
current_tags: Tags = dict(tags) | {row_key: row_value}
|
|
if column_value:
|
|
current_tags |= {column_key: column_value}
|
|
icon, _ = SCHEME.get_icon(
|
|
EXTRACTOR, current_tags, processed, MapConfiguration()
|
|
)
|
|
if not icon:
|
|
print("Icon was not constructed.")
|
|
text += (
|
|
f"| [[Image:Röntgen {icon.main_icon.get_name()}.svg|32px]]\n"
|
|
)
|
|
|
|
text += "|}\n"
|
|
|
|
return text
|
|
|
|
|
|
def generate_new_text(
|
|
old_text: str,
|
|
tags: Tags,
|
|
row_key: str,
|
|
row_values: list[str],
|
|
column_key: str,
|
|
column_values: list[str],
|
|
) -> Optional[str]:
|
|
"""
|
|
Generate Röntgen icon table for the OpenStreetMap wiki page.
|
|
|
|
:param old_text: previous wiki page text
|
|
:param tags: core tags
|
|
:param row_key: tag key to be used in rows
|
|
:param row_values: list of tag values to be used in rows
|
|
:param column_key: tag key to be used in columns
|
|
:param column_values: list of tag values to be used in columns
|
|
:return: new wiki page text
|
|
"""
|
|
wiki_text: str
|
|
|
|
if row_key:
|
|
wiki_text = generate_table(
|
|
tags, row_key, row_values, column_key, column_values
|
|
)
|
|
else:
|
|
processed = set()
|
|
icon, _ = SCHEME.get_icon(
|
|
EXTRACTOR, tags, processed, MapConfiguration()
|
|
)
|
|
if icon.main_icon.is_default():
|
|
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"
|
|
)
|
|
else:
|
|
wiki_text = (
|
|
f"[[Image:Röntgen {icon.main_icon.get_name()}.svg|32px]]\n"
|
|
)
|
|
|
|
lines: list[str] = old_text.split("\n")
|
|
|
|
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 RENDERING_HEADER_PATTERN.match(line):
|
|
start = index
|
|
|
|
if start is not None:
|
|
return (
|
|
"\n".join(lines[: start + 2])
|
|
+ "\n"
|
|
+ wiki_text
|
|
+ "\n"
|
|
+ "\n".join(lines[end:])
|
|
)
|
|
|
|
example_header: Optional[int] = None
|
|
|
|
for index, line in enumerate(lines):
|
|
if EXAMPLE_HEADER_PATTERN.match(line) or SEE_ALSO_HEADER_PATTERN.match(
|
|
line
|
|
):
|
|
example_header = index
|
|
break
|
|
|
|
if example_header is not None:
|
|
return (
|
|
"\n".join(lines[:example_header])
|
|
+ "\n"
|
|
+ "== Rendering ==\n\n=== [[Röntgen]] icons ===\n\n"
|
|
+ wiki_text
|
|
+ "\n"
|
|
+ "\n".join(lines[example_header:])
|
|
)
|
|
|
|
return None
|