diff --git a/.github/workflows/ruff.yml b/.github/workflows/ruff.yml
new file mode 100644
index 0000000..1f323b2
--- /dev/null
+++ b/.github/workflows/ruff.yml
@@ -0,0 +1,16 @@
+name: Ruff
+on: pull_request
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+jobs:
+ ruff:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: astral-sh/ruff-action@v3
+ with:
+ args: check --output-format=github
+ - uses: astral-sh/ruff-action@v3
+ with:
+ args: format --diff
\ No newline at end of file
diff --git a/api/directus.py b/api/directus.py
index 1c9bd4d..0258fcf 100644
--- a/api/directus.py
+++ b/api/directus.py
@@ -8,7 +8,7 @@ class DirectusAPI:
self.base_url = base_url
self.access_token = access_token
- def __get_raw(self, endpoint, params = None):
+ def __get_raw(self, endpoint, params=None):
if params is None:
params = {}
for k in params.keys():
@@ -16,16 +16,11 @@ class DirectusAPI:
params[k] = json.dumps(params[k])
url = self.base_url + endpoint
result = requests.get(
- url,
- params = params,
- headers = {
- "Authorization": f"Bearer {self.access_token}",
- "Cache-Control": "no-store"
- }
+ url, params=params, headers={"Authorization": f"Bearer {self.access_token}", "Cache-Control": "no-store"}
)
return result
- def get(self, endpoint, params = None):
+ def get(self, endpoint, params=None):
if params is None:
params = {}
result = self.__get_raw(endpoint, params)
@@ -39,8 +34,8 @@ class DirectusAPI:
print(f"Error: {e}")
return None
return data
-
- def get_one(self, endpoint, params = None):
+
+ def get_one(self, endpoint, params=None):
if params is None:
params = {}
results = self.get(endpoint, params)
@@ -50,12 +45,12 @@ class DirectusAPI:
return None
else:
raise Exception("One result expected, but got more than one result")
-
- def get_file(self, endpoint, params = None):
+
+ def get_file(self, endpoint, params=None):
if params is None:
params = {}
result = self.__get_raw(endpoint, params)
data = result.content
if data is None:
raise Exception("No data from API")
- return data
\ No newline at end of file
+ return data
diff --git a/pyproject.toml b/pyproject.toml
index c1d7ca4..6e37258 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -15,6 +15,7 @@ select = [
# pycodestyle
# Ensure PEP8-compatible code style.
"E",
+ "W",
# pep8-naming
# Ensure consisten, PEP8-compatible naming.
"N",
@@ -38,6 +39,11 @@ select = [
"C90",
# ruff-specific: No unused noqa directives
"RUF100",
+ ## Write modern python code
+ # Use f-strings instead of joining strings
+ "FLY",
+ # Check refurb rules
+ "FURB",
]
[tool.pytest.ini_options]
diff --git a/renderer/comment.py b/renderer/comment.py
index 7626af8..9a3251c 100644
--- a/renderer/comment.py
+++ b/renderer/comment.py
@@ -1,7 +1,6 @@
import re
from mistletoe.block_token import BlockToken
-from mistletoe.span_token import SpanToken
class BlockComment(BlockToken):
diff --git a/renderer/fifty_ohm_html_renderer.py b/renderer/fifty_ohm_html_renderer.py
index c61e5a9..b53d4e8 100644
--- a/renderer/fifty_ohm_html_renderer.py
+++ b/renderer/fifty_ohm_html_renderer.py
@@ -172,7 +172,10 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
return f"{lookup[token.first]}{token.second}{lookup[token.third]}"
def render_references(self, token):
- return f'{self.ref_id}'
+ return (
+ f'{self.ref_id}"
+ )
def render_question(self, token):
return self.question_renderer(token.question_number)
diff --git a/renderer/fifty_ohm_latex_renderer.py b/renderer/fifty_ohm_latex_renderer.py
index 48ea836..21a9883 100644
--- a/renderer/fifty_ohm_latex_renderer.py
+++ b/renderer/fifty_ohm_latex_renderer.py
@@ -27,7 +27,7 @@ class FiftyOhmLaTeXRenderer(LaTeXRenderer):
Question,
Picture,
Photo,
- Table
+ Table,
)
self.question_renderer = question_renderer
@@ -87,7 +87,7 @@ class FiftyOhmLaTeXRenderer(LaTeXRenderer):
return rf"\{tagtype}{{{self.render_inner(token)}}}"
def render_halfwidth_spaces(self, token):
- return f"{token.first}.\,{token.second}."
+ return rf"{token.first}.\,{token.second}."
def render_nonbreaking_spaces(self, token):
return f"{token.first}~{token.second}"
@@ -105,7 +105,7 @@ class FiftyOhmLaTeXRenderer(LaTeXRenderer):
\captionof{{figure}}{{{text}}}
\label{{{ref}}}"""
- def render_picture(self, token) :
+ def render_picture(self, token):
return self.render_picture_helper(token.id, token.ref, token.text, token.number)
@staticmethod
@@ -114,26 +114,26 @@ class FiftyOhmLaTeXRenderer(LaTeXRenderer):
\captionof{{figure}}{{{text}}}
\label{{{ref}}}"""
- def render_photo(self, token) :
+ def render_photo(self, token):
return self.render_photo_helper(token.id, token.ref, token.text, token.number)
def render_table(self, token):
alignments = token.alignment
align = ""
- for alignment in alignments :
+ for alignment in alignments:
align += alignment
table = f"\\begin{{DARCtabular}}{{{align}}}\n"
-
+
for row in token.children:
for j, cell in enumerate(row.children):
table += self.render_inner(cell)
if j < len(row.children) - 1:
table += " & "
- table += r"\\"+ "\n"
+ table += r"\\" + "\n"
table += "\\end{DARCtabular}"
- if token.caption != "" :
+ if token.caption != "":
table += f"\\captionof{{figure}}{{{token.caption}}}\n"
table += f"\\label{{{token.name}}}\n"
diff --git a/renderer/include.py b/renderer/include.py
index 9f2a690..0cf92d3 100644
--- a/renderer/include.py
+++ b/renderer/include.py
@@ -15,10 +15,10 @@ class Include(BlockToken):
@classmethod
def read(cls, lines):
- re.compile(r'')
- line = next(lines) # Consume the line with the include directive
+ re.compile(r"")
+ line = next(lines) # Consume the line with the include directive
ident = re.match(r"^\s*\[include:\s*([^\]]+)\]", line).group(1)
return ident
def __init__(self, match):
- self.ident = match
\ No newline at end of file
+ self.ident = match
diff --git a/renderer/morse.py b/renderer/morse.py
index 72eabe6..e47ba86 100644
--- a/renderer/morse.py
+++ b/renderer/morse.py
@@ -87,4 +87,4 @@ class Morse(SpanToken):
return result
parse_inner = False
- pattern = re.compile(r'\[morse:\s*([^\]]+)\]')
+ pattern = re.compile(r"\[morse:\s*([^\]]+)\]")
diff --git a/renderer/photo.py b/renderer/photo.py
index c167887..5634372 100644
--- a/renderer/photo.py
+++ b/renderer/photo.py
@@ -16,4 +16,4 @@ class Photo(SpanToken):
self.id = match_object.group(1)
self.ref = match_object.group(2)
self.text = match_object.group(3)
- self.number = "TODO"
\ No newline at end of file
+ self.number = "TODO"
diff --git a/renderer/picture.py b/renderer/picture.py
index acfe82c..0477185 100644
--- a/renderer/picture.py
+++ b/renderer/picture.py
@@ -16,4 +16,4 @@ class Picture(SpanToken):
self.id = match_object.group(1)
self.ref = match_object.group(2)
self.text = match_object.group(3)
- self.number = "TODO"
\ No newline at end of file
+ self.number = "TODO"
diff --git a/renderer/qso.py b/renderer/qso.py
index 6571696..2359ffc 100644
--- a/renderer/qso.py
+++ b/renderer/qso.py
@@ -25,6 +25,7 @@ class Qso(BlockToken):
def __init__(self, match):
self.children = match
+
class QsoLine(BlockToken):
@classmethod
def parse_line(cls, line):
diff --git a/test/test_comment.py b/test/test_comment.py
index dedb47f..68118f9 100644
--- a/test/test_comment.py
+++ b/test/test_comment.py
@@ -24,7 +24,7 @@ def test_comment_latex():
assertions = {
"%Comment\nBar": "% Comment\n\nBar\n",
"%Comment\n": "% Comment\n",
- "Foo 100 % Bar": "\nFoo 100 \% Bar\n",
+ "Foo 100 % Bar": "\nFoo 100 \\% Bar\n",
"Foo\n%Comment\nBar": "\nFoo\n% Comment\n\nBar\n",
}
diff --git a/test/test_halfwidth_spaces.py b/test/test_halfwidth_spaces.py
index 97a57ac..b2e29c7 100644
--- a/test/test_halfwidth_spaces.py
+++ b/test/test_halfwidth_spaces.py
@@ -17,6 +17,6 @@ def test_halfwidth_space_html():
@pytest.mark.latex
def test_halfwidth_space_latex():
input = "Dies ist z.B. ein Test. D.h. hier sollten d.h. Spaces ersetzt worden sein."
- target = "\nDies ist z.\,B. ein Test. D.\,h. hier sollten d.\,h. Spaces ersetzt worden sein.\n"
+ target = "\nDies ist z.\\,B. ein Test. D.\\,h. hier sollten d.\\,h. Spaces ersetzt worden sein.\n"
assert mistletoe.markdown(input, FiftyOhmLaTeXRenderer) == target
diff --git a/test/test_html.py b/test/test_html.py
index 05b8964..714bb34 100644
--- a/test/test_html.py
+++ b/test/test_html.py
@@ -69,11 +69,13 @@ def question_stub(input):
answer_pictures=answer_pictures,
)
+
def include_stub(include):
with open("data/includes.json") as file:
includes = json.load(file)
return includes.get(include)
+
def test_html(capsys):
with capsys.disabled():
with open("test/acceptanceTest.md") as file:
diff --git a/test/test_include.py b/test/test_include.py
index 24c02f7..4b024a4 100644
--- a/test/test_include.py
+++ b/test/test_include.py
@@ -7,7 +7,7 @@ from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
@pytest.mark.html
def test_include_html():
assertions = {
- '[include:ident]': "ident\n",
+ "[include:ident]": "ident\n",
}
def test_function(input):
@@ -15,4 +15,4 @@ def test_include_html():
with FiftyOhmHtmlRenderer(include_handler=test_function) as renderer:
for assertion in assertions:
- assert renderer.render(Document(assertion)) == assertions[assertion]
\ No newline at end of file
+ assert renderer.render(Document(assertion)) == assertions[assertion]
diff --git a/test/test_morse.py b/test/test_morse.py
index 9985209..8a80fc2 100644
--- a/test/test_morse.py
+++ b/test/test_morse.py
@@ -8,12 +8,12 @@ from test.util import paragraph
@pytest.mark.html
def test_morse_html():
assertions = {
- '[morse:a]': FiftyOhmHtmlRenderer.render_morse_helper([[1, 2]]),
- '[morse:a] abc [morse:a]': FiftyOhmHtmlRenderer.render_morse_helper([[1, 2]])+ ' abc ' + FiftyOhmHtmlRenderer.render_morse_helper([[1, 2]]),
- '[morse: a]': FiftyOhmHtmlRenderer.render_morse_helper([[1, 2]]),
- '[morse: aaa]': FiftyOhmHtmlRenderer.render_morse_helper([[1, 2], [1, 2], [1, 2]]),
- '[morse: a a]': FiftyOhmHtmlRenderer.render_morse_helper([[1, 2], [3], [1, 2]]),
- '[morse: db0]': FiftyOhmHtmlRenderer.render_morse_helper([[2, 1, 1], [2, 1, 1, 1], [2, 2, 2, 2, 2]]),
+ "[morse:a]": FiftyOhmHtmlRenderer.render_morse_helper([[1, 2]]),
+ "[morse:a] abc [morse:a]": f"{FiftyOhmHtmlRenderer.render_morse_helper([[1, 2]])} abc {FiftyOhmHtmlRenderer.render_morse_helper([[1, 2]])}", # noqa: E501
+ "[morse: a]": FiftyOhmHtmlRenderer.render_morse_helper([[1, 2]]),
+ "[morse: aaa]": FiftyOhmHtmlRenderer.render_morse_helper([[1, 2], [1, 2], [1, 2]]),
+ "[morse: a a]": FiftyOhmHtmlRenderer.render_morse_helper([[1, 2], [3], [1, 2]]),
+ "[morse: db0]": FiftyOhmHtmlRenderer.render_morse_helper([[2, 1, 1], [2, 1, 1, 1], [2, 2, 2, 2, 2]]),
}
for assertion in assertions:
diff --git a/test/test_nonbreaking_spaces.py b/test/test_nonbreaking_spaces.py
index 4b52992..68839d8 100644
--- a/test/test_nonbreaking_spaces.py
+++ b/test/test_nonbreaking_spaces.py
@@ -18,7 +18,7 @@ def test_paragraph_html():
def test_three_points_html():
assertions = {
"Heute hatte ich ... zum Mittagessen.": "Heute hatte ich ... zum Mittagessen.",
- "Niemals hätte ich gedacht, dass...ich ...nicht kann.": "Niemals hätte ich gedacht, dass...ich ...nicht kann.",
+ "Niemals hätte ich gedacht, dass...ich ...nicht kann.": "Niemals hätte ich gedacht, dass...ich ...nicht kann.", # noqa: E501
"Oh nein ...ein Pinguin.": "Oh nein ...ein Pinguin.",
"Haha .. . Hahaha": "Haha .. . Hahaha",
}
@@ -55,7 +55,7 @@ def test_paragraph_latex():
def test_three_points_latex():
assertions = {
"Heute hatte ich ... zum Mittagessen.": "\nHeute hatte ich~...~zum Mittagessen.\n",
- "Niemals hätte ich gedacht, dass...ich ...nicht kann.": "\nNiemals hätte ich gedacht, dass...ich~...nicht kann.\n",
+ "Niemals hätte ich gedacht, dass...ich ...nicht kann.": "\nNiemals hätte ich gedacht, dass...ich~...nicht kann.\n", # noqa: E501
"Oh nein ...ein Pinguin.": "\nOh nein~...ein Pinguin.\n",
"Haha .. . Hahaha": "\nHaha .. . Hahaha\n",
}
diff --git a/test/test_qso.py b/test/test_qso.py
index 231c70c..50bdfa2 100644
--- a/test/test_qso.py
+++ b/test/test_qso.py
@@ -23,11 +23,11 @@ def test_qso_html():
for assertion in assertions:
assert mistletoe.markdown(assertion, FiftyOhmHtmlRenderer) == assertions[assertion]
+
@pytest.mark.slide
def test_qso_slide():
assertions = {
- "\nfoo\n> bar\n":
- '
\n\n',
+ "\nfoo\n> bar\n": '\n\n', # noqa: E501
}
for assertion in assertions:
diff --git a/test/test_question.py b/test/test_question.py
index 526677d..e4e4ceb 100644
--- a/test/test_question.py
+++ b/test/test_question.py
@@ -24,6 +24,7 @@ def test_question_html():
for assertion in assertions:
assert renderer.render(Document(assertion)) == assertions[assertion]
+
@pytest.mark.html
def test_question_translation_html():
assertions = {
@@ -34,7 +35,7 @@ def test_question_translation_html():
}
def test_function(input):
- with open('data/metadata.json') as file:
+ with open("data/metadata.json") as file:
metadata = json.load(file)
return metadata[f"{input}"].get("number")
@@ -46,14 +47,14 @@ def test_question_translation_html():
@pytest.mark.latex
def test_question_latex():
assertions = {
- "[question:123]": "\question{123}",
- "\n[question:123]\n": "\question{123}",
- "\n[question:123]\n[question:123]": "\question{123}\question{123}",
- "Foo\n[question:123]\nBar": "\nFoo\n\question{123}\nBar\n",
+ "[question:123]": r"\question{123}",
+ "\n[question:123]\n": r"\question{123}",
+ "\n[question:123]\n[question:123]": r"\question{123}\question{123}",
+ "Foo\n[question:123]\nBar": "\nFoo\n\\question{123}\nBar\n",
}
def test_function(input):
- return "\\question{"+input+"}"
+ return "\\question{" + input + "}"
with FiftyOhmLaTeXRenderer(test_function) as renderer:
for assertion in assertions:
diff --git a/test/test_quote.py b/test/test_quote.py
index a83f8e8..64ff664 100644
--- a/test/test_quote.py
+++ b/test/test_quote.py
@@ -24,11 +24,11 @@ def test_quote_html():
@pytest.mark.latex
def test_quote_latex():
assertions = {
- '"quote"': "\n\enquote{quote}\n",
- '" quote "': "\n\enquote{ quote }\n",
- '"quote" "': '\n\enquote{quote} "\n',
- '"quo te1" filltext "qu ot e2"': "\n\enquote{quo te1} filltext \enquote{qu ot e2}\n",
- '"quo *te1*" filltext "qu ot e2"': "\n\enquote{quo \emph{te1}} filltext \enquote{qu ot e2}\n",
+ '"quote"': "\n\\enquote{quote}\n",
+ '" quote "': "\n\\enquote{ quote }\n",
+ '"quote" "': '\n\\enquote{quote} "\n',
+ '"quo te1" filltext "qu ot e2"': "\n\\enquote{quo te1} filltext \\enquote{qu ot e2}\n",
+ '"quo *te1*" filltext "qu ot e2"': "\n\\enquote{quo \\emph{te1}} filltext \\enquote{qu ot e2}\n",
'""': '\n""\n',
}
diff --git a/test/test_references.py b/test/test_references.py
index 4d60018..ab332b4 100644
--- a/test/test_references.py
+++ b/test/test_references.py
@@ -10,9 +10,9 @@ def test_references_html():
# Right now this tests only the default values.
# The correct behavior can be tested when the information is added to the renderer class
assertions = {
- "[ref:e_oszilloskop_bildschirmfoto_sinus]": '0',
+ "[ref:e_oszilloskop_bildschirmfoto_sinus]": '0', # noqa: E501
"[ref:n_rst_r]": '0',
- "[ref:Uuuuuh]": '0', # Test the default parameters
+ "[ref:Uuuuuh]": '0', # Test the default parameters # noqa: E501
}
for key, value in assertions.items():
diff --git a/test/test_table.py b/test/test_table.py
index 1c507fd..deaba13 100644
--- a/test/test_table.py
+++ b/test/test_table.py
@@ -11,14 +11,14 @@ def test_table_html():
"| l: a |": '\n',
"| r: a |": '\n',
"| c: a |": '\n',
- "| l: a |\n| b |": '\n',
- "| l: a |\n| b |\n| c |": '\n',
- "| a |\n| b |\n| c |": "\n",
- "| l: a |\n| *b* |": '\n',
- "| l: a |\n| b |\n[table:n_ab:A und B]": '\n',
+ "| l: a |\n| b |": '\n', # noqa: E501
+ "| l: a |\n| b |\n| c |": '\n', # noqa: E501
+ "| a |\n| b |\n| c |": "\n", # noqa: E501
+ "| l: a |\n| *b* |": '\n', # noqa: E501
+ "| l: a |\n| b |\n[table:n_ab:A und B]": '\n', # noqa: E501
"| l: *a* |": '\n',
- "| l: a |\n| [morse:a] |": '\n\n| a | \n
\n\n| \n\n▄\n\n▄▄▄\n\n | \n
\n
\n',
- "| l: abc | r: abc | X: abc |\n| 123 | 456 | 789 | \n | 987 | 654 | 321 | ": '\n\n| abc | \nabc | \nabc | \n
\n\n| 123 | \n456 | \n789 | \n
\n\n| 987 | \n654 | \n321 | \n
\n
\n',
+ "| l: a |\n| [morse:a] |": '\n\n| a | \n
\n\n| \n\n▄\n\n▄▄▄\n\n | \n
\n
\n', # noqa: E501
+ "| l: abc | r: abc | X: abc |\n| 123 | 456 | 789 | \n | 987 | 654 | 321 | ": '\n\n| abc | \nabc | \nabc | \n
\n\n| 123 | \n456 | \n789 | \n
\n\n| 987 | \n654 | \n321 | \n
\n
\n', # noqa: E501
}
with FiftyOhmHtmlRenderer() as renderer:
diff --git a/test/test_tag.py b/test/test_tag.py
index 4af938d..2b2c493 100644
--- a/test/test_tag.py
+++ b/test/test_tag.py
@@ -76,17 +76,17 @@ def test_thematic_break_latex():
@pytest.mark.latex
def test_tag_latex():
assertions = {
- "\nFoo\n": "\Margin{\nFoo\n}",
- "\nFoo\n": "\MarginDanger{\nFoo\n}",
- "\nFoo\n": "\MarginWarning{\nFoo\n}",
- "\nFoo\n": "\MarginAttention{\nFoo\n}",
- "\nFoo\n": "\MarginTip{\nFoo\n}",
- "\nFoo\n": "\WebTip{\nFoo\n}",
- "\nFoo\n": "\MarginUnit{\nFoo\n}",
- "\nFoo\n": "\MarginInDepth{\nFoo\n}",
- "\nFoo\n": "\MarginWebInDepth{\nFoo\n}",
- "\nFoo\n": "\WebMargin{\nFoo\n}",
- "\nFoo\n": "\FullWidth{\nFoo\n}",
+ "\nFoo\n": "\\Margin{\nFoo\n}",
+ "\nFoo\n": "\\MarginDanger{\nFoo\n}",
+ "\nFoo\n": "\\MarginWarning{\nFoo\n}",
+ "\nFoo\n": "\\MarginAttention{\nFoo\n}",
+ "\nFoo\n": "\\MarginTip{\nFoo\n}",
+ "\nFoo\n": "\\WebTip{\nFoo\n}",
+ "\nFoo\n": "\\MarginUnit{\nFoo\n}",
+ "\nFoo\n": "\\MarginInDepth{\nFoo\n}",
+ "\nFoo\n": "\\MarginWebInDepth{\nFoo\n}",
+ "\nFoo\n": "\\WebMargin{\nFoo\n}",
+ "\nFoo\n": "\\FullWidth{\nFoo\n}",
"\nFoo\n": "\nFoo\n",
"\nFoo\n": "",
}
@@ -98,9 +98,9 @@ def test_tag_latex():
@pytest.mark.latex
def test_thematic_break_and_tag_latex():
assertions = {
- "---\n\nFoo\n": "\Margin{\nFoo\n}",
- "---\n\nFoo\n\n\nFoo\n": "\Margin{\nFoo\n}\Margin{\nFoo\n}",
- "---\n\nFoo\n\n---\n\nFoo\n": "\Margin{\nFoo\n}\Margin{\nFoo\n}",
+ "---\n\nFoo\n": "\\Margin{\nFoo\n}",
+ "---\n\nFoo\n\n\nFoo\n": "\\Margin{\nFoo\n}\\Margin{\nFoo\n}",
+ "---\n\nFoo\n\n---\n\nFoo\n": "\\Margin{\nFoo\n}\\Margin{\nFoo\n}",
}
for assertion in assertions:
diff --git a/test/test_underline.py b/test/test_underline.py
index 9edfe16..ec22438 100644
--- a/test/test_underline.py
+++ b/test/test_underline.py
@@ -23,7 +23,7 @@ def test_underline_latex():
assertions = {
"Text": "\n\\underline{Text}\n",
" Text Text ": "\n\\underline{ Text Text }\n",
- " Text *Text* ": "\n\\underline{ Text \emph{Text} }\n",
+ " Text *Text* ": "\n\\underline{ Text \\emph{Text} }\n",
}
for assertion in assertions: