Skip to content

Commit

Permalink
minor: additional None checks for frontmatters and docstrings
Browse files Browse the repository at this point in the history
  • Loading branch information
AlphaJack committed May 14, 2024
1 parent 87d2c66 commit 7db654f
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 49 deletions.
11 changes: 9 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
# usage:
# make release tag=v2.7.0

#In case a tag has been pushed to GitHub, but the release failed, run `
# git tag --delete v2.7.0
# git push --delete origin v2.7.0
# and repeat the steps below

release:
python -m pytest
mypy .
black .
git status
echo "Abort now if there are files that needs to be committed"
sleep 5
git log
sleep 10
git tag $(tag)
# enter "v2.7.0"
git-cliff -c pyproject.toml > CHANGELOG.md
Expand Down
7 changes: 4 additions & 3 deletions tests/test_toc.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,9 +223,10 @@ def test_input_files(self):
t.lineNumbers = True if file.name == "latex_linenumbers.tex" else False
t.to_file(output_file)
if output_file.is_file() and reference_file.is_file():
with open(output_file, "r") as output, open(
reference_file, "r"
) as reference:
with (
open(output_file, "r") as output,
open(reference_file, "r") as reference,
):
output_content, reference_content = output.read(), reference.read()
comparison = True if output_content == reference_content else False
with self.subTest(comparison=comparison):
Expand Down
193 changes: 149 additions & 44 deletions toc/toc.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,67 @@ def __init__(self, inputFile: Path):
def set_character(self) -> str:
# automatically select the comment type from its extension, if not already set
match self.extension:
case "ad" | "adoc" | "asc" | "asciidoc" | "c" | "carbon" | "cc" | "coffee" | "cpp" | "cs" | "css" | "cu" | "d" | "dart" | "go" | "h" | "hpp" | "htm" | "html" | "hxx" | "java" | "js" | "jsx" | "kt" | "md" | "mdx" | "qmd" | "rmd" | "pas" | "php" | "pp" | "proto" | "qs" | "rs" | "scala" | "sc" | "swift" | "ts" | "typ" | "xml" | "zig":
case (
"ad"
| "adoc"
| "asc"
| "asciidoc"
| "c"
| "carbon"
| "cc"
| "coffee"
| "cpp"
| "cs"
| "css"
| "cu"
| "d"
| "dart"
| "go"
| "h"
| "hpp"
| "htm"
| "html"
| "hxx"
| "java"
| "js"
| "jsx"
| "kt"
| "md"
| "mdx"
| "qmd"
| "rmd"
| "pas"
| "php"
| "pp"
| "proto"
| "qs"
| "rs"
| "scala"
| "sc"
| "swift"
| "ts"
| "typ"
| "xml"
| "zig"
):
self.character = "//"
case "ahk" | "asm" | "beancount" | "cl" | "clj" | "cljs" | "cljc" | "edn" | "fasl" | "ini" | "lisp" | "lsp" | "rkt" | "scm" | "ss":
case (
"ahk"
| "asm"
| "beancount"
| "cl"
| "clj"
| "cljs"
| "cljc"
| "edn"
| "fasl"
| "ini"
| "lisp"
| "lsp"
| "rkt"
| "scm"
| "ss"
):
self.character = ";"
case "bib" | "cls" | "erl" | "hrl" | "mat" | "sty" | "tex":
self.character = "%"
Expand Down Expand Up @@ -117,10 +175,14 @@ def to_stdout(self) -> None:
_, _outerToc = self._generate_toc()
if _outerToc == "":
# skip error if we already set self.err
print(
f'Could not generate a "{self.character}" toc from "{self.inputFile}"',
file=sys.stderr,
) if self.err is None else None
(
print(
f'Could not generate a "{self.character}" toc from "{self.inputFile}"',
file=sys.stderr,
)
if self.err is None
else None
)
self.err = "empty"
else:
print(_outerToc)
Expand All @@ -132,9 +194,11 @@ def to_file(self, output: Path | None = None) -> None:
if self.outputFile is None:
self.outputFile = output if output else self.inputFile
if self.inputFile == Path("-"):
print(
"Cannot write to stdin", file=sys.stderr
) if self.err is None else None
(
print("Cannot write to stdin", file=sys.stderr)
if self.err is None
else None
)
self.err = "stdin"
else:
# run twice because updating the toc with self.lineNumbers == True may shift everything down
Expand All @@ -149,19 +213,23 @@ def _add_or_update(self) -> None:
_innerToc, _outerToc = self._generate_toc()
# do not write an empty file
if _outerToc == "":
print(
f'Could not generate a "{self.character}" toc from "{self.inputFile}"',
file=sys.stderr,
) if self.err is None else None
(
print(
f'Could not generate a "{self.character}" toc from "{self.inputFile}"',
file=sys.stderr,
)
if self.err is None
else None
)
self.err = "empty"
else:
# if the file does not contain a toc, add it, otherwise update it
# re.MULTILINE: https://docs.python.org/3/library/re.html#re.M
# match also file name, results in a second toc if file is renamed
#self.pattern = re.compile(
# self.pattern = re.compile(
# rf"{self.innerTocBegin}\n{self.innerTocTitle}(.*?){self.innerTocEnd}",
# re.DOTALL,
#)
# )
# does not match file name, replacing toc even if file gets renamed
self.pattern = re.compile(
rf"{self.innerTocBegin}\n{self.character} │ Contents of (.*?){self.innerTocEnd}",
Expand All @@ -182,15 +250,24 @@ def _write_toc(self, data: str) -> None:
with open(self.outputFile, "w") as f:
f.write(data)
except PermissionError:
print(
f'Skipping write-protected "{self.outputFile}"', file=sys.stderr
) if self.err is None else None
(
print(
f'Skipping write-protected "{self.outputFile}"', file=sys.stderr
)
if self.err is None
else None
)
self.err = "write"
self.updated = True
except BaseException:
print(
f'Unknown error while writing "{self.outputFile}"', file=sys.stderr
) if self.err is None else None
(
print(
f'Unknown error while writing "{self.outputFile}"',
file=sys.stderr,
)
if self.err is None
else None
)
self.err = "unknownw"
self.updated = True
elif not self.updated:
Expand Down Expand Up @@ -224,16 +301,29 @@ def _check_directives(self, outerToc: str) -> str:
_firstline_toml = re.search(r"^\+\+\+$", _firstLine)
_firstline_json = re.search(r"^{$", _firstLine)
if _firstline_yaml is not None:
_frontmatters_yaml = re.search(r"^---\n.*?\n---", _data, re.DOTALL)
_frontmatter = _frontmatters_yaml.group(0)
_frontmatters_yaml = re.search(
r"^---\n.*?\n---", _data, re.DOTALL
)
if _frontmatters_yaml is not None:
_frontmatter = _frontmatters_yaml.group(0)
else:
_frontmatter = None
elif _firstline_toml is not None:
_frontmatters_toml = re.search(
r"^\+\+\+\n.*?\n\+\+\+", _data, re.DOTALL
)
_frontmatter = _frontmatters_toml.group(0)
if _frontmatters_toml is not None:
_frontmatter = _frontmatters_toml.group(0)
else:
_frontmatter = None
elif _firstline_json is not None:
_frontmatters_json = re.search(r"^\{\n.*?\n\}", _data, re.DOTALL)
_frontmatter = _frontmatters_json.group(0)
_frontmatters_json = re.search(
r"^\{\n.*?\n\}", _data, re.DOTALL
)
if _frontmatters_json is not None:
_frontmatter = _frontmatters_json.group(0)
else:
_frontmatter = None
else:
_frontmatter = None
if _frontmatter is not None:
Expand All @@ -253,9 +343,12 @@ def _check_directives(self, outerToc: str) -> str:
else:
if _firstline_docstring is not None:
_docstrings = re.search(r'^"""\n.*?\n"""', _data, re.DOTALL)
_docstring = _docstrings.group(0)
_firstLine = _docstring
_firstFewLines = _firstLine + "\n\n" + outerToc
if _docstrings is not None:
_docstring = _docstrings.group(0)
_firstLine = _docstring
_firstFewLines = _firstLine + "\n\n" + outerToc
else:
_firstFewLines = outerToc + "\n\n" + _firstLine
else:
_firstFewLines = outerToc + "\n\n" + _firstLine
case _:
Expand Down Expand Up @@ -678,33 +771,45 @@ def _read_file(self) -> str:
with open(self.inputFile, "r") as f:
_data = f.read()
except FileNotFoundError:
print(
f'Skipping non-existing "{self.inputFile}"', file=sys.stderr
) if self.err is None else None
(
print(f'Skipping non-existing "{self.inputFile}"', file=sys.stderr)
if self.err is None
else None
)
_data = ""
self.err = "notfound"
except PermissionError:
print(
f'Skipping read-protected "{self.inputFile}"', file=sys.stderr
) if self.err is None else None
(
print(f'Skipping read-protected "{self.inputFile}"', file=sys.stderr)
if self.err is None
else None
)
_data = ""
self.err = "read"
except IsADirectoryError:
print(
f'Skipping directory "{self.inputFile}"', file=sys.stderr
) if self.err is None else None
(
print(f'Skipping directory "{self.inputFile}"', file=sys.stderr)
if self.err is None
else None
)
_data = ""
self.err = "directory"
except UnicodeDecodeError:
print(
f'Skipping binary "{self.inputFile}"', file=sys.stderr
) if self.err is None else None
(
print(f'Skipping binary "{self.inputFile}"', file=sys.stderr)
if self.err is None
else None
)
_data = ""
self.err = "binary"
except BaseException:
print(
f'Unknown error while reading "{self.inputFile}"', file=sys.stderr
) if self.err is None else None
(
print(
f'Unknown error while reading "{self.inputFile}"', file=sys.stderr
)
if self.err is None
else None
)
_data = ""
self.err = "unknownr"
finally:
Expand Down

0 comments on commit 7db654f

Please sign in to comment.