11
16

More than 1 year has passed since last update.

Markdownでレポートを書きたい

Posted at

レポートは面倒

※ 読み飛ばしOK

学生のみなさんならヘッドバンギング並みにうなずいてくれると思いますが、レポートは面倒です。
私のレポート遍歴を簡単に振り返ると、最初は手書きでした。が、文章の追加が難しい、間違ったところを消すのが面倒、表作成が面倒、式を書くのが面倒、ペンを握るのが面倒、と問題だらけでした。
しばらくしてWordを使い始めたところ、文章の追加や間違ったところの削除が非常に簡単になり感動しました。しかし数式は相変わらず面倒です。ラテン文字なんて膨大な数の中から探さないといけないし、「=」の位置が合わないからいまいち美しくないし・・・。
そしてLaTeXを使うようになりました。これなら式も表もきれいに表示できるし、何よりキーボードからあまり手を放したくない自分としてはコマンドでラテン文字や分数などを作れるのは魅力的でした。
が、これも壁にぶつかります。というのも、独特の記法が多くて面倒という壁です。LaTexの長所の一つは文書形式を細かく設定できることです(実際に二段組みやsectionの書式変更、概要や引用の機能を使って前刷りを作ったこともあります)が、正直レポートくらいなら初期設定で問題ありません。そのくせ表や図は独特の記法が多く、見た目の変更をしたければいちいち調べなければなりません。
そしてシンプルにソースコードが見にくい。
ところがMarkdownなら、LaTeXのような細かい文書設定は無理ですが、HTMLタグ、CSS、JavaScriptが使えます。プログラマーにとってなじみの深い言葉が急に出てきました。つまり、表だろうが図だろうがsectionだろうが、CSSで簡単に装飾できるということになります。慣れている人にとっては大きなアドバンテージではないでしょうか。
HTMLとの違いとして、LaTeXを使ったりソースコードを貼ったりが簡単にできるという特長があります。
前置きが長くなりましたが、こういう理由で「Markdownでレポートやりたい!」という結論に至りました。

表紙を作ろう

CSSを使えるということは、表紙も簡単に装飾できるということでもあります。
正直レポートの表紙なんて無地で十分ですが、やってるうちに楽しくなってきたのでいろいろ作ってみました。
なお、pdfが貼れなかったのでpng画像を貼りますが、実際は縦のA4サイズになっています。

シンプルな表紙

表紙.png

ソースコード
<style>
div p {
    font-family: sans-serif;
    text-align: center;
}
.main-title {
    margin: 200px 100px 0;
    padding-bottom: 1rem;
    font-size: 2rem;
    border-bottom: solid;
    border-color: rgb(128, 128, 255, .5);
}
</style>

<div class="front-cover">
    <p class="main-title">コンクリート材料の座屈検査</p>
    <p class="author">田中太郎</p>
</div>

知的な感じに

表紙.png

ソースコード
<style>
div p {
    font-family: "MS PMincho";
    text-align: left;
}
.front-cover {
    margin: 0;
    padding-top: 30%;
    background-color: #97cdf3;
    width: 100%;
    height: 100%;
}
.title {
    margin-left: 40%;
    border: solid;
    border-color: #fff;
}
.main-title {
    padding-top: 0;
    margin-top: 0;
    font-size: 2rem;
    border-bottom: solid;
    border-color: #fff;
    line-height: 3rem;
}
.author {
    margin: 0;
    padding: 0 0 1rem;
}
</style>

<div class="front-cover">
    <div class="title">
        <p class="main-title">フーリエ変換による<br>音波解析に関するレポート</p>
        <p class="author">田中太郎</p>
    </div>
    <div style="page-break-before:always"></div>
</div>
<!-- pdf出力はうまくできるが、png出力がうまくいかなかったため追加。 -->
<!-- pdf出力の際は必要ない -->
<div class="front-cover">
</div>

昔の本っぽく

表紙.png

ソースコード
<style>
div p {
    font-family: "SimSun";
    text-align: center;
}
.front-cover {
    margin-top: 0;
    padding: 200px;
    background-color: #6e5064;
}
.title {
    display: grid;
    flex-direction: column;
    justify-content: space-around;
    grid-template-columns: 250px 80px;
    writing-mode: vertical-rl;
    align-items: center;
    margin-left: 100px; /* pdf */
    margin-left: 160px; /* png */
    border-left: solid;
}
.main-title {
    font-size: 2rem;
}
</style>

<div class="front-cover">
    <div class="title">
        <p class="main-title">塑性加工の歴史</p>
        <p class="author">田中太郎</p>
    </div>
    <div style="page-break-before:always"></div>
</div>
<div class="front-cover">
</div>

図番号をつけよう

自分好みの表紙が作れることは分かりましたが、LaTeXにあってMarkdownにないものがあります。それは、図や表などの番号の自動管理です。
しかし、MarkdownにはJavaScriptが使えるという大きな利点があります。これを使えば図番号を自動管理できるのではないかと考えました。
具体的には以下のようになります。

var label_num = new Map;

const label = (type, id) => {
    if (!label_num.has(type)) {
        label_num.set(type, new Map);
    }
    l = label_num.get(type);
    l.set(id, l.size+1);
}

const ref = (type, id) => {
    var moji = label_num.get(type).get(id)
    document.write(moji);
}

label関数で図などを登録し、ref関数で図の番号などを呼び出せます。

しかしこれでは、label関数を使わない限り番号が生成されないので、章の最初や関数定義の後で以下のように宣言しておく必要があります。

label("img", "pink")
label("img", "grad")
label("img", "title_call")
label("table", "first-table")

上の例では、typeには"img""table"が入っていますが、「typeは自分で決められる」という点に着目すると、例えば"section"ならセクションの数が数えられますし、同様に"subsection""page""first-section-img"なんてものもできるでしょう。

section名を装飾しよう

Markdownでは、#でセクション管理ができますが、一方で<h1>などのタグも使えます。つまり、これをCSSで装飾すれば簡単にsectionの書式を変更できます。
さらに、上で作ったlabel、ref関数と組み合わせることもできます。

スクショで申し訳ないですが、こんな感じになります。

image.png

ソースコード
<style>
h1 {
    padding-left: 2rem;
    font-family: serif;
}
</style>
<h1><script>ref("section", "クレしんチャレンジ")</script>章 クレしんチャレンジ</h1>

図表も箇条書きも装飾しよう

またもスクショになりますが・・・

image.png

ソースコード
<style>
ol {
    list-style-type: none;
    counter-reset: count 1;
    margin-left: 0;
    padding-left: 0;
}
li {
    padding: 5px 0;
    line-height: 1.5em;
    display: flex;
    align-items: center;
}
li::before {
    content: " " counter(count) " ";
    counter-increment: count 1;
    text-align: center;
    border: 1px solid;
    border-radius: 50%;
    width: 1em;
    height: 1em;
    line-height: 1;
    font-size: 1em;
}
</style>
<ol>
    <li>2から始めることもできるし</li>
    <li>行間を変えることもできるし</li>
    <li>数字に丸をつけたりも自由自在</li>
</ol>

image.png

ソースコード
<style>
.img {
    margin-bottom: 0;
    text-align: center;
}

table tr, th, td {
    border: 1px solid;
}
table th {
    font-family: "游ゴシック";
    text-align: left;
}
table td {
    font-size: 0.5rem;
    text-align: right;
}
</style>

<div class="img">
    <img src="pic/title_call.png">
    <p><script>ref("img", "title_call")</script> 完成画像</p>
</div>

<table>
    <tr><th>一列しかないけど</th></tr>
    <tr><td>二行しかないけど</td></tr>
</table>

<p><script>ref("table", "first-table")</script> に表のテストがあります。</p>

ソースコードを貼ろう

image.png

ソースコード
<!-- わざとエスケープシーケンスを使っています -->
\```c
#include <stdio.h>

void main()
{
    printf("hello world\n");
}
\```

LaTeXを使おう

image.png

LaTeXはデフォルト状態ではできないようです。
しかし、以下のようにすれば使えます(scriptタグ内の出典)。

<script type="text/javascript" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js?config=TeX-MML-AM_CHTML">
</script>
<script type="text/x-mathjax-config">
 MathJax.Hub.Config({
 tex2jax: {
 inlineMath: [['$', '$'] ],
 displayMath: [ ['$$','$$'], ["\\[","\\]"] ]
 }
 });
</script>

$$
w_{new}=w_{old}-\eta\frac{\partial E}{\partial w}
$$

まとめ

思ったより大変だったので途中から簡素なものばかりになってしまいましたが、Markdownを使えば世界に一つだけのレポートを作れることが分かりました。
CSSとJavaScriptは初心者なので、上達したらまた挑戦してみたいです。
最後に、今回作ったフルバージョンを載せておきます。

テンプレート.png

ソースコード
<style>
div {
    font-family: "Yu Gothic";
}
div p {
    font-family: sans-serif;
    text-align: center;
}
.main-title {
    margin-top: 200px;
    padding-bottom: 1rem;
    font-size: 2rem;
    border-bottom: solid;
    border-color: rgb(128, 128, 255, .5);
}

.img {
    margin-bottom: 0;
    text-align: center;
}

table tr, th, td {
    border: 1px solid;
}
table th {
    font-family: "游ゴシック";
    text-align: left;
}
table td {
    font-size: 0.5rem;
    text-align: right;
}

h1 {
    padding-left: 2rem;
    font-family: serif;
}

ol {
    list-style-type: none;
    counter-reset: count 1;
    margin-left: 0;
    padding-left: 0;
}
li {
    padding: 5px 0;
    line-height: 1.5em;
    display: flex;
    align-items: center;
}
li::before {
    content: " " counter(count) " ";
    counter-increment: count 1;
    text-align: center;
    border: 1px solid;
    border-radius: 50%;
    width: 1em;
    height: 1em;
    line-height: 1;
    font-size: 1em;
}
</style>

<script>
var label_num = new Map;

const label = (type, id) => {
    if (!label_num.has(type)) {
        label_num.set(type, new Map);
    }
    l = label_num.get(type);
    l.set(id, l.size+1);
}

const ref = (type, id) => {
    var moji = label_num.get(type).get(id)
    document.write(moji);
}

// 使う図たち
label("section", "クレしんチャレンジ")
label("img", "pink")
label("img", "grad")
label("img", "title_call")
label("table", "first-table")
</script>

<script type="text/javascript" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js?config=TeX-MML-AM_CHTML">
</script>
<script type="text/x-mathjax-config">
 MathJax.Hub.Config({
 tex2jax: {
 inlineMath: [['$', '$'] ],
 displayMath: [ ['$$','$$'], ["\\[","\\]"] ]
 }
 });
</script>

<!-- 表紙 -->
<div class="front-cover">
    <p class="main-title">レポートタイトル</p>
    <p class="author">名前</p>
</div><!-- /.front-cover -->

<div style="page-break-before:always"></div>

<h1><script>ref("section", "クレしんチャレンジ")</script>章 クレしんチャレンジ</h1>

まず、以下の画像が作られます。
<div class="img">
    <img src="pic/pink.png">
    <p><script>ref("img", "pink")</script> ピンクの画像</p>
</div>

<p>グラデーション画像を図<script>ref("img", "grad")</script> に示します。</p>

<div class="img">
    <img src="pic/grad.png">
    <p><script>ref("img", "grad")</script> グラデーション画像</p>
</div>

<p>完成画像は図<script>ref("img", "title_call")</script> です。</P>

<div class="img">
    <img src="pic/title_call.png">
    <p><script>ref("img", "title_call")</script> 完成画像</p>
</div>

<table>
    <tr><th>一列しかないけど</th></tr>
    <tr><td>二行しかないけど</td></tr>
</table>

<p><script>ref("table", "first-table")</script> に表のテストがあります。</p>

<ol>
    <li>2から始めることもできるし</li>
    <li>行間を変えることもできるし</li>
    <li>数字に丸をつけたりも自由自在</li>
</ol>

<!-- わざとエスケープシーケンスを書いてます -->
\```c
#include <stdio.h>

void main()
{
    printf("hello world\n");
}
\```

$$
w_{new}=w_{old}-\eta\frac{\partial E}{\partial w}
$$
11
16
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
16