pandoc: `RawBlock` in filter - pandoc

What is the correct use of the RawBlock function in Pandoc filters?
#!/usr/bin/env python
from pandocfilters import toJSONFilter, Str, Para, Emph, Header, RawBlock
import re
def replace(key, value, format, meta):
if key == 'Str':
if value.startswith('Hello'):
#return Str("Hi") # this works
return RawBlock("opendocument", "Hi") # this doesn't
if __name__ == '__main__':
toJSONFilter(replace)

You are trying to replace an Inline value (Str) with a Block value (RawBlock). One can only replace elements with elements of the same type. Use RawInline instead of RawBlock.

Related

I get this error: 'list' object has no attribute 'countPoints'

When I import this code that I typed in here in to another code I get the error: 'list' object has no attribute 'countPoints' .
import ModuleRollDice as dce
def judge(rollPlayerA,rollPlayerB):
if not all(item in dce.options for item in rollPlayerA) or
not all(item in dce.options for item in rollPlayerB):
print("error")
if rollPlayerA.countPoints(rollPlayerA[0]) == len(rollPlayerA) and
rollPlayerB.countPoints(rollPlayerB[0]) != len(rollPlayerB):
return "A"
if rollPlayerA.countPoints(rollPlayerA[0]) != len(rollPlayerA) and
rollPlayerB.countPoints(rollPlayerB[0]) == len(rollPlayerB):
return "B"
elif sum(rollPlayerA) == sum(rollPlayerB):
return "tie"
elif sum(rollPlayerA) > sum(rollPlayerB):
return "A"
else:
return "B"
return
It appears as though the arguments passed to rollPlayerA/B are not list types objects. You should sanity check this beforehand to ensure that what is recieved is in fact a list type object. The issue can be resolved by both sanity checking and looking at the caller function and seeing what is being sent as arguments.
A simple sanity check could look like:
def judge(rollPlayerA,rollPlayerB):
if type(rollPlayerA) is not type(list) or
type(rollPlayerB) is not type(list):
print("judge function did not recieve proper input types")
return
...
Another way of doing this would be using pythons assert
def judge(rollPlayerA,rollPlayerB):
assert(type(rollPlayerA) == type(list)), "rollPlayerA is not a list"
assert(type(rollPlayerB) == type(list)), "rollPlayerB is not a list"
An even nicer way of doing this would be using PEP 3107's implementation of type assertions in definition declarations:
def judge(rollPlayerA: list, rollplayerB: list) -> None:
....
This also allows you to remove the redundant 'return' statement at the end of your function, which you didn't really need anyways

python-sphinx - Display only function signature with autodoc?

In Sphinx is possible to include the signature of a function or method manually using the py:function (or py:method) directive:
.. py:function:: my_func(data, named=None, *args, *kwargs)
It is also possible to use autodoc directives to include and format the whole docstring of a function or method:
.. automethod:: my_func
I am wondering if there is a way of configuring autodoc to include and format only the signature, without the rest of the docstring, so that I don't have to do it manually.
autodoc-process-signature can be used here as well.
def process_signature(app, what, name, obj, options, signature, return_annotation):
return modified_signature, modified_return_annotation
# will be rendered to method(modified_signature) -> modified_return_annotation
def setup(app):
app.connect("autodoc-process-signature", process_signature)
http://www.sphinx-doc.org/en/master/_modules/sphinx/ext/autodoc.html
See autodoc's sphinx.ext.autodoc.between.
Return a listener that either keeps, or if exclude is True excludes, lines between lines that match the marker regular expression. If no line matches, the resulting docstring would be empty, so no change will be made unless keepempty is true.
If what is a sequence of strings, only docstrings of a type in what will be processed.

Substitution in a file name with reStructuredText (Sphinx)?

I want to create several files from a single template, which differ only by a variable name. For example :
(file1.rst):
.. |variable| replace:: 1
.. include template.rst
(template.rst) :
Variable |variable|
=====================
Image
-------
.. image:: ./images/|variable|-image.png
where of course I have an image called "./images/1-image.png". The substitution of "|variable|" by "1" works well in the title, but not in the image file name, and at compilation I get :
WARNING: image file not readable: ./images/|variable|-image.png
How can I get reST to make the substitution in the variable name too? (if this changes anything, am using Sphinx).
There are two problems here: a substitution problem, and a parsing order problem.
For the first problem, the substitution reference |variable| cannot have adjacent characters (besides whitespace or maybe _ for hyperlinking) or else it won't parse as a substitution reference, so you need to escape it:
./images/\ |variable|\ -image.png
However, the second problem is waiting around the corner. While I'm not certain of the details, it seems reST is unable to parse substitutions inside other directives. I think it first parses the image directive, which puts it in the document tree and thus out of reach of the substitution mechanism. Similarly, I don't think it's possible to use a substitution to insert content intended to be parsed (e.g. .. |img1| replace::`.. image:: images/1-image.png`). This is all speculative based on some tests and my incomplete comprehension of the official documentation, so someone more knowledgeable can correct what I've said here.
I think you're aware of the actual image substitution directive (as opposed to text substitution), but I don't think it attains the generality you're aiming for (you'll still need a separate directive for the image as from the |variable|), but in any case it looks like this:
.. |img1| image:: images/1-image.png
Since you're using Sphinx, you can try creating your own directive extension (see this answer for information), but it won't solve the substitutions-inside-markup problem.
You have to create a custom directive in this case as Sphinx doesn't allow you to substitute image paths. You can change Sphinx figure directive as follows and use it instead of the image directive.
from typing import Any, Dict, List, Tuple
from typing import cast
from docutils import nodes
from docutils.nodes import Node, make_id, system_message
from docutils.parsers.rst import directives
from docutils.parsers.rst.directives import images, html, tables
from sphinx import addnodes
from sphinx.directives import optional_int
from sphinx.domains.math import MathDomain
from sphinx.util.docutils import SphinxDirective
from sphinx.util.nodes import set_source_info
if False:
# For type annotation
from sphinx.application import Sphinx
class CustomFigure(images.Figure):
"""The figure directive which applies `:name:` option to the figure node
instead of the image node.
"""
def run(self) -> List[Node]:
name = self.options.pop('name', None)
path = self.arguments[0] #path = ./images/variable-image.png
#replace 'variable' from th.e given value
self.argument[0] = path.replace("variable", "string substitution")
result = super().run()
if len(result) == 2 or isinstance(result[0], nodes.system_message):
return result
assert len(result) == 1
figure_node = cast(nodes.figure, result[0])
if name:
# set ``name`` to figure_node if given
self.options['name'] = name
self.add_name(figure_node)
# copy lineno from image node
if figure_node.line is None and len(figure_node) == 2:
caption = cast(nodes.caption, figure_node[1])
figure_node.line = caption.line
return [figure_node]
def setup(app: "Sphinx") -> Dict[str, Any]:
directives.register_directive('figure', Figure)
return {
'version': 'builtin',
'parallel_read_safe': True,
'parallel_write_safe': True,
}
You can add this CustomFigure.py directive in the conf.py of the project and use the customfigure directive across Sphinx project instead of the Image directive. Refer http://www.sphinx-doc.org/en/master/usage/extensions/index.html to add a custom directive to your Sphinx project.

Sphinx Pygments lexer filter extension?

I have a Lisp-like language I would like to highlight using Pygments in Sphinx code snippet documentation. My approach is to extend the existing CommonLispLexer to add the built-in names using a NameHighlightFilter. However, it is not working, so I must be missing something obvious. I have added the following to my conf.py:
def setup(app):
from sphinx.highlighting import lexers
from pygments.lexers import CommonLispLexer
from pygments.token import Name
from pygments.filters import NameHighlightFilter
tl_lexer = CommonLispLexer()
tl_lexer.add_filter(NameHighlightFilter(
names=['define-function', 'define-macro',
'define-variable', 'define-constant'],
tokentype=Name.Builtin,
))
app.add_lexer('tl', tl_lexer)
highlight_language = 'tl'
But the NameHighlightFilter has no effect. Code blocks are highlighted as if they were Lisp, but my new builtin names have no special highlighting.
The reason is that the NameHighlighFilter only converts tokens that the lexer categorizes as Token.Name, but the CommonLispLexer categorizes almost everything as Name.Variable. This is the filter function of the NameHighlightFilter, from the Pygments source code:
def filter(self, lexer, stream):
for ttype, value in stream:
if ttype is Name and value in self.names:
yield self.tokentype, value
else:
yield ttype, value
My only workaround was to write my own filter. This function gave me the look I wanted.
def filter(self, lexer, stream):
define = False
for ttype, value in stream:
if value in self.tl_toplevel_forms:
ttype = Name.Builtin
define = True
elif define and ttype == Name.Variable:
define = False
ttype = Name.Function
elif value in self.tl_special_forms:
ttype = Name.Variable
# the Common Lisp lexer highlights everything else as
# variables, which isn't the look I want. Instead
# highlight all non-special things as text.
elif ttype == Name.Variable:
ttype = Name.Text
yield ttype, value
As a note to Pygments developers, perhaps the NameHighlightFilter could take an optional argument representing the token type(s) to be converted (currently it only takes the output token type).

Lxml or Xpath content print

I have the following function
def parseTitle(self, post):
"""
Returns title string with spaces replaced by dots
""
return post.xpath('h2')[0].text.replace('.', ' ')
I would to see the content of post. I have tried everything I can think of.
How can I properly debug the content? This is an website of movies where I'm rip links and title and this function should parse the title.
I am sure H# is not existing, how can I print/debug this?
post is lxml element tree object, isn't it?
so first, you could try:
# import lxml.html # if not yet imported
# (or you can use lxml.etree instead of lxml.html)
print lxml.html.tostring(post)
if isn't, you should create element tree object from it
post = lxml.html.fromstring(post)
or maybe the problem is just that you should replace h2 with //h2?
your question is not very explanatory..

Resources