def _parse_quote_block(self, content, title, args, kwargs): _, kwargs = merge_args(args, kwargs, ["attribution"]) p = analyse(MainParser(), "\n".join(content)) self._save( QuoteNode( kwargs.pop("attribution"), content=p.nodes, kwargs=kwargs, ))
def parse_macro_image(self, args, kwargs): args, kwargs = merge_args( args, kwargs, ["uri", "alt_text", "width", "height"], ) uri = kwargs.pop("uri", None) alt_text = kwargs.pop("alt_text", None) width = kwargs.pop("width", None) height = kwargs.pop("height", None) return ImageNode(uri=uri, alt_text=alt_text, width=width, height=height)
def parse_macro_footnote(self, args, kwargs): args, kwargs = merge_args(args, kwargs, ["content"]) content_text = kwargs.get("content") refanchor, defanchor = footnote_anchors(content_text) number = self.footnotes_start_with + len(self.footnotes) p = analyse(TextParser(), content_text) self.footnotes.append( FootnoteDefNode( refanchor=refanchor, defanchor=defanchor, number=number, content=p.nodes ) ) return FootnoteRefNode(refanchor=refanchor, defanchor=defanchor, number=number)
def _parse_conditional_block(self, condition, content, args, kwargs): _, kwargs = merge_args(args, kwargs, ["variable", "value"]) match = self.variables.get(kwargs["variable"]) == kwargs.get( "value", True) test = True if condition == "if" else False if match is test: p = analyse(MainParser(variables=self.variables), "\n".join(content)) self._add_footnotes(p.footnotes) self.nodes.extend(p.nodes)
def _parse_admonition_block(self, content, args, kwargs): _, kwargs = merge_args(args, kwargs, ["class", "icon", "label"]) p = analyse(MainParser(variables=self.variables), "\n".join(content)) self._add_footnotes(p.footnotes) self._save( AdmonitionNode( admclass=kwargs.pop("class"), icon=kwargs.pop("icon"), label=kwargs.pop("label"), content=p.nodes, kwargs=kwargs, ))
def parse_macro_mailto(self, args, kwargs): args, kwargs = merge_args(args, kwargs, ["email"]) email = kwargs.get("email") target = f"mailto:{email}" return LinkNode(target, email)
def parse_macro_link(self, args, kwargs): args, kwargs = merge_args(args, kwargs, ["target", "text"]) return LinkNode(kwargs.get("target"), kwargs.get("text"))
def _parse_source_block(self, content, secondary_content, title, args, kwargs): delimiter = kwargs.pop("callouts", ":") highlight_marker = kwargs.pop("highlight", "@") # A dictionary that contains callout markers in # the form {linenum:name} callout_markers = {} # A list of highlighted lines highlighted_lines = [] lines_with_callouts = [(linenum, line) for linenum, line in enumerate(content) if line.endswith(delimiter)] for linenum, line in lines_with_callouts: # Remove the final delimiter line = line[:-1] splits = line.split(delimiter) if len(splits) < 2: # It's a trap! There are no separators left continue callout_name = splits[-1] line = delimiter.join(splits[:-1]) content[linenum] = line if callout_name == highlight_marker: highlighted_lines.append(linenum) else: callout_markers[linenum] = callout_name # A dictionary that contains the text for each # marker in the form {name:text} callout_contents = {} for line in secondary_content: if ":" not in line: raise ParseError( f"Callout description should be written as 'linuenum: text'. Missing ':' in '{line}'" ) name, text = line.split(":") if name not in callout_markers.values(): raise ParseError( f"Callout {name} has not been created in the source code") text = text.strip() callout_contents[name] = text # Put markers and contents together callouts = {"markers": callout_markers, "contents": callout_contents} # Source blocks must preserve the content literally textlines = [TextNode(line) for line in content] _, kwargs = merge_args(args, kwargs, ["language"]) language = kwargs.pop("language", "text") self._save( SourceNode( language, callouts=callouts, highlights=highlighted_lines, delimiter=delimiter, code=textlines, title=title, kwargs=kwargs, ))
def _parse_source_block(self, content, secondary_content, title, args, kwargs): delimiter = kwargs.pop("callouts", ":") # This removes callouts from the source code # and maps line numbers to callouts and text # {linenum:(callout,text)} marked_lines = {} for linenum, line in enumerate(content): if not line.endswith(delimiter): continue # Remove the final delimiter line = line[:-1] splits = line.split(delimiter) if len(splits) < 2: # It's a trap! There are no separators left continue callout_name = splits[-1] line = delimiter.join(splits[:-1]) marked_lines[linenum] = (callout_name, line) # This maps callouts names to line numbers # {callout_name:linenum} callout_name_to_linenum = {} for linenum, mark in marked_lines.items(): callout_name, fixed_line = mark content[linenum] = fixed_line callout_name_to_linenum[callout_name] = linenum # This reads the callout text and connects # it with the text line callouts = {} for line in secondary_content: if ":" not in line: raise ParseError callout_name, text = line.split(": ") try: linenum = callout_name_to_linenum[callout_name] except KeyError: raise ParseError(f"Callout {callout_name} can't be found") callouts[linenum] = (callout_name, text) # Source blocks must preserve the content literally textlines = [TextNode(line) for line in content] _, kwargs = merge_args(args, kwargs, ["language"]) language = kwargs.pop("language", "text") self._save( SourceNode( language, callouts=callouts, delimiter=delimiter, code=textlines, title=title, kwargs=kwargs, ))
def parse_macro_link(self, args, kwargs): args, kwargs = merge_args(args, kwargs, ["target", "text"]) target = kwargs.get("target") text = kwargs.get("text", target) return LinkNode(target, text)