Skip to content

Commit

Permalink
Robustify xymatrix rendering and improve nowiki handling
Browse files Browse the repository at this point in the history
We make some tweaks to the xymatrix diagram renderer to allow it to
handle correctly a wider range of cases: curved arrows for example. We
move from \xymatrix{...} to \begin{xymatrix} ... \end{xymatrix} to
make it easier to detect the diagram correctly when mathematics is
used inside it.

We also tweak the <nowiki>...</nowiki> renderer and the way it is
called in certain cases to allow Tikz and Xymatrix diagram code, as
well as centred code, to be able to be displayed verbatim.
  • Loading branch information
Richard Williamson committed Feb 2, 2019
1 parent 494c311 commit 97d31e5
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 19 deletions.
1 change: 1 addition & 0 deletions script/author_to_user
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ Bas Spitters, spitters
Max S. New, maxsnew
N. Raghavendra, raghu
Nyshadham Raghavendra, raghu
Pieter Cuijpers, Pieter
58 changes: 57 additions & 1 deletion script/src/diagrams/diagram.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
logging_file_handler.setFormatter(logging_formatter)
logger.addHandler(logging_file_handler)

class DocumentParametersException(Exception):
def __init__(self, message):
super().__init__(message)

class PdfRenderingException(Exception):
def __init__(self, message):
super().__init__(message)
Expand Down Expand Up @@ -95,11 +99,56 @@ def tikz_tex_source(diagram, is_commutative_diagram):
tikz_libraries = "\\usetikzlibrary{cd}",
tikz_diagram = diagram)

def parse_document_parameters(document_parameters):
parsed_parameters = { "document_header_parameters": [ "12pt" ] }
for parameter in document_parameters.split(","):
split_at_equals = parameter.split("=")
if len(split_at_equals) != 2:
raise DocumentParametersException(
"The following does not have the expected format: " +
parameter)
key = split_at_equals[0].strip()
value = split_at_equals[1].strip()
if key == "font":
parsed_parameters["font_size"] = value
elif key == "border":
parsed_parameters["document_header_parameters"].append(parameter)
else:
raise DocumentParametersException(
"The key " +
key +
" of the following parameter is not recognised: " +
parameter)
return parsed_parameters

def extract_document_parameters(diagram):
split_at_first_curly_brace = diagram.split("{", 1)
document_parameters = {
"font_size": "",
"document_header_parameters": ["12pt"] }
document_parameters_block = find_block.Block(
"[",
"]",
lambda within_square_brackets: document_parameters.update(
parse_document_parameters(within_square_brackets)),
False)
document_parameters_processor = find_block.Processor([
document_parameters_block])
processed_preamble = document_parameters_processor.process(
split_at_first_curly_brace[0])
return (
document_parameters,
processed_preamble + "{" + split_at_first_curly_brace[1])

def xypic_tex_source(diagram):
document_parameters, diagram = extract_document_parameters(diagram)
xypic_diagram_template_path = os.environ["NLAB_XYPIC_DIAGRAM_TEMPLATE"]
with open(xypic_diagram_template_path, "r") as xypic_diagram_template_file:
xypic_diagram_template = xypic_diagram_template_file.read()
return string.Template(xypic_diagram_template).substitute(
document_parameters = ", ".join(
document_parameters["document_header_parameters"]),
font_size = document_parameters["font_size"],
xypic_diagram = diagram)

def create_pdf(
Expand Down Expand Up @@ -207,8 +256,15 @@ def main():
"\nThe error was: " +
str(svgRenderingException))
sys.exit(message)
except DocumentParametersException as documentParametersException:
message = (
"An error occurred when rendering the following diagram. \n" +
diagram +
"\n " +
str(documentParametersException))
logger.warning(message)
sys.exit(message)
except Exception as exception:
raise exception
message = (
"An unexpected error occurred when creating an SVG from a PDF " +
"for the following diagram. \n" +
Expand Down
8 changes: 6 additions & 2 deletions script/src/diagrams/xypic_diagram_template
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
\documentclass[12pt]{standalone}
\documentclass[$document_parameters]{standalone}

\usepackage[all]{xy}
\usepackage[all, 2cell]{xy}

\UseTwocells

\begin{document}

$font_size

$xypic_diagram

\end{document}
8 changes: 6 additions & 2 deletions script/src/renderer/centre_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"""

import find_block
import nowiki_block

def initial_centre_processor(content):
return (
Expand Down Expand Up @@ -33,8 +34,11 @@ def define_centre():
True)

def handle_initial_centring(content):
return find_block.Processor([define_center(), define_centre()]).process(
content)
processor = find_block.Processor([
define_center(),
define_centre(),
nowiki_block.define(True)])
return processor.process(content)

def handle_post_centring(content):
centre_paragraph_block = find_block.Block(
Expand Down
8 changes: 4 additions & 4 deletions script/src/renderer/nowiki_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
"""
import find_block

def nowiki_processor(nowiki_content):
if "[[!include" in nowiki_content:
def nowiki_processor(nowiki_content, retain_nowiki_block):
if retain_nowiki_block or ("[[!include" in nowiki_content):
return "<nowiki>" + nowiki_content + "</nowiki>"
return nowiki_content

def define():
def define(retain_nowiki_block = False):
return find_block.Block(
"<nowiki>",
"</nowiki>",
nowiki_processor,
lambda content: nowiki_processor(content, retain_nowiki_block),
True)
7 changes: 5 additions & 2 deletions script/src/renderer/tikz_diagram_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import find_block
import os
import subprocess
import nowiki_block

class TikzDiagramException(Exception):
def __init__(self, message):
Expand Down Expand Up @@ -66,7 +67,9 @@ def define_tikz_commutative_diagram():
True)

def handle_tikz_diagrams(content):
processor = find_block.Processor(
[ define_tikz(), define_tikz_commutative_diagram() ])
processor = find_block.Processor([
define_tikz(),
define_tikz_commutative_diagram(),
nowiki_block.define(True) ])
return processor.process(content)

35 changes: 27 additions & 8 deletions script/src/renderer/xypic_diagram_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,23 @@
import find_block
import os
import subprocess
import nowiki_block

class XyPicDiagramException(Exception):
def __init__(self, message):
super().__init__(message)

def remove_new_lines_at_start_of_block(diagram):
split_at_opening_brace = diagram.split("}", 1)
if len(split_at_opening_brace) == 0:
raise XyPicDiagramException(
"Missing end brace } after \\begin{xymatrix")
return split_at_opening_brace[0] + "{" + split_at_opening_brace[1].strip()

def xypic_diagram_processor(xypic_diagram):
xypic_diagram = (
"\\xymatrix@" +
xypic_diagram +
remove_new_lines_at_start_of_block(xypic_diagram) +
"}")
diagram_api_path = os.environ["NLAB_DIAGRAM_API_PATH"]
completed_xypic_diagram_process = subprocess.run(
Expand All @@ -30,21 +38,32 @@ def xypic_diagram_processor(xypic_diagram):

def define_xymatrix_default_size():
return find_block.Block(
"\\xymatrix{",
"}",
"\\begin{xymatrix}",
"\\end{xymatrix}",
lambda diagram: xypic_diagram_processor(
"=5em}" + diagram),
True)

def define_xymatrix_document_parameters():
return find_block.Block(
"\\begin{xymatrix[",
"\end{xymatrix}",
lambda diagram: xypic_diagram_processor(
"=5em{" + diagram),
"=5em[" + diagram),
True)

def define_xymatrix():
return find_block.Block(
"\\xymatrix@",
"}",
"\\begin{xymatrix@",
"\\end{xymatrix}",
xypic_diagram_processor,
True)

def handle_xypic_diagrams(content):
processor = find_block.Processor(
[ define_xymatrix(), define_xymatrix_default_size() ])
processor = find_block.Processor([
define_xymatrix(),
define_xymatrix_default_size(),
define_xymatrix_document_parameters(),
nowiki_block.define(True) ])
return processor.process(content)

0 comments on commit 97d31e5

Please sign in to comment.