Skip to content

Commit

Permalink
[latex] Add command problem_slides
Browse files Browse the repository at this point in the history
  • Loading branch information
mpsijm committed Nov 12, 2023
1 parent bdd0b2d commit 0f9fb8f
Show file tree
Hide file tree
Showing 8 changed files with 186 additions and 8 deletions.
39 changes: 32 additions & 7 deletions bin/latex.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,16 +241,23 @@ def find_logo():
return config.tools_root / 'latex/images/logo-not-found.pdf'


TYPE_PROBLEM = 'problem'
TYPE_PROBLEM_SLIDE = 'problem-slide'
TYPE_SOLUTION = 'solution'


# Build a pdf for an entire problemset in the given language. Explanation in latex/readme.md
def build_contest_pdf(contest, problems, tmpdir, language, solutions=False, web=False):
def build_contest_pdf(contest, problems, tmpdir, language, build_type=TYPE_PROBLEM, web=False):
log(
f"Building contest {'statements' if not solutions else 'solutions'} PDF for language {language} "
f"Building contest {build_type}s PDF for language {language} "
)
builddir = tmpdir / contest
builddir.mkdir(parents=True, exist_ok=True)
build_type = 'solution' if solutions else 'problem'

main_file = 'solutions' if solutions else 'contest'
problem_slides = build_type == TYPE_PROBLEM_SLIDE
solutions = build_type == TYPE_SOLUTION

main_file = 'problem-slides' if problem_slides else 'solutions' if solutions else 'contest'
main_file += '-web.tex' if web else '.tex'

default_config_data = {
Expand Down Expand Up @@ -295,6 +302,8 @@ def build_contest_pdf(contest, problems, tmpdir, language, solutions=False, web=
else config.tools_root / 'latex' / f'contest-{build_type}.tex'
).read_text()

probyaml = problems_yaml()

for problem in problems:
if build_type == 'problem':
prepare_problem(problem)
Expand All @@ -312,12 +321,28 @@ def build_contest_pdf(contest, problems, tmpdir, language, solutions=False, web=
warn(f'{problem.name}: solution.{language}.tex not found')
continue

background = next(
(p['rgb'] for p in probyaml if p['id'] == str(problem.path) and 'rgb' in p), '#ffffff'
)[1:]
# Source: https://github.com/DOMjudge/domjudge/blob/095854650facda41dbb40966e70199840b887e33/webapp/src/Twig/TwigExtension.php#L1056
foreground = (
'000000'
if sum(int(background[i : i + 2], 16) for i in range(0, 6, 2)) > 450
else 'ffffff'
)
border = "".join(
("00" + hex(max(0, int(background[i : i + 2], 16) - 64))[2:])[-2:]
for i in range(0, 6, 2)
)
problems_data += util.substitute(
per_problem_data,
{
'problemlabel': problem.label,
'problemyamlname': problem.settings.name[language].replace('_', ' '),
'problemauthor': problem.settings.author,
'problembackground': background,
'problemforeground': foreground,
'problemborder': border,
'timelimit': get_tl(problem),
'problemdir': problem.path.absolute().as_posix(),
'problemdirname': problem.name,
Expand All @@ -339,9 +364,9 @@ def build_contest_pdf(contest, problems, tmpdir, language, solutions=False, web=
return build_latex_pdf(builddir, Path(main_file), language)


def build_contest_pdfs(contest, problems, tmpdir, lang=None, solutions=False, web=False):
def build_contest_pdfs(contest, problems, tmpdir, lang=None, build_type=TYPE_PROBLEM, web=False):
if lang:
return build_contest_pdf(contest, problems, tmpdir, lang, solutions, web)
return build_contest_pdf(contest, problems, tmpdir, lang, build_type, web)

"""Build contest PDFs for all available languages"""
statement_languages = set.intersection(*(set(p.statement_languages) for p in problems))
Expand All @@ -354,5 +379,5 @@ def build_contest_pdfs(contest, problems, tmpdir, lang=None, solutions=False, we
else:
languages = statement_languages
return all(
build_contest_pdf(contest, problems, tmpdir, lang, solutions, web) for lang in languages
build_contest_pdf(contest, problems, tmpdir, lang, build_type, web) for lang in languages
)
27 changes: 26 additions & 1 deletion bin/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,26 @@ def build_parser():
pdfparser.add_argument('--web', action='store_true', help='Create a web version of the pdf.')
pdfparser.add_argument('-1', action='store_true', help='Only run the LaTeX compiler once.')

# Problem slides
pdfparser = subparsers.add_parser(
'problem_slides', parents=[global_parser], help='Build the problem slides pdf.'
)
# pdfparser.add_argument(
# '--all',
# '-a',
# action='store_true',
# help='Create problem statements for individual problems as well.',
# )
pdfparser.add_argument('--no-timelimit', action='store_true', help='Do not print timelimits.')
pdfparser.add_argument(
'--watch',
'-w',
action='store_true',
help='Continuously compile the pdf whenever a `problem_statement.tex` changes. Note that this does not pick up changes to `*.yaml` configuration files.',
)
# pdfparser.add_argument('--web', action='store_true', help='Create a web version of the pdf.')
pdfparser.add_argument('-1', action='store_true', help='Only run the LaTeX compiler once.')

# Solution slides
solparser = subparsers.add_parser(
'solutions', parents=[global_parser], help='Build the solution slides pdf.'
Expand Down Expand Up @@ -983,7 +1003,12 @@ def run_parsed_arguments(args):

if action in ['solutions']:
success &= latex.build_contest_pdfs(
contest, problems, tmpdir, solutions=True, web=config.args.web
contest, problems, tmpdir, build_type=latex.TYPE_SOLUTION, web=config.args.web
)

if action in ['problem_slides']:
success &= latex.build_contest_pdfs(
contest, problems, tmpdir, build_type=latex.TYPE_PROBLEM_SLIDE, web=config.args.web
)

if action in ['zip']:
Expand Down
17 changes: 17 additions & 0 deletions latex/contest-problem-slide.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
\begingroup\graphicspath{{{%problemdir%}/problem_statement/}}
\renewcommand{\problemlabel}{{%problemlabel%}}
\renewcommand{\problemyamlname}{{%problemyamlname%}}
\renewcommand{\problemauthor}{{%problemauthor%}}
\renewcommand{\problembackground}{{%problembackground%}}
\renewcommand{\problemforeground}{{%problemforeground%}}
\renewcommand{\problemborder}{{%problemborder%}}
\renewcommand{\timelimit}{{%timelimit%}}
\input{{%problemdir%}/problem_statement/problem-slide.\lang.tex}
\renewcommand{\problemlabel}{}
\renewcommand{\problemyamlname}{}
\renewcommand{\problemauthor}{}
\renewcommand{\problembackground}{}
\renewcommand{\problemforeground}{}
\renewcommand{\problemborder}{}
\renewcommand{\timelimit}{}
\endgroup
3 changes: 3 additions & 0 deletions latex/contest-solution.tex
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@
\renewcommand{\timelimit}{{%timelimit%}}
\input{{%problemdir%}/problem_statement/solution.\lang.tex}
\renewcommand{\problemlabel}{}
\renewcommand{\problemyamlname}{}
\renewcommand{\problemauthor}{}
\renewcommand{\timelimit}{}
\endgroup
101 changes: 101 additions & 0 deletions latex/problem-slides.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
\documentclass[rgb,dvipsnames,aspectratio=169,9pt,t]{beamer}

\usepackage[T1, OT1]{fontenc}
\DeclareTextSymbolDefault{\dh}{T1}
\usepackage[english]{babel}
\usepackage{lmodern}

%-------------------------------------------------------------------------------
% The following are required for most problems:
%-------------------------------------------------------------------------------
\usepackage{amsmath,amssymb}
\usepackage{pgf,tikz}
\usepackage{mathrsfs}
\usetikzlibrary{arrows}
\usetikzlibrary{shapes}
\usetikzlibrary{backgrounds}
\usetikzlibrary{patterns}
\usetikzlibrary{positioning}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.15}
\usepackage{graphicx}
\usepackage{listings}
%\usepackage{subcaption}
\usepackage{algorithm}
\usepackage[makeroom]{cancel}
\usepackage[noend]{algpseudocode}
\usepackage{standalone}
\usepackage{ifthen}
\usepackage{tcolorbox}
\usepackage[autoplay,controls,loop,poster=last]{animate}

\lstset{
backgroundcolor=\color{white},
tabsize=4,
language=python,
basicstyle=\footnotesize\ttfamily,
breaklines=true,
keywordstyle=\color[rgb]{0, 0, 1},
commentstyle=\color[rgb]{0, 0.5, 0},
stringstyle=\color{red}
}

\newcommand{\timelimit}{0.0s}
\newcommand{\problemlabel}{} % Empty to hide activity chart
\newcommand{\problemauthor}{Problem author}
\newcommand{\problembackground}{}
\newcommand{\problemforeground}{}
\newcommand{\problemborder}{}
% TODO: Clean these up
\newcommand{\problemyamlname}{Problem name}
\newcommand{\fullproblemtitle}{\problemlabel: \problemyamlname}
\newcommand{\problemtitle}{\problemyamlname}

\usetheme[numbering=none,block=fill]{metropolis}

\newcommand{\illustration}[3]{
\begin{column}[T]{#1\textwidth}
\includegraphics[width=\textwidth]{#2}
\ifstrempty{#3}{
\vspace{-5pt}
}{
\begin{flushright}
\vspace{-5pt}
\tiny #3
\end{flushright}
}
\end{column}
}

\setbeamertemplate{frametitle}{%
\nointerlineskip%
\vspace{1em}%
\begin{minipage}{0.06\paperwidth}%
\begin{tikzpicture}
\definecolor{problembackground}{HTML}{\problembackground}
\definecolor{problemforeground}{HTML}{\problemforeground}
\definecolor{problemborder}{HTML}{\problemborder}
\node[rectangle,rounded corners,thick,minimum size=2em,draw=problemborder,fill=problembackground,text=problemforeground] (0, 0) {\Huge\problemlabel};
\end{tikzpicture}
\end{minipage}%
\begin{minipage}{0.8\paperwidth}%
\color{black}%
\ifdefempty{\problemlabel}{%
\insertframetitle\strut%
}{%
\problemtitle%
\\[0.3em]%
\tiny%
Time limit: \timelimit{}s%
\quad\quad%
Problem Author: \problemauthor%
\strut%
}%
\end{minipage}%
\hfill%
}

\begin{document}
\input{./contest-problem-slides.tex}
\end{document}
Binary file added skel/problem.zip
Binary file not shown.
7 changes: 7 additions & 0 deletions test/problems/boolfind/data/sample/1.interaction
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<1
<5
>READ 2
<false
>READ 1
<true
>OUTPUT 1
Binary file added test/problems/identity.zip
Binary file not shown.

0 comments on commit 0f9fb8f

Please sign in to comment.