Skip to content

Instantly share code, notes, and snippets.

@yosupo06
Last active May 2, 2020 06:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yosupo06/97e4170c32c4468c4c2944450cbd1e8d to your computer and use it in GitHub Desktop.
Save yosupo06/97e4170c32c4468c4c2944450cbd1e8d to your computer and use it in GitHub Desktop.
from jinja2 import *
from markdown import markdown
from sys import stderr
# evaluate markdown
markdown_evaluated = markdown(
open('task.md', 'r').read(), extensions=[
'markdown.extensions.fenced_code',
],
)
with open('test.mid.txt', 'w') as f:
f.write(markdown_evaluated)
# html tag for change lang
def lang_div_start(lang):
return '<div class="lang-{}">'.format(lang)
def lang_div_end(lang):
return '</div>'
# {{keyword.statement}}, {{keyword.constraints}}, ...
def to_keyword_str(lang_dict):
s = ''
for k, v in lang_dict.items():
s += lang_div_start(k) + v + lang_div_end(k)
return s
keywords = {
'statement': to_keyword_str({
'en': 'Problem Statement',
'ja': '問題文',
}),
'constraints': to_keyword_str({
'en': 'Constraints',
'ja': '制約',
}),
'input': to_keyword_str({
'en': 'Input',
'ja': '入力',
}),
'output': to_keyword_str({
'en': 'Output',
'ja': '出力',
}),
'sample': to_keyword_str({
'en': 'Sample',
'ja': 'サンプル',
}),
}
# {{param.A_AND_B_MAX}}
def param_to_str(v):
assert(v == 1_000_000_000)
return "1{,}000{,}000{,}000"
params = {
'A_AND_B_MAX': param_to_str(1_000_000_000)
}
# {{example.example_00}}
class ExampleReader:
sample_template = '''
<div class="uk-grid-small uk-child-width-1-2@s" uk-grid>
<div><pre>{}</pre></div>
<div><pre>{}</pre></div>
</div>
'''
def __init__(self):
self.counter = 1
def __getitem__(self, key):
print('read example: {}'.format(key), file=stderr)
infile = open(key + '.in').read()
outfile = open(key + '.out').read()
s = r'<h3># {}</h3>'.format(self.counter)
self.counter += 1
s += self.sample_template.format(infile, outfile)
return s
# {{setlang('en')}}, {{resetlang()}}
now_lang = ''
def set_lang(lang):
global now_lang
assert(now_lang == '')
now_lang = lang
return lang_div_start(lang)
def reset_lang():
global now_lang
s = lang_div_end(now_lang)
assert(now_lang != '')
now_lang = ''
return s
# evaluate template
template = Template(markdown_evaluated)
template.environment.globals['setlang'] = set_lang
template.environment.globals['resetlang'] = reset_lang
statement = template.render(
keyword=keywords,
param=params,
example=ExampleReader(),
)
# to html
html_header = '''
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<!-- Uikit -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://judge.yosupo.jp/public/css/uikit.min.css" />
<script src="https://judge.yosupo.jp/public/js/uikit.min.js"></script>
<script src="https://judge.yosupo.jp/public/js/uikit-icons.min.js"></script>
<!-- Katex -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.10.2/dist/katex.min.css"
integrity="sha384-yFRtMMDnQtDRO8rLpMIKrtPCD5jdktao2TV19YiZYWMDkUR5GQZR/NOVTdquEx1j" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.10.2/dist/katex.min.js"
integrity="sha384-9Nhn55MVVN0/4OFx7EE5kpFBPsEMZxKTCnA+4fqDmg12eCTqGi6+BB2LjY8brQxJ"
crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.10.2/dist/contrib/auto-render.min.js"
integrity="sha384-kWPLUVMOks5AQFrykwIup5lo0m3iMkkHrD0uJ4H5cjeGihAutqP0yW0J6dpFiVkI" crossorigin="anonymous"
onload="renderMathInElement(document.body);"></script>
<script>
document.addEventListener("DOMContentLoaded", function () {
renderMathInElement(
document.body, {
delimiters: [
{ left: "$$", right: "$$", display: true },
{ left: "$", right: "$", display: false }],
ignoredTags: [],
})
});
</script>
<script>
function getLang(lang) {
lang = localStorage.getItem("lang");
if (lang == "ja" || lang == "en") return lang;
for (e of navigator.languages) {
if (e.startsWith("en")) return "en";
if (e.startsWith("ja")) return "ja";
}
return "en";
}
function refLang() {
lang = getLang();
document.getElementById("nav-lang").text = `Lang(${lang})`;
document.querySelectorAll(".lang-en, .lang-ja").forEach(function(e) {
if (e.classList.contains(`lang-${lang}`)) {
e.style.display = 'block';
} else {
e.style.display = 'none';
}
})
}
function setLang(lang) {
localStorage.setItem("lang", lang)
refLang()
}
document.addEventListener("DOMContentLoaded", refLang);
</script>
</head>
'''
html_body = '''
<body>
<div class="uk-navbar-container" uk-navbar>
<div class="uk-navbar-right">
<ul class="uk-navbar-nav">
<li>
<a href="#" id="nav-lang">Lang()</a>
<div class="uk-navbar-dropdown">
<ul class="uk-nav uk-navbar-dropdown-nav">
<li><a href="#" onclick="setLang('ja')">Ja</a></li>
<li><a href="#" onclick="setLang('en')">En</a></li>
</ul>
</div>
</li>
</ul>
</div>
</div>
<section class="uk-section">
<div class="uk-container">
{}
</div>
</section>
</body>
</html>
'''
html = html_header + html_body.format(statement)
with open('test.html', 'w') as f:
f.write(html)

{{keyword.statement}}

{{ setlang('en') }} You are given integers $A$ and $B$. Print $A + B$. {{ resetlang() }} {{ setlang('ja') }} 整数 $A, B$ が与えられます。 $A + B$ を出力してください。 {{ resetlang() }}

{{keyword.constraints}}

  • $0 \leq A, B \leq {{param.A_AND_B_MAX}}$

{{keyword.input}}

$A$ $B$

{{keyword.output}}

$A + B$

{{keyword.sample}}

{{example.example_00}}

{{example.example_01}}

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<!-- Uikit -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://judge.yosupo.jp/public/css/uikit.min.css" />
<script src="https://judge.yosupo.jp/public/js/uikit.min.js"></script>
<script src="https://judge.yosupo.jp/public/js/uikit-icons.min.js"></script>
<!-- Katex -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.10.2/dist/katex.min.css"
integrity="sha384-yFRtMMDnQtDRO8rLpMIKrtPCD5jdktao2TV19YiZYWMDkUR5GQZR/NOVTdquEx1j" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.10.2/dist/katex.min.js"
integrity="sha384-9Nhn55MVVN0/4OFx7EE5kpFBPsEMZxKTCnA+4fqDmg12eCTqGi6+BB2LjY8brQxJ"
crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.10.2/dist/contrib/auto-render.min.js"
integrity="sha384-kWPLUVMOks5AQFrykwIup5lo0m3iMkkHrD0uJ4H5cjeGihAutqP0yW0J6dpFiVkI" crossorigin="anonymous"
onload="renderMathInElement(document.body);"></script>
<script>
document.addEventListener("DOMContentLoaded", function () {
renderMathInElement(
document.body, {
delimiters: [
{ left: "$$", right: "$$", display: true },
{ left: "$", right: "$", display: false }],
ignoredTags: [],
})
});
</script>
<script>
function getLang(lang) {
lang = localStorage.getItem("lang");
if (lang == "ja" || lang == "en") return lang;
for (e of navigator.languages) {
if (e.startsWith("en")) return "en";
if (e.startsWith("ja")) return "ja";
}
return "en";
}
function refLang() {
lang = getLang();
document.getElementById("nav-lang").text = `Lang(${lang})`;
document.querySelectorAll(".lang-en, .lang-ja").forEach(function(e) {
if (e.classList.contains(`lang-${lang}`)) {
e.style.display = 'block';
} else {
e.style.display = 'none';
}
})
}
function setLang(lang) {
localStorage.setItem("lang", lang)
refLang()
}
document.addEventListener("DOMContentLoaded", refLang);
</script>
</head>
<body>
<div class="uk-navbar-container" uk-navbar>
<div class="uk-navbar-right">
<ul class="uk-navbar-nav">
<li>
<a href="#" id="nav-lang">Lang()</a>
<div class="uk-navbar-dropdown">
<ul class="uk-nav uk-navbar-dropdown-nav">
<li><a href="#" onclick="setLang('ja')">Ja</a></li>
<li><a href="#" onclick="setLang('en')">En</a></li>
</ul>
</div>
</li>
</ul>
</div>
</div>
<section class="uk-section">
<div class="uk-container">
<h2><div class="lang-en">Problem Statement</div><div class="lang-ja">問題文</div></h2>
<p><div class="lang-en">
You are given integers $A$ and $B$. Print $A + B$.
</div>
<div class="lang-ja">
整数 $A, B$ が与えられます。 $A + B$ を出力してください。
</div></p>
<h2><div class="lang-en">Constraints</div><div class="lang-ja">制約</div></h2>
<ul>
<li>$0 \leq A, B \leq 1{,}000{,}000{,}000$</li>
</ul>
<h2><div class="lang-en">Input</div><div class="lang-ja">入力</div></h2>
<pre><code>$A$ $B$
</code></pre>
<h2><div class="lang-en">Output</div><div class="lang-ja">出力</div></h2>
<pre><code>$A + B$
</code></pre>
<h2><div class="lang-en">Sample</div><div class="lang-ja">サンプル</div></h2>
<p><h3># 1</h3>
<div class="uk-grid-small uk-child-width-1-2@s" uk-grid>
<div><pre>1234 5678
</pre></div>
<div><pre>6912
</pre></div>
</div>
</p>
<p><h3># 2</h3>
<div class="uk-grid-small uk-child-width-1-2@s" uk-grid>
<div><pre>1000000000 1000000000
</pre></div>
<div><pre>2000000000
</pre></div>
</div>
</p>
</div>
</section>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment