""" 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