owickstrom / pandoc-include-code

A Pandoc filter for including code from source files
Mozilla Public License 2.0
139 stars 18 forks source link

Cannot combine with minted filter #15

Open hasufell opened 5 years ago

hasufell commented 5 years ago

I'm using this with the following filter:

#!/usr/bin/env python
''' A pandoc filter that has the LaTeX writer use minted for typesetting code.

Usage:
    pandoc --filter ./minted.py -o myfile.tex myfile.md
'''

from string import Template
from pandocfilters import toJSONFilter, RawBlock, RawInline

def unpack_code(value, language):
    ''' Unpack the body and language of a pandoc code element.

    Args:
        value       contents of pandoc object
        language    default language
    '''
    [[_, classes, attributes], contents] = value

    if len(classes) > 0:
        language = classes[0]

    attributes = ', '.join('='.join(x) for x in attributes)

    return {'contents': contents, 'language': language,
            'attributes': attributes}

def unpack_metadata(meta):
    ''' Unpack the metadata to get pandoc-minted settings.

    Args:
        meta    document metadata
    '''
    settings = meta.get('pandoc-minted', {})
    if settings.get('t', '') == 'MetaMap':
        settings = settings['c']

        # Get language.
        language = settings.get('language', {})
        if language.get('t', '') == 'MetaInlines':
            language = language['c'][0]['c']
        else:
            language = None

        return {'language': language}

    else:
        # Return default settings.
        return {'language': 'text'}

def minted(key, value, format, meta):
    ''' Use minted for code in LaTeX.

    Args:
        key     type of pandoc object
        value   contents of pandoc object
        format  target output format
        meta    document metadata
    '''
    if format != 'latex':
        return

    # Determine what kind of code object this is.
    if key == 'CodeBlock':
        template = Template(
            '\\begin{minted}[linenos,tabsize=2,breaklines]{$language}\n$contents\n\end{minted}'
        )
        Element = RawBlock
    elif key == 'Code':
        template = Template(
            '\\mintinline[linenos,tabsize=2,breaklines]{$language}{$contents}')
        Element = RawInline
    else:
        return

    settings = unpack_metadata(meta)

    code = unpack_code(value, settings['language'])

    return [Element(format, template.substitute(code))]

if __name__ == '__main__':
    toJSONFilter(minted)

The result is:

screenshot_2018-12-07_11-45-21

This filter is run first.

hasufell commented 5 years ago

I discovered that this seems to be a problem with tabs.

owickstrom commented 5 years ago

Hi! Please post the following:

That is, a complete and reproducible example.

Thanks!

hasufell commented 5 years ago
* the Python filter source code

It is attached here