Skip to content

Commit

Permalink
Interactive samples for pdf
Browse files Browse the repository at this point in the history
  • Loading branch information
Matistjati committed Aug 18, 2024
1 parent 480e0ea commit e9b3f8e
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 26 deletions.
2 changes: 1 addition & 1 deletion problemtools/md2html.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def convert(problem: str, options: argparse.Namespace) -> None:
title=problem_name or "Missing problem name",
problemid=problembase)

samples = "".join(statement_common.samples_to_html(problem))
samples = "".join(statement_common.format_samples(problem, to_pdf=False))

html_template = inject_samples(html_template, samples)
html_template = replace_hr_in_footnotes(html_template)
Expand Down
16 changes: 7 additions & 9 deletions problemtools/problem2pdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,22 +38,20 @@ def convert(options: argparse.Namespace) -> bool:
with open(statement_path, "r") as f:
statement_md = f.read()

# Add code that adds vertical and horizontal lines to all tables
statement_md = table_fix + statement_md

# Hacky: html samples -> md. Then we append to the markdown document
samples = "".join(statement_common.samples_to_html(problem_root))
with tempfile.NamedTemporaryFile(mode='w', suffix=".html") as temp_file:
temp_file.write(samples)
temp_file.flush()
samples_md = os.popen(f"pandoc {temp_file.name} -t latex").read()
statement_md += samples_md
samples = "\n".join(statement_common.format_samples(problem_root, to_pdf=True))

# If we don't add newline, the table might get attached to a footnote
statement_md += "\n" + samples

#statement_md += samples_md
with tempfile.NamedTemporaryFile(mode='w', suffix=".md") as temp_file:
temp_file.write(statement_md)
temp_file.flush()
# Do .read so that the file isn't deleted until pandoc is done
os.popen(f"pandoc --verbose {temp_file.name} -o {problembase}.pdf --resource-path={statement_dir}").read()
# Do .read so that the temp file isn't deleted until pandoc is done
os.popen(f"pandoc {temp_file.name} -o {problembase}.pdf --resource-path={statement_dir}").read()

else:
# Set up template if necessary
Expand Down
74 changes: 58 additions & 16 deletions problemtools/statement_common.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
from typing import Optional, List
import html
import tempfile

from . import verifyproblem

Expand Down Expand Up @@ -49,8 +50,7 @@ def get_problem_name(problem: str, language: Optional[str]) -> Optional[str]:
with verifyproblem.Problem(problem) as prob:
config = verifyproblem.ProblemConfig(prob)
if not config.check(None):
print("Please add problem name to problem.yaml when using markdown")
return None
raise Exception(f"Invalid problem.yaml")
names = config.get("name")
# If there is only one language, per the spec that is the one we want
if len(names) == 1:
Expand All @@ -61,44 +61,78 @@ def get_problem_name(problem: str, language: Optional[str]) -> Optional[str]:
return names[language]


def samples_to_html(problem_root: str) -> List[str]:
"""Read all samples from the problem directory and convert them to HTML
def format_samples(problem_root: str, to_pdf: bool = False) -> List[str]:
"""Read all samples from the problem directory and convert them to pandoc-valid markdown
Args:
problem_root: path to root of problem
to_pdf: whether the outputted samples should be valid for for html or pdf
Returns:
List[str]: All samples, converted to html. Ordered lexicographically by file names
List[str]: All samples, converted to a format appropriate to be pasted into
a markdown file. Ordered lexicographically by file names
"""

sample_path = os.path.join(problem_root, "data", "sample")
if not os.path.isdir(sample_path):
print("WARNING!! no sample folder")
return []
samples = []
casenum = 1
for sample in sorted(os.listdir(sample_path)):
if sample.endswith(".interaction"):
lines = [f"""<table class="sample" summary="sample data">
if to_pdf:
line = r"""\begin{tabular}{p{0.3\textwidth} p{0.5\textwidth} p{0.0\textwidth}}
\textbf{Read} & \textbf{Sample Interaction %i} & \textbf{Write} \\
\end{tabular}""" % casenum
else:
line = f"""
<table class="sample" summary="sample data">
<tr>
<th style="text-align:left; width:33%;">Read</th>
<th style="text-align:center; width:33%;">Sample Interaction {casenum}</th>
<th style="text-align:right; width:33%;">Write</th>
</tr>
</table>"""]
</table>"""

with open(os.path.join(sample_path, sample), "r", encoding="utf-8") as infile:
sample_interaction = infile.readlines()
lines = []
for interaction in sample_interaction:
data = interaction[1:]
line_type = ""
if interaction[0] == '>':
line_type = "sampleinteractionwrite"
elif interaction[0] == '<':
line_type = "sampleinteractionread"
if to_pdf:
if interaction[0] == '>':
left = True
elif interaction[0] == '<':
left = False
else:
print(f"Warning: Interaction had unknown prefix {interaction[0]}")
lines.append(r"""
\begin{table}[H]
%(justify)s\begin{tabular}{|p{0.6\textwidth}|}
\hline
%(text)s \\
\hline
\end{tabular}
\end{table}""" % {"justify": "" if left else "\\hspace*{\\fill}\n",
"text": data})
else:
print(f"Warning: Interaction had unknown prefix {interaction[0]}")
lines.append(f"""<div class="{line_type}"><pre>{data}</pre></div>""")

samples.append(''.join(lines))
line_type = ""
if interaction[0] == '>':
line_type = "sampleinteractionwrite"
elif interaction[0] == '<':
line_type = "sampleinteractionread"
else:
print(f"Warning: Interaction had unknown prefix {interaction[0]}")
lines.append(f"""<div class="{line_type}"><pre>{data}</pre></div>""")

if to_pdf:
samples.append(line + '\\vspace{-15pt}'.join(lines))
else:
samples.append(line + ''.join(lines))
casenum += 1
continue

if not sample.endswith(".in"):
continue
sample_name = sample[:-3]
Expand All @@ -124,6 +158,14 @@ def samples_to_html(problem_root: str) -> List[str]:
</tbody>
</table>"""
% ({"case": casenum, "input": html.escape(sample_input), "output": html.escape(sample_output)}))

if to_pdf:
# If pdf, convert to markdown
with tempfile.NamedTemporaryFile(mode='w', suffix=".html") as temp_file:
temp_file.write(samples[-1])
temp_file.flush()
samples[-1] = os.popen(f"pandoc {temp_file.name} -t markdown").read()

casenum += 1

return samples
Expand Down
2 changes: 2 additions & 0 deletions problemtools/templates/markdown_pdf/fix_tables.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
---
header-includes:
- '\usepackage{float}'
- '\usepackage{booktabs}'
- '\usepackage{xstring}'
- '\setlength{\aboverulesep}{0pt}'
- '\setlength{\belowrulesep}{0pt}'
Expand Down

0 comments on commit e9b3f8e

Please sign in to comment.