#!/usr/bin/env python3 # Based on https://gist.github.com/mastbaum/2655700 for the basic plugin scaffolding import sys import re import docutils.core from docutils.transforms import Transform from docutils.nodes import TextElement, Inline, Text from docutils.parsers.rst import Directive, directives from docutils.writers.html4css1 import Writer, HTMLTranslator class UnfuckedHTMLTranslator(HTMLTranslator): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.in_literal_block = False def visit_literal_block(self, node): # Insert an empty "lineno" span before each line. We insert the line numbers using pure CSS in a ::before # pseudo-element. This has the added advantage that the line numbers don't get included in text selection. # These line number spans are also used to show line continuation markers when a line is wrapped. self.in_literal_block = True self.body.append(self.starttag(node, 'pre', CLASS='literal-block')) self.body.append('') def depart_literal_block(self, node): self.in_literal_block = False self.body.append('\n\n') def visit_Text(self, node): if self.in_literal_block: for match in re.finditer('([^\n]*)(\n|$)', node.astext()): text, end = match.groups() if text: super().visit_Text(Text(text)) if end == '\n': if isinstance(node.parent, Inline): self.depart_inline(node.parent) self.body.append(f'\n') if isinstance(node.parent, Inline): self.visit_inline(node.parent) else: super().visit_Text(node) html_writer = Writer() html_writer.translator_class = UnfuckedHTMLTranslator docutils.core.publish_cmdline(writer=html_writer)