From 62a4c4a4e182ff641fda5afc32eb2977fce963f9 Mon Sep 17 00:00:00 2001 From: ankraft <an.kraft@gmail.com> Date: Fri, 21 Feb 2025 14:33:30 +0100 Subject: [PATCH] Adapted debug output. Corrections in the main script. Renamed wrong filename --- .gitignore | 1 + toMkdocs/gridTableTools.py | 229 ++++++++++-------- .../{makrdownTools.py => markdownTools.py} | 58 +++-- toMkdocs/toMkdocs.py | 59 ++++- 4 files changed, 208 insertions(+), 139 deletions(-) rename toMkdocs/{makrdownTools.py => markdownTools.py} (92%) diff --git a/.gitignore b/.gitignore index 6d0869a..4fb7084 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ */ts-* */.python-version .python-version +toMkdocs/__pycache__ diff --git a/toMkdocs/gridTableTools.py b/toMkdocs/gridTableTools.py index c690c2c..22bc895 100644 --- a/toMkdocs/gridTableTools.py +++ b/toMkdocs/gridTableTools.py @@ -6,10 +6,25 @@ # """ Tools for working with grid tables in markdown files. """ -from typing import Optional +from typing import Optional, Callable from regexMatches import * +_alignLeft = 'align="left"' +_alignRight = 'align="right"' +_alignCenter = 'align="center"' + +printInfo = print +printDebug = print +printError = print + +def setLoggers(info:Callable=print, debug:Callable=print, error:Callable=print) -> None: + global printInfo, printDebug, printError + + printInfo = info + printDebug = debug + printError = error + class GridCell: """ Represents a grid table cell. """ @@ -27,8 +42,18 @@ class GridCell: self.auxiliarIndex:int = 0 - def calculateAndSetAlignment(self, headerDelimiterPositions:list[int], delimiterPositions:list[int], defaultAlignments:list[str], hasHeader:bool) -> None: + def calculateAndSetAlignment(self, + headerDelimiterPositions:list[int], + delimiterPositions:list[int], + defaultAlignments:list[str], + hasHeader:bool) -> None: """ Set the alignment of the cell based on the position of the delimiter. + + Args: + headerDelimiterPositions: The positions of the header delimiters. + delimiterPositions: The positions of the delimiters. + defaultAlignments: The default alignments. + hasHeader: True if the table has a header, False otherwise. """ if self.position is None: raise ValueError('Cell position must be set before calculating alignment.') @@ -46,17 +71,17 @@ class GridCell: else: raise ValueError('Invalid table formatting') else: - body_delimiter_index = 0 - while body_delimiter_index in range(len(defaultAlignments)) and self.position > delimiterPositions[body_delimiter_index]: - body_delimiter_index += 1 - if body_delimiter_index in range(len(defaultAlignments)): - if self.position < delimiterPositions[body_delimiter_index]: - self.alignment = defaultAlignments[body_delimiter_index] - elif self.position == delimiterPositions[body_delimiter_index]: - self.alignment = defaultAlignments[body_delimiter_index] - body_delimiter_index += 1 + bodyDelimiterIndex = 0 + while bodyDelimiterIndex < len(defaultAlignments) and self.position > delimiterPositions[bodyDelimiterIndex]: + bodyDelimiterIndex += 1 + if bodyDelimiterIndex < len(defaultAlignments): + if self.position < delimiterPositions[bodyDelimiterIndex]: + self.alignment = defaultAlignments[bodyDelimiterIndex] + elif self.position == delimiterPositions[bodyDelimiterIndex]: + self.alignment = defaultAlignments[bodyDelimiterIndex] + bodyDelimiterIndex += 1 else: - raise ValueError("Invalid table formatting") + raise ValueError('Invalid table formatting') def __str__(self): @@ -91,6 +116,7 @@ class GridRow(): def __repr__(self): return self.__str__() + class GridRowsTracker(): """ Represents the document object. """ def __init__(self, size:int) -> None: @@ -155,9 +181,10 @@ def parseGridTableWithSpans(gridTable:str) -> tuple[GridTableRowList, GridTableR cell.content = _c + nextListElementMark # Add list element end mark to know when the list element ends elif cell.listFlag and len(_c) > 0: # any other content when handling list is concatenated to the last list element _c = re.sub(r'\\\s*$', '\n', _c) - cell.content += _c + nextListElementMark #add the list element end mark - elif not _c: # separation between list and other paragraph - cell.content += '\n' if not cell['content'].endswith('\n') else "" + cell.content = _c + nextListElementMark #add the list element end mark + elif not _c: # empty line. separation between list and other paragraph + # cell.content = '\n' if not cell.content.endswith('\n') else "" + cell.content = '\n' # cell content is always empty / None here. else: cell.content = re.sub(r'\\\s*$', '\n', _c) else: # Cell has content @@ -173,8 +200,8 @@ def parseGridTableWithSpans(gridTable:str) -> tuple[GridTableRowList, GridTableR _c = re.sub(r'\\\s*$', '\n', _c) cell.content += " " + _c + nextListElementMark #add list element end mark elif len(_c) == 0: # separation between list and other paragraph - if cell.list_flag: - cell.list_flag = False + if cell.listFlag: + cell.listFlag = False cell.content += '\n\n' #end list by \n #content = re.sub(r'\\\s*$', "\n", content.strip()) cell.content += '\n' if not cell.content.endswith('\n') else '' @@ -205,7 +232,8 @@ def parseGridTableWithSpans(gridTable:str) -> tuple[GridTableRowList, GridTableR row[columnIndex].colspanAdjusted = True # Mark cell as adjusted - def check_delimiter_alignment(line: str, delimiterPositions:list[int], delimiters: str = "|+") -> bool: + + def checkDelimiterAlignment(line: str, delimiterPositions:list[int], delimiters: str = "|+") -> bool: """ Check if delimiters in a row align with expected positions. @@ -220,33 +248,29 @@ def parseGridTableWithSpans(gridTable:str) -> tuple[GridTableRowList, GridTableR if not line or not delimiterPositions: return False - print(f"\nChecking line: '{line}'") - print(f"Expected delimiter positions: {delimiterPositions}") + printDebug(f'\nChecking line: "{line}"') + printDebug(f'Expected delimiter positions: {delimiterPositions}') # For full separator lines (only +) if '+' in line and '|' not in line: - currentPositions = [i for i, char in enumerate(line) if (char == '+' and i != 0)] - print(f"Full separator line - Found + at positions: {currentPositions}") - return all(delimiterPositions[-1] in currentPositions and - line.startswith("+") and - pos in delimiterPositions for pos in currentPositions) + currentPositions = [i for i, char in enumerate(line) if (char == '+' and i > 0)] + printDebug(f'Full separator line - Found + at positions: {currentPositions}') + return all(delimiterPositions[-1] in currentPositions and line.startswith('+') and pos in delimiterPositions + for pos in currentPositions) # For data lines (only |) if '|' in line and '+' not in line: - currentPositions = [i for i, char in enumerate(line) if (char == '|' and i != 0)] - print(f"Data line - Found | at positions: {currentPositions}") - return all(delimiterPositions[-1] in currentPositions and - line.startswith("|") and - pos in delimiterPositions for pos in currentPositions) + currentPositions = [i for i, char in enumerate(line) if (char == '|' and i > 0)] + printDebug(f'Data line - Found | at positions: {currentPositions}') + return all(delimiterPositions[-1] in currentPositions and line.startswith("|") and pos in delimiterPositions + for pos in currentPositions) # For partial separators (mix of + and |) - currentPositions = [i for i, char in enumerate(line) if (char in delimiters and i != 0)] - print(f"Partial separator - Found delimiters at positions: {currentPositions}") - print(f"Characters at those positions: {[line[pos] for pos in currentPositions]}") - return all(delimiterPositions[-1] in currentPositions and - (line.startswith("+") or line.startswith("|")) and - pos in delimiterPositions for pos in currentPositions) - + currentPositions = [i for i, char in enumerate(line) if (char in delimiters and i > 0)] + printDebug(f'Partial separator - Found delimiters at positions: {currentPositions}') + printDebug(f'Characters at those positions: {[line[pos] for pos in currentPositions]}') + return all(delimiterPositions[-1] in currentPositions and line.startswith(('+', '|')) and pos in delimiterPositions + for pos in currentPositions) separatorIndices = [i for i, line in enumerate(lines) if isSeparator(line)] @@ -254,8 +278,8 @@ def parseGridTableWithSpans(gridTable:str) -> tuple[GridTableRowList, GridTableR raise ValueError('No valid separators found in the provided grid table.') # Calculate max number of columns - delimiterPositions:list[int] = [] - numberOfColumns = 0 + delimiterPositions = [] + numberOfColumns:int = 0 for separatorIndex in separatorIndices: if (_cnt := lines[separatorIndex].count('+') - 1) > numberOfColumns: @@ -263,10 +287,10 @@ def parseGridTableWithSpans(gridTable:str) -> tuple[GridTableRowList, GridTableR delimiterPositions = [] for rowIndex in range(numberOfColumns): delimiterPositionsStart = delimiterPositions[rowIndex - 1] if rowIndex != 0 else 0 - delPositions = [lines[separatorIndex].find(delimiter, delimiterPositionsStart + 1) for delimiter in '+' if delimiter in lines[separatorIndex][delimiterPositionsStart + 1:]] + delPositions = [lines[separatorIndex].find(delimiter, delimiterPositionsStart + 1) + for delimiter in '+' if delimiter in lines[separatorIndex][delimiterPositionsStart + 1:]] delimiterPositions.append(min(delPositions) if delPositions else -1) - # Determine delimter positions and alignments headerRows:GridTableRowList = [] dataRows:GridTableRowList = [] @@ -278,15 +302,22 @@ def parseGridTableWithSpans(gridTable:str) -> tuple[GridTableRowList, GridTableR parts = re.split(r'\+', lines[index].strip('+')) #Calculate default alignments and positions of delimiters for partIndex in range(len(parts)): - if parts[partIndex].startswith(':') and not parts[partIndex].endswith(':'): # Left alignment - defaultAlignments.append('align="left"') - elif not parts[partIndex].startswith(':') and parts[partIndex].endswith(':'): # Right alignment - defaultAlignments.append('align="right"') + # Left alignment + if parts[partIndex].startswith(':') and not parts[partIndex].endswith(':'): + defaultAlignments.append(_alignLeft) + + # Right alignment + elif not parts[partIndex].startswith(':') and parts[partIndex].endswith(':'): + defaultAlignments.append(_alignRight) + + # Center alignment else: - defaultAlignments.append('align="center"') # Center alignment + defaultAlignments.append(_alignCenter) + # Delimiter position delimiterPositionsStart = delimiterPositions[partIndex - 1] if partIndex != 0 else 0 - delPositions = [lines[index].find(delimiter, delimiterPositionsStart + 1) for delimiter in '+' if delimiter in lines[index][delimiterPositionsStart + 1:]] + delPositions = [lines[index].find(delimiter, delimiterPositionsStart + 1) + for delimiter in '+' if delimiter in lines[index][delimiterPositionsStart + 1:]] headerDelimiterPositions.append(min(delPositions) if delPositions else -1) if not hasHeader: @@ -296,11 +327,13 @@ def parseGridTableWithSpans(gridTable:str) -> tuple[GridTableRowList, GridTableR # Calculate default alignments and positions of delimiters for part_index in range(len(parts)): if parts[part_index].startswith(':') and not parts[part_index].endswith(':'): - default_alignments.append('align="left"') + default_alignments.append(_alignLeft) + elif not parts[part_index].startswith(':') and parts[part_index].endswith(':'): - default_alignments.append('align="right"') + default_alignments.append(_alignRight) + else: - default_alignments.append('align="center"') + default_alignments.append(_alignCenter) for rowNumber in range(len(separatorIndices) - 1): rows:list[GridRow] = [] @@ -314,8 +347,8 @@ def parseGridTableWithSpans(gridTable:str) -> tuple[GridTableRowList, GridTableR if isSeparator(line) and not inDataRow: inDataRow = True # Add delimiter alignment check for separator lines - if not check_delimiter_alignment(line, delimiterPositions): - raise ValueError(f"Misaligned delimiters in separator row: {line}") + if not checkDelimiterAlignment(line, delimiterPositions): + raise ValueError(f'Misaligned delimiters in separator row: {line}') parts = re.split(r'\s*\+\s*', line.strip('+')) delimiterIndex = 0 @@ -343,17 +376,17 @@ def parseGridTableWithSpans(gridTable:str) -> tuple[GridTableRowList, GridTableR # Regular data row or partial separator if matchGridTableBodySeparator.match(line): # Partial separator # Add delimiter alignment check for partial separators - if not check_delimiter_alignment(line, delimiterPositions): - raise ValueError(f"Misaligned delimiters in partial separator: {line}") + if not checkDelimiterAlignment(line, delimiterPositions): + raise ValueError(f'Misaligned delimiters in partial separator: {line}') - cellsContent = re.split(r"[\|\+]", line.strip('|').strip('+')) # (?<!\\)[\|\+] + cellsContent = re.split(r'[\|\+]', line.strip('|').strip('+')) # (?<!\\)[\|\+] #Add another row, set delimiters for each cell rows.append(GridRow(numberOfColumns)) auxDelimiterIndex = 0 auxiliarCellIndex = 0 for columnIndex, content in enumerate(cellsContent): - if auxiliarCellIndex in range(numberOfColumns): + if auxiliarCellIndex < numberOfColumns: auxDelimiterIndex += len(content) + 1 cell = rows[-1][auxiliarCellIndex] cell.position = auxDelimiterIndex # Position of cell delimiter + @@ -398,15 +431,14 @@ def parseGridTableWithSpans(gridTable:str) -> tuple[GridTableRowList, GridTableR continue else: - raise ValueError("More cells than columns found") + raise ValueError('More cells than columns found') else: # Data row - cellsContent = line.strip() - cellsContent = re.split(r"\|", line.strip('|')) + cellsContent = re.split(r'\|', line.strip('|')) # Add delimiter alignment check - if not check_delimiter_alignment(line, delimiterPositions): - raise ValueError(f"Misaligned delimiters in row: {line}") + if not checkDelimiterAlignment(line, delimiterPositions): + raise ValueError(f'Misaligned delimiters in row: {line}') columnCellIndex = 0 if len(cellsContent) < numberOfColumns: # Colspan: Positions of | with respect to + need to be determined @@ -426,9 +458,9 @@ def parseGridTableWithSpans(gridTable:str) -> tuple[GridTableRowList, GridTableR rowIndex = rowsTracker[columnIndex] handleCellContent(rows[rowIndex][columnIndex], content) else: - raise ValueError("More cells than columns found") + raise ValueError('More cells than columns found') else: - raise ValueError("No separator line found for row starting") + raise ValueError('No separator line found for row starting') if hasHeader and start >= headerSeparatorIndex: # table_row and auxiliar_row are part of data_rows for row in rows: @@ -451,7 +483,7 @@ def parseGridTableWithSpans(gridTable:str) -> tuple[GridTableRowList, GridTableR for cell in gridRow: if cell.content is not None: # Replacing "<" by < - cell.content = cell.content.replace("<", "<") + cell.content = cell.content.replace('<', '<') # Bold replacements # Regex to detect markdown bold formatting in cell content @@ -463,7 +495,6 @@ def parseGridTableWithSpans(gridTable:str) -> tuple[GridTableRowList, GridTableR if cell.content is not None: cell.content = matchItalic.sub(r'<i>\g<text></i>', cell.content) - # Correct newlines characters for headerRow in headerRows: for cell in headerRow: @@ -525,25 +556,11 @@ def generateHtmlTableWithSpans(gridTable:str) -> str: Returns: The HTML table in string format. """ - debug_output = [] - def debug_print(msg): - debug_output.append(str(msg)) # Convert message to string - try: - # Redirect print statements to our debug collector - global print - original_print = print - print = debug_print - gridHeader, gridBody = parseGridTableWithSpans(gridTable) - - # Restore original print - print = original_print - except Exception as e: - debug_print("Grid table could not be generated") - debug_text = "<br>".join(debug_output) # Now all items are strings - return f'HTML TABLE COULD NOT BE GENERATED FROM MARKDOWN GRID TABLE.<br><pre>{debug_text}</pre>' + printDebug('Grid table could not be generated') + return f'HTML TABLE COULD NOT BE GENERATED FROM MARKDOWN GRID TABLE' # Generate table HTML... html = '<table>\n' @@ -564,47 +581,47 @@ def generateHtmlTableWithSpans(gridTable:str) -> str: continue else: # Prepare content, in case there's a list - if cell.content is not None and (matches := re.findall(r"\s*([-*+]|\s*\d+\.)\s+((?:(?!@).)+)@", cell.content)): # Update cell in new row - list = "<ul>" + if cell.content is not None and (matches := re.findall(r'\s*([-*+]|\s*\d+\.)\s+((?:(?!@).)+)@', cell.content)): # Update cell in new row + list = '<ul>' # Build list the matches for match in matches: - list += "<li>" + match[1] + "</li>" - list += "</ul>" - cell.content = re.sub(r"(\s*([-*+]|\s*\d+\.)\s+(?:(?!@).)+@)+", list, cell.content) + list += '<li>' + match[1] + '</li>' + list += '</ul>' + cell.content = re.sub(r'(\s*([-*+]|\s*\d+\.)\s+(?:(?!@).)+@)+', list, cell.content) # Enforce left alignment if cell contains a list - cell.alignment = "align=\"left\"" + cell.alignment = _alignLeft - rowspan = f" rowspan=\"{cell.rowspan}\"" if cell.rowspan > 1 else "" - colspan = f" colspan=\"{cell.colspan}\"" if cell.colspan > 1 else "" - html += f" <th{rowspan}{colspan} {cell.alignment}>{cell.content}</th>\n" - html += " </tr>\n" - html += " </thead>\n" + rowspan = f' rowspan="{cell.rowspan}"' if cell.rowspan > 1 else '' + colspan = f' colspan="{cell.colspan}"' if cell.colspan > 1 else '' + html += f' <th{rowspan}{colspan} {cell.alignment}>{cell.content}</th>\n' + html += ' </tr>\n' + html += ' </thead>\n' - html += " <tbody>\n" + html += ' <tbody>\n' for row in gridBody: - html += " <tr>\n" + html += ' <tr>\n' for cell in row: if cell.rowspan == 0 or cell.colspan == 0: continue else: #Prepare content, in case there's a list - if cell.content is not None and (matches := re.findall(r"\s*([-*+]|\s*\d+\.)\s+((?:(?!@).)+)@", cell.content)): # Update cell in new row - list = "<ul>" + if cell.content is not None and (matches := re.findall(r'\s*([-*+]|\s*\d+\.)\s+((?:(?!@).)+)@', cell.content)): # Update cell in new row + list = '<ul>' # Build list the matches for match in matches: - list += "<li>" + match[1] + "</li>" - list += "</ul>" - cell.content = re.sub(r"(\s*([-*+]|\s*\d+\.)\s+(?:(?!@).)+@)+",list, cell.content) + list += f'<li>{match[1]}</li>' + list += '</ul>' + cell.content = re.sub(r'(\s*([-*+]|\s*\d+\.)\s+(?:(?!@).)+@)+', list, cell.content) # Enforce left alignment if cell contains a list - cell.alignment = "align=\"left\"" + cell.alignment = _alignLeft - rowspan = f" rowspan=\"{cell.rowspan}\"" if cell.rowspan > 1 else "" - colspan = f" colspan=\"{cell.colspan}\"" if cell.colspan > 1 else "" - html += f" <td{rowspan}{colspan} {cell.alignment}>{cell.content}</td>\n" - html += " </tr>\n" + rowspan = f' rowspan="{cell.rowspan}"' if cell.rowspan > 1 else '' + colspan = f' colspan="{cell.colspan}"' if cell.colspan > 1 else '' + html += f' <td{rowspan}{colspan} {cell.alignment}>{cell.content}</td>\n' + html += ' </tr>\n' - html += " </tbody>\n" - html += "</table>" + html += ' </tbody>\n' + html += '</table>' return html diff --git a/toMkdocs/makrdownTools.py b/toMkdocs/markdownTools.py similarity index 92% rename from toMkdocs/makrdownTools.py rename to toMkdocs/markdownTools.py index 169b634..56ea86e 100644 --- a/toMkdocs/makrdownTools.py +++ b/toMkdocs/markdownTools.py @@ -9,12 +9,13 @@ """ Various tools for markdown processing """ from __future__ import annotations +from typing import Callable from dataclasses import dataclass import base64, hashlib from enum import Enum, auto -from gridTableTools import generateHtmlTableWithSpans +from gridTableTools import generateHtmlTableWithSpans, setLoggers as setGridTableLoggers from regexMatches import * # TODO use a verbosity level instead @@ -23,12 +24,18 @@ veryVerbose = False printInfo = print printDebug = print +printError = print -def setScreenPrinters(info:callable = print, debug:callable = print) -> None: - global printInfo, printDebug +def setLoggers(info:Callable = print, debug:Callable = print, error:Callable= print) -> None: + global printInfo, printDebug, printError printInfo = info printDebug = debug + printError = error + + # Set the loggers for the grid table tools + setGridTableLoggers(info, debug, error) + def _shortHash(value:str, length:int) -> str: @@ -365,6 +372,28 @@ def analyseMarkdown(filename:str) -> Document: The document object. """ + gridTable:str = '' + + def processGridTable() -> None: + """ Process a grid table and convert it to an html table. + + This function adds the html table to the output clauses and + clears the gridTable variable. + """ + nonlocal gridTable + + htmltable:str = '' + try: + htmltable = generateHtmlTableWithSpans(gridTable) + printDebug(htmltable) + except Exception as e: + printError(f"Error: {e}") + # TODO move this outside of the analyseMarkdown function !!! + for row in htmltable: + outClauses[-1].append(Line(row, LineType.TABLEROW)) + gridTable = '' + + printInfo(f'Analyzing "{filename}"') # Read the file. @@ -381,10 +410,7 @@ def analyseMarkdown(filename:str) -> Document: inTable = False tableHasSeparator = False inGridTable = False - gridTableHasSeparator = False - gridTable = "" for line in inLines: - # Detect and handle codefences # For the moment we support only codefences that start and end # with 3 backticks. This is the most common way to define codefences. @@ -439,18 +465,7 @@ def analyseMarkdown(filename:str) -> Document: continue else: inGridTable = False - # Mark the previous line as the last row in the table - #outClauses[-1].lines[-1].lineType = LineType.TABLELASTROW - # print(gridTable) - try: - htmltable = generateHtmlTableWithSpans(gridTable) - print(htmltable) - except Exception as e: - print(f"Error: {e}") - # TODO move this outside of the analyseMarkdown function !!! - for row in htmltable: - outClauses[-1].append(Line(row, LineType.TABLEROW)) - gridTable = "" + processGridTable() # continue with other matches # Detect notes @@ -486,9 +501,10 @@ def analyseMarkdown(filename:str) -> Document: # Just add the line to the current clause as text outClauses[-1].append(Line(line, _lineType)) - return Document(outClauses, footnotes) - - + # Process still unfinished cases + if gridTable: + processGridTable() + return Document(outClauses, footnotes) diff --git a/toMkdocs/toMkdocs.py b/toMkdocs/toMkdocs.py index 69037d1..af4a286 100644 --- a/toMkdocs/toMkdocs.py +++ b/toMkdocs/toMkdocs.py @@ -12,13 +12,49 @@ from __future__ import annotations import argparse, os, shutil from rich import print -from makrdownTools import Line, Document, analyseMarkdown, setScreenPrinters +from markdownTools import Line, Document, analyseMarkdown, setLoggers from regexMatches import match2spaceListIndention verbose = False veryVerbose = False +def printDebug(text:str) -> None: + """ Print a debug message. + + Args: + text: The text of the debug message. + """ + if verbose: + print(f'[dim]{text}') + + +def printInfo(text:str) -> None: + """ Print an information message. + + Args: + text: The text of the information message. + """ + print(f'[green]{text}') + + +def printWarning(text:str) -> None: + """ Print a warning message. + + Args: + text: The text of the warning message. + """ + print(f'[yellow]{text}') + + +def printError(text:str) -> None: + """ Print an error message. + + Args: + text: The text of the error message. + """ + print(f'[red]{text}') + def prepareForMkdocs(document:Document, includeHangingParagraphs:bool = False) -> None: """ Prepare the clauses for MkDocs. This includes removing the heading from the clauses and marking the clauses that are only for navigation. @@ -47,7 +83,7 @@ def prepareForMkdocs(document:Document, includeHangingParagraphs:bool = False) - # Check if there is a sub-clause in the next clause if i + 1 < len(document.clauses) and document.clauses[i+1].level > clause.level: # This is a hanging paragraph. Remove the text from the current clause. - print(f'[yellow]Hanging paragraph in clause "{clause.title}" {"(removed)" if not includeHangingParagraphs else "(kept)"}') + printWarning(f'Hanging paragraph in clause "{clause.title}" {"(removed)" if not includeHangingParagraphs else "(kept)"}') if not includeHangingParagraphs: document.clauses[i].lines = [] else: @@ -72,15 +108,14 @@ def writeClausesMkDocs(document:Document, filename:str, navTitle:str, addNavTitl addNavTitle: Add the title as an extra navigation level to the navigation file. """ - print(f'[green]Writing clauses to files') + printInfo(f'Writing clauses to files') # create directory first os.makedirs(f'{os.path.dirname(filename)}/{navTitle}', exist_ok = True) # Write the files for i, f in enumerate(document.clauses): # write to single files, even empty ones - if verbose: - print(f'[dim]Writing "{f.clauseNumber}.md" - "{f.title}"') + printDebug(f'Writing "{f.clauseNumber}.md" - "{f.title}"') with open(f'{os.path.dirname(filename)}/{navTitle}/{f.clauseNumber}.md', 'w') as file: # Add one empty line before the clause. This is done to avoid # a bug in MkDocs that does not display the first line of a clause @@ -90,11 +125,10 @@ def writeClausesMkDocs(document:Document, filename:str, navTitle:str, addNavTitl # write nav.yml file - print(f'[green]Writing "_nav.yml"') + printInfo(f'Writing "_nav.yml"') indentation = ' ' if addNavTitle else '' # TODO make number of spaces configurable with open(f'{os.path.dirname(filename)}/_nav.yml', 'w') as file: - if veryVerbose: - print(f'[dim]Writing navigation file') + printDebug(f'Writing navigation file') if addNavTitle: file.write(f'{indentation}- {navTitle}:\n') for i, f in enumerate(document.clauses): @@ -130,10 +164,10 @@ def copyMediaFiles(filename:str, navTitle:str, mediaDirectory:str = 'media') -> targetDirectory = f'{os.path.dirname(filename)}/{navTitle}/{mediaDirectory}' if os.path.exists(sourceDirectory): - print(f'[green]Copying media files from "{sourceDirectory}" to "{targetDirectory}"') + printInfo(f'Copying media files from "{sourceDirectory}" to "{targetDirectory}"') shutil.copytree(sourceDirectory, targetDirectory, dirs_exist_ok = True) else: - print(f'[red]Media directory "{sourceDirectory}" does not exist') + printError(f'Media directory "{sourceDirectory}" does not exist') def processDocument(args:argparse.Namespace) -> None: @@ -177,8 +211,9 @@ def main() -> None: parser.add_argument('document', type = str, help = 'a oneM2M markdown specification document to process') args = parser.parse_args() - setScreenPrinters(info = lambda text: print(f'[green]{text}'), - debug = lambda text: print(f'[dim]{text}')) + setLoggers(info = printInfo, + debug = printDebug, + error = printError) processDocument(args) -- GitLab