Skip to content
Permalink
Browse files
Module methods updated
  • Loading branch information
aa9863 committed Jul 5, 2020
1 parent e6656a6 commit e1b33438b0c8c54ee2391d45147c9b81334544aa
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 77 deletions.
@@ -10,16 +10,16 @@ Two use cases at the moment:
- Input File
1. Called with just an input file. Which contains the template.
I would then plumb this to a command line script.
I would then plumb this to a command line script.
```
markdownmark <input> -t [template] [output]
```
Exceptions to check for
Exceptions to check for
- jinja2.exceptions.TemplateNotFound
- jinja2.exceptions.TemplateNotFound
Things to think about:
@@ -29,12 +29,10 @@ Things to think about:
"""

import logging

import os
import pathlib

import MarkdownMark.parser as parser
import MarkdownMark.renderer as renderer
import remarkable.parser as parser
import remarkable.renderer as renderer


class RenderError(Exception):
@@ -47,11 +45,9 @@ class RenderError(Exception):
def __init__(self, message):
self.message = message



def convertFile(inputFile, templateFile = None, templateDir=None, outputFile = None):
def convertFile(inputFile, templateFile=None, templateDir=None, outputFile=None):
"""
Given a set of options convert a file from markdown
Given a set of options convert a file from markdown
to a nicely rendered output.
The template file can be specified as part of the function, or in the header file.
@@ -64,7 +60,7 @@ def convertFile(inputFile, templateFile = None, templateDir=None, outputFile = N
"""

log = logging.getLogger("CONTROLLER")


#Create a parser for this input file
theParser = parser.MarkdownParser(inputFile)
@@ -75,17 +71,17 @@ def convertFile(inputFile, templateFile = None, templateDir=None, outputFile = N
if templateFile is None:
templateFile = theParser.header.get("template")
log.debug("Using template from header: {0}".format(templateFile))

if templateDir is None:
templateDir = theParser.header.get("templatedir")


if templateFile is None:
log.critical("No Template Specified")
raise RenderError("No Template has been specified")
#Feed this to the Renderer

if templateDir:
if templateDir:
log.info("Render with {0} from {1}".format(templateFile, templateDir))
else:
log.info("Render with default template: {0}".format(templateFile))
@@ -94,7 +90,7 @@ def convertFile(inputFile, templateFile = None, templateDir=None, outputFile = N
#We also need to know where to output the thing.
if outputFile is None:
log.debug("No Output file specified")

outputFile = "{0}.html".format(pathlib.Path(inputFile).stem)
log.debug("Output File is now {0}".format(outputFile))

@@ -1,5 +1,5 @@
"""
File to read Markdown files and generate
File to read Markdown files and generate
whatever AST we need to generate
"""

@@ -8,11 +8,17 @@ import re

import yaml

import MarkdownMark.section as section
import remarkable.section as section

class MarkdownParser(object):
class MarkdownParser():
"""
Parser for Markdown input files
This will split out the header and body, and parse it.
output for sections is based on top level headings
"""
def __init__(self, theFile):
"""Create a markdown parser,
"""Create a markdown parser,
param theFile: File to use as input
"""
self.log = logging.getLogger("[PARSER]")
@@ -44,36 +50,34 @@ class MarkdownParser(object):
#Cast to Integer
marks = int(marks)
#And delete the marks part
cleanLine = marksRe.sub("",cleanLine)
cleanLine = marksRe.sub("", cleanLine)
cleanLine = cleanLine.strip()

#We also want to replace spaces with underscores
cleanLine = cleanLine.replace(" ","_")
cleanLine = cleanLine.replace(" ", "_")
self.log.debug("--> Section '{0}' (Marks {1})".format(cleanLine,
marks))
marks))
return (cleanLine, marks)


def _splitHeader(self):
"""
Break the input file into a Header and body
We take the standard MD approach of using a YAML header in the file.
The header is delimited by ```---``` and should be at the TOP of the document
@return (header, body): None if they dont exist
"""

self.log.debug("Splitting File")

header = []
body = []

inHeader = False
#Messy but it gets it done
firstLine = False


for line in self.fd:
theLine = line.rstrip()
if theLine.startswith("---"):
@@ -85,8 +89,6 @@ class MarkdownParser(object):
else:
body.append(theLine)



#Put the Header together
if header:
outHeader = "\n".join(header)
@@ -97,30 +99,30 @@ class MarkdownParser(object):
outBody = body[1:]
else:
outBody = body


return outHeader, outBody

def _parseHeader(self, theHeader):
"""
Parse any YAML header in the file
This will take a string representing the YAML header,
parse it and update the self.header variable with its contents
@param theHeader: Header section
@param theHeader: Header section
@return: True if successfull
"""

self.header = yaml.safe_load(theHeader)
self.header = yaml.safe_load(theHeader)
self.log.debug("Header Items {0}".format(self.header))
return True

def _parseBody(self, theText):
"""
Parse the text portion of the file
This takes the markdown text in the file, and breaks it into
This takes the markdown text in the file, and breaks it into
sections based on the line headings.
"""

@@ -136,7 +138,7 @@ class MarkdownParser(object):
self.log.debug("Body Text {0}".format(out[:3]))
theSection = section.Section(out, currentMarks)

sections[currentSection] = theSection
sections[currentSection] = theSection
else:
pass
#And update our Current section
@@ -145,23 +147,23 @@ class MarkdownParser(object):
out = []
else:
cleanLine = line.rstrip() #Also remove newlines
out.append(cleanLine)
out.append(cleanLine)
#We also need to store the final section

self.log.debug("Body Text {0}".format(out[:3]))
theSection = section.Section(out, currentMarks)

sections[currentSection] = theSection


#And Store the sections where they belong
self.sections = sections
return True

def parseFile(self):
""" Parse the input file
This function will split the input file into the Header and Body.
Then parse each of them
"""
@@ -176,4 +178,3 @@ class MarkdownParser(object):
self._parseBody(body)

return True

@@ -5,20 +5,20 @@ I cant see this going much beyond HTML, but lets keep it here for
completeness.
"""

import jinja2
import logging

import jinja2
#from jinja2 import Environment, PackageLoader, select_autoescape

import markdown
from markdown.treeprocessors import Treeprocessor
from markdown.extensions import Extension

#Extra to make sure tables have the bootstrap "table" class
class TableProcessor(Treeprocessor):
def run(self, root):
for element in root.iter("table"):
element.set("class","table")

from markdown.extensions import Extension
element.set("class", "table")

class TableExtension(Extension):
def extendMarkdown(self, md):
@@ -32,22 +32,22 @@ markdowner = markdown.Markdown(extensions=["tables",
TableExtension(),
'mdx_math'])

class Renderer(object):
class Renderer():
"""Parent class for all rendering objects
"""
def __init__(self):
"""Create a renderer"""
self.log = logging.getLogger("Render")
pass

def render(self, parser):

def render(self, theParser):
"""Do the Magic required to render
Placeholder for inherited function
@param theParser: Parser object
@return: String representation of the output
"""
pass
raise NotImplementedError

def toFile(self, theParser, outFile):
"""
@@ -63,6 +63,10 @@ class Renderer(object):
fd.close()

class HTMLRenderer(Renderer):
"""
Render our document to HTML using Jinja templates
"""

def __init__(self, theTemplate, templateDir=None):
"""
Create a new rendering object.
@@ -78,37 +82,33 @@ class HTMLRenderer(Renderer):

if templateDir:
self.log.debug("--> Template Dir Specified")
#Default to specified dir, fall back to system
theLoader=jinja2.ChoiceLoader([jinja2.FileSystemLoader(templateDir),
jinja2.PackageLoader("MarkdownMark")]
)
#Default to specified dir, fall back to system
theLoader = jinja2.ChoiceLoader([jinja2.FileSystemLoader(templateDir),
jinja2.PackageLoader("remarkable")])
else:
self.log.debug("--> No Templates Specified")
theLoader = jinja2.PackageLoader("MarkdownMark")
theLoader = jinja2.PackageLoader("remarkable")

self.log.info("--> Create Renderer")
#We are going to load all templates from scratch first
from jinja2 import Environment, PackageLoader, select_autoescape
self.env = jinja2.Environment(
loader = theLoader,
loader=theLoader,
autoescape=jinja2.select_autoescape(['html', 'xml'])
)

self.log.info("--> Template file {0}".format(theTemplate))
self.template = self.env.get_template(theTemplate)

def render(self, theParser):
"""
Render the template to a string
@param theParser: Parser object to render
"""

sections = theParser.sections
header = theParser.header

out = self.template.render({"content":sections,
"header": header})
return out

0 comments on commit e1b3343

Please sign in to comment.