Skip to content

Commit

Permalink
Merge pull request #58 from mdboom/markdown
Browse files Browse the repository at this point in the history
Markdown
  • Loading branch information
mdboom committed Mar 10, 2015
2 parents bafc36f + a0fbf40 commit 6047c54
Show file tree
Hide file tree
Showing 17 changed files with 304 additions and 98 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ branches:
- master

before_install:
- pip install six sphinx sphinx_bootstrap_theme jsonschema pyyaml
- pip install six sphinx sphinx_bootstrap_theme jsonschema pyyaml mistune
- bash -x ./install-texlive.sh
- export PATH=$PWD/texlive/bin/x86_64-linux:$PATH

Expand Down
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,16 @@ ASDF standard

This document describes the Advanced Scientific Data Format (ASDF),
pronounced *AZ*-diff.

Build requirements
==================

- `sphinx`
- `sphinx_bootstrap_theme`
- `jsonschema`
- `pyyaml`
- `mistune`

The following command should install these requirements::

pip install sphinx sphinx_bootstrap_theme jsonshema pyyaml mistune
13 changes: 5 additions & 8 deletions convert_schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

import yaml

from md2rst import md2rst


def write_if_different(filename, data):
""" Write `data` to `filename`, if the content of the file is different.
Expand Down Expand Up @@ -243,11 +245,6 @@ def reindent(content, indent):
return '\n'.join(lines)


def write_subschemas(o, name, schema, path, level, schemas):
indent = ' ' * max(level, 0)



def recurse(o, name, schema, path, level, required=False):
"""
Convert a schema fragment to reStructuredText.
Expand Down Expand Up @@ -291,10 +288,10 @@ def recurse(o, name, schema, path, level, required=False):
o.write(' Required.')
o.write('\n\n')

o.write(reindent(schema.get('title', ''), indent))
o.write(reindent(md2rst(schema.get('title', '')), indent))
o.write('\n\n')

o.write(reindent(schema.get('description', ''), indent))
o.write(reindent(md2rst(schema.get('description', '')), indent))
o.write('\n\n')

if 'default' in schema:
Expand Down Expand Up @@ -344,7 +341,7 @@ def recurse(o, name, schema, path, level, required=False):
o.write(indent)
o.write(":category:`Examples:`\n\n")
for description, example in schema['examples']:
o.write(reindent(description + "::\n\n", indent))
o.write(reindent(md2rst(description + "::\n\n"), indent))
o.write(reindent(example, indent + ' '))
o.write('\n\n')

Expand Down
195 changes: 195 additions & 0 deletions md2rst.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
# Licensed under a 3-clause BSD style license - see LICENSE.rst
# -*- coding: utf-8 -*-

"""
Implements a markdown to reST converter using the mistune markdown
parser.
"""

import re
import textwrap

import mistune


class BlockLexer(mistune.BlockLexer):
# Adds math support

def __init__(self, *args, **kwargs):
super(BlockLexer, self).__init__(*args, **kwargs)
self.enable_math()

def enable_math(self):
self.rules.block_math = re.compile(r'^\$\$(.*?)\$\$', re.DOTALL)
self.default_rules = ['block_math'] + mistune.BlockLexer.default_rules

def parse_block_math(self, m):
self.tokens.append({
'type': 'block_math',
'text': m.group(1)
})


class Markdown(mistune.Markdown):
def output_block_math(self):
return self.renderer.block_math(self.token['text'])


class InlineLexer(mistune.InlineLexer):
# Adds math support

default_rules = ['math'] + mistune.InlineLexer.default_rules

def __init__(self, *args, **kwargs):
super(InlineLexer, self).__init__(*args, **kwargs)
self.enable_math()

def enable_math(self):
self.rules.text = re.compile(
r'^[\s\S]+?(?=[\\<!\[_*`~$]|https?://| {2,}\n|$)')
self.rules.math = re.compile(r'^\$(.+?)\$')
self.default_rules = ['math'] + mistune.InlineLexer.default_rules

def output_math(self, m):
return self.renderer.math(m.group(1))


class RstRenderer(object):
"""The default HTML renderer for rendering Markdown.
"""
def __init__(self, **kwargs):
self.options = kwargs
self.levels = kwargs.get('levels', '*=-^"+:~')

def _indented(self, content):
content = textwrap.dedent(content)
return '\n'.join(' ' + line for line in content.split('\n'))

def _directive(self, name, content, args=[], attributes={}):
out = '.. %s:: %s\n' % (name, ', '.join(args))
for key, val in attributes.items():
out += ' :%s: %s\n' % (key, val)
out += '\n'
out += self._indented(content)
out += '\n\n'
return out

def placeholder(self):
return ''

def block_code(self, code, lang=None):
code = code.rstrip('\n')
if lang:
langs = lang
else:
langs = []
return self._directive('code', code, langs)

def block_quote(self, text):
return self._indented(text)

def block_html(self, html):
if self.options.get('skip_html'):
return ''
return self._directive('raw', html, ['html'])

def header(self, text, level, raw=None):
return '%s\n%s\n\n' % (text, self.levels[level] * len(text))

def hrule(self):
return '\n\n--------\n\n'

def list(self, body, ordered=True):
if ordered:
body = ('\n' + body).replace('\n- ', '\n#.')
return body

def list_item(self, text):
return textwrap.fill(
text, initial_indent='- ', subsequent_indent=' ') + '\n\n'

def paragraph(self, text):
return '%s\n\n' % text

def table(self, header, body):
raise NotImplementedError()

def table_row(self, content):
raise NotImplementedError()

def table_cell(self, content, **flags):
raise NotImplementedError()

def double_emphasis(self, text):
return '**%s**' % text

def emphasis(self, text):
return '*%s*' % text

def codespan(self, text):
return ':code:`%s`' % text

def linebreak(self):
return ''

def strikethrough(self, text):
return text

def text(self, text):
return text

def autolink(self, link, is_email=False):
text = link
if is_email:
link = 'mailto:%s' % link
if link.startswith('ref:'):
return ':ref:`%s <%s>`' % (text, link[4:])
return '`%s <%s>`__' % (text, link)

def link(self, link, title, text):
if link.startswith('javascript:'):
link = ''
if link.startswith('ref:'):
return ':ref:`%s <%s>`' % (text, link[4:])
return '`%s <%s>`__' % (text, link)

def image(self, src, title, text):
if src.startswith('javascript:'):
src = ''
options = {}
if text:
options['alt'] = text
return self._directive('image', '', [src], options)

def tag(self, html):
if self.options.get('skip_html'):
return ''
return ":raw:`%s`" % html

def newline(self):
return ''

def footnote_ref(self, key, index):
raise NotImplementedError()

def footnote_item(self, key, text):
raise NotImplementedError()

def footnotes(self, text):
raise NotImplementedError()

def math(self, text):
return ':math:`%s`' % text

def block_math(self, text):
return self._directive('math', text)


def md2rst(content):
"""
Convert the given string in markdown to a string of reST.
"""
renderer = RstRenderer()
md = Markdown(
block=BlockLexer, inline=InlineLexer, renderer=renderer)
return md.render(content)
6 changes: 4 additions & 2 deletions schemas/stsci.edu/asdf/0.1.0/core/complex.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ $schema: "http://stsci.edu/schemas/yaml-schema/draft-01"
id: "http://stsci.edu/schemas/asdf/0.1.0/core/complex"
title: Complex number value.
description: |
Represents a complex number matching the following EBNF grammar::
Represents a complex number matching the following EBNF grammar
```
plus-or-minus = "+" | "-"
suffix = "J" | "j" | "I" | "i"
complex = [ieee754] [plus-or-minus ieee754 suffix]
```
Where ``ieee754`` is a floating point number in IEEE 754 decimal
Where `ieee754` is a floating point number in IEEE 754 decimal
format.
examples:
Expand Down

0 comments on commit 6047c54

Please sign in to comment.