2018-12-23 00:13:57 +01:00
|
|
|
import os
|
2020-06-11 00:54:34 +02:00
|
|
|
import re
|
2020-10-20 01:28:13 +02:00
|
|
|
from typing import Any, List
|
2018-12-23 00:13:57 +01:00
|
|
|
|
|
|
|
import markdown
|
2020-06-11 00:54:34 +02:00
|
|
|
from markdown_include.include import IncludePreprocessor, MarkdownInclude
|
2018-12-23 00:13:57 +01:00
|
|
|
|
|
|
|
from zerver.lib.exceptions import InvalidMarkdownIncludeStatement
|
|
|
|
|
|
|
|
INC_SYNTAX = re.compile(r'\{!\s*(.+?)\s*!\}')
|
|
|
|
|
|
|
|
|
|
|
|
class MarkdownIncludeCustom(MarkdownInclude):
|
2020-10-20 01:28:13 +02:00
|
|
|
def extendMarkdown(self, md: markdown.Markdown) -> None:
|
|
|
|
md.preprocessors.register(
|
2018-12-23 00:13:57 +01:00
|
|
|
IncludeCustomPreprocessor(md, self.getConfigs()),
|
2020-10-20 01:28:13 +02:00
|
|
|
'include_wrapper',
|
|
|
|
500,
|
2018-12-23 00:13:57 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
class IncludeCustomPreprocessor(IncludePreprocessor):
|
|
|
|
"""
|
|
|
|
This is a custom implementation of the markdown_include
|
|
|
|
extension that checks for include statements and if the included
|
|
|
|
macro file does not exist or can't be opened, raises a custom
|
|
|
|
JsonableError exception. The rest of the functionality is identical
|
|
|
|
to the original markdown_include extension.
|
|
|
|
"""
|
2020-04-22 01:45:30 +02:00
|
|
|
|
2018-12-23 00:13:57 +01:00
|
|
|
def run(self, lines: List[str]) -> List[str]:
|
|
|
|
done = False
|
|
|
|
while not done:
|
|
|
|
for line in lines:
|
|
|
|
loc = lines.index(line)
|
|
|
|
m = INC_SYNTAX.search(line)
|
|
|
|
|
|
|
|
if m:
|
|
|
|
filename = m.group(1)
|
|
|
|
filename = os.path.expanduser(filename)
|
|
|
|
if not os.path.isabs(filename):
|
|
|
|
filename = os.path.normpath(
|
python: Use trailing commas consistently.
Automatically generated by the following script, based on the output
of lint with flake8-comma:
import re
import sys
last_filename = None
last_row = None
lines = []
for msg in sys.stdin:
m = re.match(
r"\x1b\[35mflake8 \|\x1b\[0m \x1b\[1;31m(.+):(\d+):(\d+): (\w+)", msg
)
if m:
filename, row_str, col_str, err = m.groups()
row, col = int(row_str), int(col_str)
if filename == last_filename:
assert last_row != row
else:
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
with open(filename) as f:
lines = f.readlines()
last_filename = filename
last_row = row
line = lines[row - 1]
if err in ["C812", "C815"]:
lines[row - 1] = line[: col - 1] + "," + line[col - 1 :]
elif err in ["C819"]:
assert line[col - 2] == ","
lines[row - 1] = line[: col - 2] + line[col - 1 :].lstrip(" ")
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-10 05:23:40 +02:00
|
|
|
os.path.join(self.base_path, filename),
|
2018-12-23 00:13:57 +01:00
|
|
|
)
|
|
|
|
try:
|
2020-04-09 21:51:58 +02:00
|
|
|
with open(filename, encoding=self.encoding) as r:
|
2018-12-23 00:13:57 +01:00
|
|
|
text = r.readlines()
|
|
|
|
except Exception as e:
|
2020-06-09 00:25:09 +02:00
|
|
|
print(f'Warning: could not find file {filename}. Error: {e}')
|
2018-12-23 00:13:57 +01:00
|
|
|
lines[loc] = INC_SYNTAX.sub('', line)
|
|
|
|
raise InvalidMarkdownIncludeStatement(m.group(0).strip())
|
|
|
|
|
|
|
|
line_split = INC_SYNTAX.split(line)
|
|
|
|
if len(text) == 0:
|
|
|
|
text.append('')
|
|
|
|
for i in range(len(text)):
|
|
|
|
text[i] = text[i].rstrip('\r\n')
|
|
|
|
text[0] = line_split[0] + text[0]
|
|
|
|
text[-1] = text[-1] + line_split[2]
|
|
|
|
lines = lines[:loc] + text + lines[loc+1:]
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
done = True
|
|
|
|
|
|
|
|
return lines
|
|
|
|
|
|
|
|
def makeExtension(*args: Any, **kwargs: str) -> MarkdownIncludeCustom:
|
|
|
|
return MarkdownIncludeCustom(kwargs)
|