Skip to content

Instantly share code, notes, and snippets.

@youchan
Created September 24, 2018 01:34
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save youchan/52569644ff4ce3fef48cccee96f16c33 to your computer and use it in GitHub Desktop.
Save youchan/52569644ff4ce3fef48cccee96f16c33 to your computer and use it in GitHub Desktop.
require_relative "./renderer"
require "psych"
markdown = Redcarpet::Markdown.new(Renderer, autolink: true, tables: true)
files = Psych.load_file("articles/articles.yaml")
File.open("html/index.html", "w") do |html|
html.write <<~HTML
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
HTML
files.each do |name|
File.open("articles/" + name, "r") do |file|
html.write(markdown.render(file.read))
end
end
html.write <<~HTML
</body>
</html>
HTML
end
require "redcarpet"
class Renderer < Redcarpet::Render::HTML
CLASSES = %w(preface)
def paragraph(text)
case text.strip
when "[begin dialog]"
@in_dialog = true
return "<div class='dialog'>\n"
when "[end dialog]"
@in_dialog = false
return "</div>\n"
when "[page break]"
return "<div class='page-break' />\n"
when /\A%([a-z][a-z0-9\-]*):(.*)\z/
return "<div class='#{$1}'>#{$2}</div>\n" if CLASSES.include?($1)
end
if @in_dialog
case text
when /しんらちゃん「(.+)」/
return <<~HTML
<div class="speech shinra">
<div class="icon"></div>
<div class="baloon">
<p>#{$1}</p>
</div>
</div>
HTML
when /黒猫先生「(.+)」/
return <<~HTML
<div class="speech kuroneko">
<div class="icon"></div>
<div class="baloon">
<p>#{$1}</p>
</div>
</div>
HTML
end
end
"<p>#{text.gsub(/ $/, "<br>\n")}</p>\n"
end
end
@page {
size: A5;
marks: crop cross;
bleed: 3mm;
margin: 12mm;
}
@page :left {
margin-left: 20mm;
@bottom-left {
font-size: 12px;
font-weight: bold;
content: counter(page);
}
}
@page :right {
margin-right: 20mm;
@bottom-right {
font-size: 12px;
font-weight: bold;
content: counter(page);
}
}
body {
counter-reset: h1 h2 h3;
font-size: 14px;
}
p {
text-indent: 1rem;
text-align: justify;
}
h1::before {
counter-increment: h1;
content: counter(h1) '章 ';
}
h1 {
counter-reset: h2 h3;
break-before: page;
background-color: #dddddd;
padding: 2rem 1rem;
margin-bottom: 3rem;
border-bottom: solid 4px #aaaaaa;
}
h2::before {
counter-increment: h2;
content: counter(h1) '.' counter(h2) ' ';
}
h2 {
counter-reset: h3;
padding: 8px;
border-bottom: dotted 4px #cccccc;
margin-bottom: 2rem;
}
h3::before {
counter-increment: h3;
content: counter(h1) '.' counter(h2) '.' counter(h3) ' ';
}
h3 {
border-left: solid 1rem #cccccc;
padding-left: 1rem;
}
img {
width: 90%;
}
.preface {
font-size: 36px;
font-weight: bold;
background-color: #aaaaaa;
color: #ffffff;
padding: 3rem;
margin-bottom: 2rem;
}
.dialog {
margin-bottom: 1.5rem;
}
.page-break {
break-before: page;
break-after: page;
}
.speech {
margin-bottom: 0.5rem;
break-inside: avoid-page;
}
.speech .icon {
float: left;
width: 32px;
height: 32px;
border: solid 0.1px;
border-radius: 16px;
}
.speech.shinra .icon {
background-image: url(./shinra.png);
background-size: cover;
}
.speech.kuroneko .icon {
background-image: url(./kuroneko.png);
background-size: cover;
}
.speech .baloon {
position: relative;
border-radius: 4px;
margin-left: 48px;
padding: 8px;
background-color: #dddddd;
}
.speech .baloon:before {
content: "";
position: absolute;
top: 16px;
left: -8px;
width: 0px;
height: 0px;
border-style: solid;
border-width: 8px 0 8px 8px;
border-color: #dddddd transparent transparent;
}
.speech p {
display: inline;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment