refactor: Add class ZulipBaseHandler to de-duplicate code.

This commit is contained in:
akshatdalton
2021-06-06 18:02:24 +00:00
committed by Tim Abbott
parent 718caf453e
commit db1cf3b521

View File

@@ -165,11 +165,39 @@ class FencedCodeExtension(Extension):
md.preprocessors.register(processor, "fenced_code_block", 25) md.preprocessors.register(processor, "fenced_code_block", 25)
class BaseHandler: class ZulipBaseHandler:
def __init__(
self,
processor: Any,
output: MutableSequence[str],
fence: Optional[str] = None,
) -> None:
self.processor = processor
self.output = output
self.fence = fence
self.lines: List[str] = []
def handle_line(self, line: str) -> None: def handle_line(self, line: str) -> None:
raise NotImplementedError() if line.rstrip() == self.fence:
self.done()
else:
self.lines.append(line.rstrip())
def done(self) -> None: def done(self) -> None:
if self.lines:
text = "\n".join(self.lines)
text = self.format_text(text)
text = self.processor.placeholder(text)
processed_lines = text.split("\n")
self.output.append("")
self.output.extend(processed_lines)
self.output.append("")
self.processor.pop()
def format_text(self, text: str) -> str:
"""Returns a formatted text.
Subclasses should override this method.
"""
raise NotImplementedError() raise NotImplementedError()
@@ -181,7 +209,7 @@ def generic_handler(
header: str, header: str,
run_content_validators: bool = False, run_content_validators: bool = False,
default_language: Optional[str] = None, default_language: Optional[str] = None,
) -> BaseHandler: ) -> ZulipBaseHandler:
lang = lang.lower() lang = lang.lower()
if lang in ("quote", "quoted"): if lang in ("quote", "quoted"):
return QuoteHandler(processor, output, fence, default_language) return QuoteHandler(processor, output, fence, default_language)
@@ -215,7 +243,7 @@ def check_for_new_fence(
output.append(line) output.append(line)
class OuterHandler(BaseHandler): class OuterHandler(ZulipBaseHandler):
def __init__( def __init__(
self, self,
processor: Any, processor: Any,
@@ -223,21 +251,17 @@ class OuterHandler(BaseHandler):
run_content_validators: bool = False, run_content_validators: bool = False,
default_language: Optional[str] = None, default_language: Optional[str] = None,
) -> None: ) -> None:
self.output = output
self.processor = processor
self.run_content_validators = run_content_validators self.run_content_validators = run_content_validators
self.default_language = default_language self.default_language = default_language
super().__init__(processor, output)
def handle_line(self, line: str) -> None: def handle_line(self, line: str) -> None:
check_for_new_fence( check_for_new_fence(
self.processor, self.output, line, self.run_content_validators, self.default_language self.processor, self.output, line, self.run_content_validators, self.default_language
) )
def done(self) -> None:
self.processor.pop()
class CodeHandler(ZulipBaseHandler):
class CodeHandler(BaseHandler):
def __init__( def __init__(
self, self,
processor: Any, processor: Any,
@@ -246,37 +270,22 @@ class CodeHandler(BaseHandler):
lang: str, lang: str,
run_content_validators: bool = False, run_content_validators: bool = False,
) -> None: ) -> None:
self.processor = processor
self.output = output
self.fence = fence
self.lang = lang self.lang = lang
self.lines: List[str] = []
self.run_content_validators = run_content_validators self.run_content_validators = run_content_validators
super().__init__(processor, output, fence)
def handle_line(self, line: str) -> None:
if line.rstrip() == self.fence:
self.done()
else:
self.lines.append(line.rstrip())
def done(self) -> None: def done(self) -> None:
text = "\n".join(self.lines)
# run content validators (if any) # run content validators (if any)
if self.run_content_validators: if self.run_content_validators:
validator = CODE_VALIDATORS.get(self.lang, lambda text: None) validator = CODE_VALIDATORS.get(self.lang, lambda text: None)
validator(self.lines) validator(self.lines)
super().done()
text = self.processor.format_code(self.lang, text) def format_text(self, text: str) -> str:
text = self.processor.placeholder(text) return self.processor.format_code(self.lang, text)
processed_lines = text.split("\n")
self.output.append("")
self.output.extend(processed_lines)
self.output.append("")
self.processor.pop()
class QuoteHandler(BaseHandler): class QuoteHandler(ZulipBaseHandler):
def __init__( def __init__(
self, self,
processor: Any, processor: Any,
@@ -284,11 +293,8 @@ class QuoteHandler(BaseHandler):
fence: str, fence: str,
default_language: Optional[str] = None, default_language: Optional[str] = None,
) -> None: ) -> None:
self.processor = processor
self.output = output
self.fence = fence
self.lines: List[str] = []
self.default_language = default_language self.default_language = default_language
super().__init__(processor, output, fence)
def handle_line(self, line: str) -> None: def handle_line(self, line: str) -> None:
if line.rstrip() == self.fence: if line.rstrip() == self.fence:
@@ -301,6 +307,8 @@ class QuoteHandler(BaseHandler):
def done(self) -> None: def done(self) -> None:
text = "\n".join(self.lines) text = "\n".join(self.lines)
text = self.processor.format_quote(text) text = self.processor.format_quote(text)
# Here we don't use placeholder as we may further
# want to process the text inside the quote.
processed_lines = text.split("\n") processed_lines = text.split("\n")
self.output.append("") self.output.append("")
self.output.extend(processed_lines) self.output.extend(processed_lines)
@@ -308,15 +316,12 @@ class QuoteHandler(BaseHandler):
self.processor.pop() self.processor.pop()
class SpoilerHandler(BaseHandler): class SpoilerHandler(ZulipBaseHandler):
def __init__( def __init__(
self, processor: Any, output: MutableSequence[str], fence: str, spoiler_header: str self, processor: Any, output: MutableSequence[str], fence: str, spoiler_header: str
) -> None: ) -> None:
self.processor = processor
self.output = output
self.fence = fence
self.spoiler_header = spoiler_header self.spoiler_header = spoiler_header
self.lines: List[str] = [] super().__init__(processor, output, fence)
def handle_line(self, line: str) -> None: def handle_line(self, line: str) -> None:
if line.rstrip() == self.fence: if line.rstrip() == self.fence:
@@ -328,35 +333,11 @@ class SpoilerHandler(BaseHandler):
if len(self.lines) == 0: if len(self.lines) == 0:
# No content, do nothing # No content, do nothing
return return
else:
header = self.spoiler_header
text = "\n".join(self.lines)
text = self.processor.format_spoiler(header, text)
processed_lines = text.split("\n")
self.output.append("")
self.output.extend(processed_lines)
self.output.append("")
self.processor.pop()
class TexHandler(BaseHandler):
def __init__(self, processor: Any, output: MutableSequence[str], fence: str) -> None:
self.processor = processor
self.output = output
self.fence = fence
self.lines: List[str] = []
def handle_line(self, line: str) -> None:
if line.rstrip() == self.fence:
self.done()
else:
self.lines.append(line)
def done(self) -> None:
text = "\n".join(self.lines) text = "\n".join(self.lines)
text = self.processor.format_tex(text) text = self.processor.format_spoiler(self.spoiler_header, text)
text = self.processor.placeholder(text) # Here we don't use placeholder as we may further
# want to process the text inside the spoiler.
processed_lines = text.split("\n") processed_lines = text.split("\n")
self.output.append("") self.output.append("")
self.output.extend(processed_lines) self.output.extend(processed_lines)
@@ -364,6 +345,11 @@ class TexHandler(BaseHandler):
self.processor.pop() self.processor.pop()
class TexHandler(ZulipBaseHandler):
def format_text(self, text: str) -> str:
return self.processor.format_tex(text)
class FencedBlockPreprocessor(Preprocessor): class FencedBlockPreprocessor(Preprocessor):
def __init__(self, md: Markdown, run_content_validators: bool = False) -> None: def __init__(self, md: Markdown, run_content_validators: bool = False) -> None:
super().__init__(md) super().__init__(md)
@@ -372,7 +358,7 @@ class FencedBlockPreprocessor(Preprocessor):
self.run_content_validators = run_content_validators self.run_content_validators = run_content_validators
self.codehilite_conf: Mapping[str, Sequence[Any]] = {} self.codehilite_conf: Mapping[str, Sequence[Any]] = {}
def push(self, handler: BaseHandler) -> None: def push(self, handler: ZulipBaseHandler) -> None:
self.handlers.append(handler) self.handlers.append(handler)
def pop(self) -> None: def pop(self) -> None:
@@ -384,7 +370,7 @@ class FencedBlockPreprocessor(Preprocessor):
output: List[str] = [] output: List[str] = []
processor = self processor = self
self.handlers: List[BaseHandler] = [] self.handlers: List[ZulipBaseHandler] = []
default_language = None default_language = None
try: try: