Commit 86e406f3 authored by Mark Canterbury's avatar Mark Canterbury Committed by Mark Canterbury
Browse files

Trying automated linting

parent f37ef65b
Loading
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -15,7 +15,15 @@ stages:
# -----------------------------------------------------------
# Markdown

markdown:
markdown_lint:
  image: "forge.etsi.org:5050/li/schemas-definitions/forgeschema:latest"
  stage: markdown_test
  script:
    - python testing/markdown/test_md.py
  tags:
    - docker

markdown_build:
  stage: markdown_test
  rules:
    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
+66 −0
Original line number Diff line number Diff line
from pathlib import Path
from re import compile


md_file = Path("104196/TR_104196.md")
md = md_file.read_text()

heading_regex = compile(r'^(#+) ((?:[0-9]+\.)*(?:[0-9]+)) (.*)$')

current_heading = ""
last_parts = []
previous_heading = ""
text_between = False

for ln, line in enumerate(md.splitlines()):
    if line.startswith("#"):
        errors = []
        match = heading_regex.match(line)
        if not match:
            if last_parts != []:
                error = f"Line {ln+1}: Malformed heading '{line}'"
                if '\t' in line:
                    error += f". Line contains tab characters, this might be the issue?"
                errors.append(error)
        else:
            heading_level = len(match.group(1))
            heading_number = match.group(2)
            heading_title = match.group(3)

            try:
                heading_number_parts = [int(x) for x in heading_number.split(".")]
            except Exception as ex:
                errors.append(f"Couldn't parse heading number '{heading_number}'")
                continue
            if len(heading_number_parts) != heading_level:
                errors.append(f"Inconsistent heading level '{line}' - heading '{heading_number}' should be level {heading_level} ({'#' * heading_level})")

            if last_parts != []:
                heading_difference = len(heading_number_parts) - len(last_parts)
                if heading_difference > 1:
                    errors.append(f"Missing some subheadings between this heading ({heading_number}) and immediate parent ({previous_heading})")
                if heading_difference == 1:
                    if heading_number_parts[-1] != 1:
                        errors.append(f"New subheading {heading_number} under {previous_heading} not starting at 1")
                    if text_between:
                        errors.append(f"Hanging text between {heading_number} and {previous_heading}")
                if heading_difference == 0:
                    if heading_number_parts[-1] != last_parts[-1] + 1:
                        errors.append(f"Heading {heading_number} missing some siblings, previous sibling was {previous_heading}")
                if heading_difference < 0:
                    new_depth = len(heading_number_parts)
                    if heading_number_parts[-1] != last_parts[new_depth - 1] + 1:
                        errors.append(f"Heading {heading_number} doesn't return to expected sequence from {previous_heading}")
            last_parts = heading_number_parts
            previous_heading = heading_number

        if len(errors) == 0:
            print(f"{line}")
        else:
            print(f"{line} - line {ln + 1}")
            for err in errors:
                print(f"   - {err}")
        text_between = False
    else:
        if line.strip() != "":
            text_between = True