Subclassing formatters ====================== .. currentmodule:: pweave In the previous section we customized the output format by altering the format dictionary. Sometimes more advanced customizations are needed. This can be done by subclassing `Existing formatters `_ . The base class PwebFormatter has a method :py:meth:`preformat_chunk` that processes all chunks before they are processed by default formatters. Suppose I have this `document <_static/ma.mdw>`_ (view the source in browser) using markdown markup and I want convert the doc chunks to HTML and output code chunks using Pweave default HTML formatter. I can do this by subclassing :py:class:`PwebHTMLFormatter`. MDtoHTML class below converts the content of all documentation chunks to HTML using python `Markdown `_ package. (:py:attr:`chunk['type']` for code chunks is "code"). *The class also stores the chunks for us to see what they contain, but that's not needed for formatting.* .. code-block:: python from pweave import * import markdown class MDtoHTML(PwebHTMLFormatter): chunks = [] #Let's keep a copy of chunks def preformat_chunk(self, chunk): MDtoHTML.chunks.append(chunk.copy()) #Store the chunks if chunk['type'] == "doc": chunk['content'] = markdown.markdown(chunk['content']) return(chunk) The specified subclass can then be used as formatter with :py:class:`Pweb` class. .. code-block:: python doc = Pweb('ma.mdw') doc.setformat(Formatter = MDtoHTML) doc.weave() :: ---------------------------------------------------------------------------FileNotFoundError Traceback (most recent call last)~/anaconda3/lib/python3.6/site- packages/pweave/readers.py in read_file_or_url(source) 15 try: ---> 16 codefile = io.open(source, 'r', encoding='utf-8') 17 contents = codefile.read() FileNotFoundError: [Errno 2] No such file or directory: 'ma.mdw' During handling of the above exception, another exception occurred: ValueError Traceback (most recent call last) in () ----> 1 doc = Pweb('ma.mdw') 2 doc.setformat(Formatter = MDtoHTML) 3 doc.weave() ~/anaconda3/lib/python3.6/site-packages/pweave/pweb.py in __init__(self, source, doctype, informat, kernel, output, figdir, mimetype) 68 69 self.setformat(doctype) ---> 70 self.read(reader = informat) 71 72 def _setwd(self): ~/anaconda3/lib/python3.6/site-packages/pweave/pweb.py in read(self, string, basename, reader) 106 107 if string is None: --> 108 self.reader = Reader(file=self.source) 109 else: 110 self.reader = self.Reader(string=string) ~/anaconda3/lib/python3.6/site-packages/pweave/readers.py in __init__(self, file, string) 36 # Get input from string or 37 if file is not None: ---> 38 self.rawtext = read_file_or_url(self.source) 39 else: 40 self.rawtext = string ~/anaconda3/lib/python3.6/site-packages/pweave/readers.py in read_file_or_url(source) 18 codefile.close() 19 except IOError: ---> 20 r = request.urlopen(source) 21 contents = r.read().decode("utf-8") 22 r.close() ~/anaconda3/lib/python3.6/urllib/request.py in urlopen(url, data, timeout, cafile, capath, cadefault, context) 221 else: 222 opener = _opener --> 223 return opener.open(url, data, timeout) 224 225 def install_opener(opener): ~/anaconda3/lib/python3.6/urllib/request.py in open(self, fullurl, data, timeout) 509 # accept a URL or a Request object 510 if isinstance(fullurl, str): --> 511 req = Request(fullurl, data) 512 else: 513 req = fullurl ~/anaconda3/lib/python3.6/urllib/request.py in __init__(self, url, data, headers, origin_req_host, unverifiable, method) 327 origin_req_host=None, unverifiable=False, 328 method=None): --> 329 self.full_url = url 330 self.headers = {} 331 self.unredirected_hdrs = {} ~/anaconda3/lib/python3.6/urllib/request.py in full_url(self, url) 353 self._full_url = unwrap(url) 354 self._full_url, self.fragment = splittag(self._full_url) --> 355 self._parse() 356 357 @full_url.deleter ~/anaconda3/lib/python3.6/urllib/request.py in _parse(self) 382 self.type, rest = splittype(self._full_url) 383 if self.type is None: --> 384 raise ValueError("unknown url type: %r" % self.full_url) 385 self.host, self.selector = splithost(rest) 386 if self.host: ValueError: unknown url type: 'ma.mdw' And `here <_static/ma.html>`_ is the weaved document. A closer look at the chunks --------------------------- Remember that we kept a copy of the chunks in the previous example? As you can see below the chunk is a dictionary that contains code, results and all of the chunk options. You can manipulate all of these options as we did to content in previous example to control how the chunk is formatted in output. .. note:: You can your own options (key = value) to chunks and they will also appear in the chunk dictionary. Let's see what the first code chunk contains: .. code-block:: python import pprint pprint.pprint(MDtoHTML.chunks[1]) :: ---------------------------------------------------------------------------IndexError Traceback (most recent call last) in () 1 import pprint ----> 2 pprint.pprint(MDtoHTML.chunks[1]) IndexError: list index out of range .. note:: Pweb class also uses separate classes to parse and execute the document, but subclassing these is not currently documented and is hopefully not needed.