map-machine/map_machine/doc/wiki.py
2021-11-14 07:50:20 +03:00

151 lines
4.2 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("==?=?.*==?=?")
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, priority = 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
"""
table_wiki_text: str = generate_table(
tags, row_key, row_values, column_key, column_values
)
lines: list[str] = old_text.split("\n")
table_start: Optional[int] = None
table_end: int = -1
for index, line in enumerate(lines):
if HEADER_PATTERN.match(line):
if table_start is not None:
table_end = index
break
if RENDERING_HEADER_PATTERN.match(line):
table_start = index
if table_start is not None:
return (
"\n".join(lines[: table_start + 2])
+ "\n"
+ table_wiki_text
+ "\n"
+ "\n".join(lines[table_end:])
)
example_header: Optional[int] = None
for index, line in enumerate(lines):
if EXAMPLE_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"
+ table_wiki_text
+ "\n"
+ "\n".join(lines[example_header:])
)
return None