adbird(広告鳥) 備忘録

VivaldiブラウザのWebパネルに簡易メディアプレイヤーを追加

概要

VivaldiブラウザのWebパネルにYouTubeやストリーミング系の音楽サイトを表示して、音楽を再生するってのは見かけるけど、ローカル(自分のPC内)にある音楽データを再生してくれる音楽プレーヤーをパネルに表示できないだろうか?(Operaブラウザにかつてあった「音楽パネル」が念頭にあったw)といろいろ調べたところ、以下の方法でできた。

追記:

これを作った後に、 Winamp2-js の存在を知りました。機能的にはたぶん、そちらのほうが幸せになりますw。

ただし、Winamp2-js だと、動画の音声は再生できるけど、映像は表示できないっぽいです。

ここで紹介する方法では、もちろん、映像も含めて、動画の再生が可能です!
それぐらいしか強みはないです…。
あとは表示がシンプルで見やすいというところぐらいしか…w。

Winamp2-js についての個人的感想としては、Winampは昔、お世話になってたけどやはりデザイン的に古いなぁと思ったのと(スキンが代えられるのは知っているけど)、操作ボタン・フォント等が小さすぎ、そして、「(パネルじゃなくて)Winampで再生してる」って感じがして、ちょっと違うかな…ってなった(^_^;)。

更新

  • Windowsの方への注意事項(html保存の際に UTF-8 に)追加。(2018/4/8)
  • 「開く/追加」ボタンを追加、その他CSS修正。(2018/3/27)
    • @z7wacg2u さん、本当にありがとうございました!
  • htmlソースを一部修正 (2018/3/25)
    • プレイリストの曲名に番号が付くようにした。
    • 背景色・フォント色を変更。
    • tableタグを削除して、パネルの幅に合わせてプレイヤー・動画が拡大・縮小されるようになった。
  • Webパネルにアイコンが表示されるように修正。(2018/3/22)
    • ※表示されたり、されなかったりと動作が不安定です…。
  • パネルを狭めると「次へ」が隠れるので、再生曲名の下に「次へ」ボタンが来るように修正。

Webパネル用のアイコンを保存

(※追記:原因は不明ですが、アイコンが表示されたりされなかったりします…。不安定なため、このプロセスは飛ばしてもらって構いません。)

なくてもいいのだけど、Webパネルにアイコンが表示されないのが寂しかったので、アイコンが表示されるようにする。

【フリーアイコン】 再生 あたりから、適当に好きなアイコンをもらってきて、保存。

ここでは「再生アイコン.png」として保存。
32px(ピクセル)× 32px の大きさにするのがいいっぽい。

後述のhtmlソースの、以下の部分で指定すれば、アイコンが表示される(表示されなかったら、いったんWebパネルから削除して、もう一度Webパネルに追加すれば表示されるはず)。

  <!-- パネルのアイコン画像 -->
  <link rel="shortcut icon" type="image/png" href="再生アイコン.png">

htmlファイル を保存

下記リンク先にアップしたhtmlをローカル(自分のPC)に保存するか、

下記のソースを「mediaplayer.html」として保存。

Windowsの方は保存の際に、文字コードUTF-8 にして保存しないと、「開く/追加」「次へ」ボタンが文字化けするかもしれません。

いまさらHTML5 (簡易プレイヤー編)」のhtmlソースがほぼそのままのベースとなっています。また、@z7wacg2u さんに「開く/追加」ボタンのJavaScriptの編集をしていただきました。

適宜、前述のアイコン画像ファイルのURLや、デフォルトの音量部分を編集すること。

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <!-- パネルのアイコン画像 -->
  <link rel="shortcut icon" type="image/png" href="再生アイコン.png">

  <title>メディアプレイヤー</title>
  <style>
    /* 背景色 フォント色 */
    body{background-color:#E1DDD8;
      color:#4F4F4F;}
    .nowplaying{margin-top:5px;
      margin-left:5px;
      margin-bottom:5px;}

        label {color: #E5E5E5;  
            background-color: #7D7D7D;
            margin:0 0 0 5px;
            padding: 4px 6px;
            border-radius: 5px;
            font-size:9pt;}
    .openbutton{display:none;}
    .nextbutton{float:right;
                display:block;
                border-style: none;
                background-color: #7D7D7D;
                color: #E5E5E5;
                margin:0 5px 3px 0;
                padding:3px 15px;
                border-radius: 5px;
                font-size:9pt
}

  </style>
  <script type="text/javascript">
    // VIDEOタグ
    var video = null;
    // AUDIOタグ
    var audio = null;
    // ファイル一覧
    var list = [];
    // 初期処理
    function init() {
      // ファイルドロップイベント設定
      document.getElementById("drop").addEventListener("dragover", eventStop, false);
      document.getElementById("drop").addEventListener("drop", filedrop, false);
      // VIDEOタグ取得
      video = document.getElementById("video");
      // 終了イベント取得設定
      video.addEventListener("ended", playerEvent, false);
      // VIDEO非表示
      video.style.display = "none";
      // AUDIOタグ取得
      audio = document.getElementById("audio");
      // 終了イベント取得設定
      audio.addEventListener("ended", playerEvent, false);
      // AUDIO非表示
      audio.style.display = "none";
      // 次へボタン押下イベント設定
      document.getElementById("next").addEventListener("click", next, false);
      // 次へボタン非表示
      document.getElementById("next").style.display = "none";
      // ファイル選択ボタンのイベント
      document.getElementById("openfile").addEventListener("change", open, false);
      // キーイベント
      document.onkeydown = key_event;
    }
    // ショートカットキー
    function key_event() {
      var code = event.keyCode;
      switch(code) {
        // Space
        case 32:
          // audioの再生と一時停止Toggle
          if (audio.paused) audio.play(); else audio.pause();
          // videoの再生と一時停止Toggle
          if (video.paused) video.play(); else video.pause();
          break;
        // N
        case 78:
          next();
          break;
      }
    }
    // ファイルがドラッグされた場合
    function eventStop(event) {
      // イベントキャンセル
      event.stopPropagation();
      event.preventDefault();
      // 操作をリンクに変更
      event.dataTransfer.dropEffect = "link";
    }
    // ファイルがドロップされた場合
    function filedrop(event) {
      try {
        // イベントキャンセル
        event.stopPropagation();
        event.preventDefault();
        // ファイル存在チェック
        if (event.dataTransfer.files) {
          var old = list.length;
          // ファイル一覧取得
          var files = event.dataTransfer.files;
          // ファイル数分ループ
          for (var i = 0; i < files.length; i++) {
            // ファイル取得
            var file = files[i];
            // 再生可能ファイルであるか判定
            if (video.canPlayType(file.type) || audio.canPlayType(file.type)) {
              // ファイル情報生成
              var item = {
                name: file.name,
                type: file.type,
                url: URL.createObjectURL(file)
              };
              // ファイル追加
              list.push(item);
            }
          }
          // 表示
          view();
          // 最初であるか判定
          if (old == 0 && list.length > 0) {
            // 次へボタン表示
            document.getElementById("next").style.display = "block";
            // 次を再生(最初)
            next();
          }
        }
      } catch (e) {
        // エラーの場合
        alert(e.message);
      }
    }
    // ファイルを開く
    function open() {
      var fileRef = document.getElementById("openfile");
      if (fileRef.files) {
        var old = list.length;
        // ファイル一覧
        var files = fileRef.files;
        for (var i = 0; i < files.length; i++) {
          // ファイル取得
          var file = files[i];
          // 再生可能ファイルであるか判定
          if (video.canPlayType(file.type) || audio.canPlayType(file.type)) {
            // ファイル情報生成
            var item = {
                name: file.name,
                type: file.type,
                url: URL.createObjectURL(file)
                };
            // ファイル追加
           list.push(item);
          }
        }
        // 表示
        view();
        // 最初であるか判定
        if (old == 0 && list.length > 0) {
          // 次へボタン表示
          document.getElementById("next").style.display = "block";
          // 次を再生(最初)
          next();
        }
      }
    }
    // 次を再生
    function next() {
        // ファイル数チェック
        if (list.length > 0) {
            // 最初のファイルを設定
            var item = list[0];
            // ファイル数分ループ
            for (var i = 0; i < list.length; i++) {
                // VIDEOタグかAUDIOタグと一致するか判定
                if (video.src === list[i].url || audio.src === list[i].url) {
                    // 最後のファイルか判定
                    if (i != list.length - 1) {
                        // 次のファイルを設定
                        item = list[i + 1];
                        break;
                    }
                }
            }
            // AUDIO停止
            audio.pause();
            // VIDEO停止
            video.pause();
            // タイプ判断
            if (item.type.indexOf("audio/") == 0) {
                // AUDIOなので、VIDEO初期化
                video.src = "";
                video.style.display = "none";
                // AUDIO表示
                audio.style.display = "block";
                // 前回とURLが異なるか判定
                if (audio.src != item.url) {
                    // URL更新
                    audio.src = item.url;
                }
                // AUDIO再生
                audio.play();
                // デフォルトの音量調整 0〜1.0
                audio.volume = 0.5;
            } else if (item.type.indexOf("video/") == 0) {
                // VIDEOなので、AUDIO初期化
                audio.src = "";
                audio.style.display = "none";
                // VIDEO表示
                video.style.display = "block";
                // 前回とURLが異なるか判定
                if (video.src != item.url) {
                    // URL更新
                    video.src = item.url;
                }
                // VIDEO再生
                video.play();
                // デフォルトの音量調整 0〜1.0
                video.volume = 0.5;
            }
            // ファイル名表示
            document.getElementById("playfilename").textContent = item.name;
        }
    }
    // イベント取得
    function playerEvent(event) {
        // イベントタイプ判定
        if (event.type == "ended") {
            // 終了なので、次へ
            next();
        }
    }
    // 表示
    function view() {
        // 表示されているリスト取得
        var nodes = document.getElementById("playlist").childNodes;
        // 全部削除
        while (nodes.length > 0) {
            document.getElementById("playlist").removeChild(nodes[0]);
        }
        // リスト数分追加 番号なし表示
        /*
        for (var i = 0; i < list.length; i++) {
          var div = document.createElement("div");
          div.textContent = list[i].name;
          document.getElementById("playlist").appendChild(div);
        }
        */
        // リスト数分追加 番号あり表示
        for (var i = 0; i < list.length; i++) {
            var li = document.createElement("li");
            li.textContent = list[i].name;
            document.getElementById("playlist").appendChild(li);
        }
        // 表示幅調整
        document.getElementById("playlist").style.width = "100%";
    }
    // ロードイベント登録
    window.addEventListener("load", init, false);
  </script>
</head>
<body>
  <div id="drop" style="position: fixed; top: 0px; left: 0px; width: 100%; height: 100%; overflow: auto;">

    <!-- ファイル名 -->
    <div id="playfilename" class="nowplaying"></div>

    <!-- ファイルを開く -->
    <label for="openfile">
    開く/追加
    <input id="openfile" type="file"  class="openbutton" accept="audio/*,video/*" multiple />
    </label>

    <!-- 次へ部分 -->
    <button id="next" class="nextbutton">次へ</button>
    <!-- プレイヤー部分 -->
    <div style="resize: both; overflow: auto; width: 100%;">
        <video id="video" controls style="width: 99%; height: 99%;"></video>
        <audio id="audio" controls style="width: 99%; height: 40px"></audio>
    </div>

    <!-- ドロップ&一覧部分 番号なしで表示したい場合はこちら。
    <div id="playlist" style="width: 100px; height:; overflow: auto;"></div>
    -->
    <!-- ドロップ&一覧部分 番号つきで表示-->
    <ol id="playlist" style="width:; height:; overflow: auto;">
    </ol>
  </div>
</body>
</html>

デフォルトの音量調整

デフォルトの音量を調整したい場合、上記htmlソースのこの部分を書き換えてください。

 // デフォルトの音量調整 0〜1.0
 audio.volume = 0.5;

(中略)

// デフォルトの音量調整 0〜1.0
video.volume = 0.5;

Webパネルに追加

Vivaldiブラウザで「mediaplayer.html」を開いて、ウェブパネルに追加。

音楽データや動画データをドラッグ・アンド・ドロップ
または
「開く/追加」ボタンをクリックして、追加

すれば再生される。


追記:

Vivaldiのピクチャ―・イン・ピクチャ―の機能が邪魔して、初回の「開く/追加」のボタンがうまく作動してくれません(「開く/追加」ボタンの右下ギリギリをクリックすれば開きます)。

初回のみ「開く/追加」の右下ギリギリをクリックするか、音楽データや動画データをドラッグ・アンド・ドロップしてください。

またはVivaldiの設定からピクチャ―・イン・ピクチャ―の機能そのものを無効化してください。


プレイリストをクリアしたい場合は、Webパネルのツールバー(※1)の「再読み込み」か「ホームページへ移動」のボタンを押す。

※1:
表示されていなかったら、ウェブパネルのアイコン上で
 右クリック > ツールバー > 表示
 右クリック > ツールバー > 全てのコントロールを表示
で表示する

こんな感じ

こんな感じにブラウザで音楽再生が可能に。僕はウェブパネルを右側に表示している。

f:id:adbird:20180327171320p:plain

他力本願な願い… 願いがかなった!

僕は htmlとcssは少しは分かるけど、JavaScript はさっぱりなので(音量調整のやつはネットで調べて偶々うまくいっただけ)、どなたか、ボタンを押せば、フォルダダイアログが開いて、プレイリストにファイルを追加する機能の「開く/追加」ボタンを作ってくれないだろうか…。
ドラッグアンドドロップのためにわざわざファイルマネージャを開きたくない。

@z7wacg2u さんからJavaScriptソースの提供をいただき、「開く/追加」ボタンが付きました!

これでフォルダダイアログが開いて、ファイルが追加できるようになりました!
もちろん、これまでどおり、ドラッグアンドドロップでの追加でもできます。

@z7wacg2u さん、本当にありがとうございました!

Geanyエディタのテーマ

テーマをインストール

$ git clone https://github.com/codebrainz/geany-themes
$ mv ./geany-themes/colorschemes ~/.config/geany/
$ rm -r ./geany-themes

テーマの変更

Geanyを起ち上げている場合は、一度閉じて、もう一度起ち上げ直す。

表示 > エディタ > 色の設定

で、テーマを選ぶ。

参照:[Ubuntu 16.04] Geany のテーマ(Color scheme)を変更する。

A5縦書き原稿PDFを、A4用紙・小冊子面付けしたPDFに

※追記した方法のほうが楽。


Pandoc + LaTeX で markdownからA5・縦書・2段組の小説本のPDFを作成」で作ったA5縦書きの原稿データを、A4用紙に2ページ面付けしたPDFファイルを作成する。

pdftk と pdfjam が必要。

$ sudo apt-get install pdftk

pdfjamはtexliveに入っている。インストールはTeX Wiki / Linuxを参考に。

手っ取り早くインストールするには以下の方法で。

sudo apt install texlive texlive-extra-utils

中綴じ用面付表 で、面付けの順番を確認する。

例えば、16ページなら、
1,16,15,2,3,14,13,4,5,12,11,6,7,10,9,8
の順番。

以下、①面付け順に並び替え、②A4用紙に2枚並べる。

$ pdftk 原稿.pdf cat 1 16 15 2 3 14 13 4 5 12 11 6 7 10 9 8 output 原稿001.pdf

$ pdfnup 原稿001.pdf --outfile 原稿完成.pdf --paper a4paper --nup 2x1

できたA4データを両面印刷。とじる辺の設定に気をつける。たぶん、短辺とじ印刷のはず。

追記(さらに修正追記)

中綴じ用の面付けをするスクリプト · GitHub というのを作ってくれている先人がいらっしゃった。

zsh と pdfjam が必要なのでインストール。

$ sudo apt install zsh

pdfjamはtexliveに入っている。インストールはTeX Wiki / Linuxを参考に。

手っ取り早くインストールするには以下の方法で。

$ sudo apt install texlive texlive-extra-utils

中綴じ用の面付けをするスクリプト · GitHub から「Download Zip」をクリックして、「nakatoji.zsh」を取り出す。

(※修正追記)中綴じ用の面付けをするスクリプト · GitHub は横書き=左綴じ用だったので、下記のように縦書き=右綴じ用に修正して(echo -nの中を左右入れ替えただけ)、改めてnakatoji.zshとして保存。

#!/bin/zsh
[ -z $1 ] && exit -1
nakatoji_sequence(){
    last=$(expr 4 \* $1)
    for i in {1..$1} ; do
        #左綴じ
        #echo -n "$(expr $last - $i \* 2 + 2),$(expr $i \* 2 - 1),"
        #echo -n "$(expr $i \* 2),$(expr 1 + $last - $i \* 2),"
        #右綴じ
        echo -n "$(expr $i \* 2 - 1),$(expr $last - $i \* 2 + 2),"
        echo -n "$(expr 1 + $last - $i \* 2),$(expr $i \* 2),"
    done | sed "s/,$//g"
}
file=$(echo $1 | sed "s/\.pdf$//g")
pages=$(pdfinfo $file.pdf | grep Pages | sed "s/^.*: *//g")
pdfjam --outfile /dev/stdout $file.pdf -,{},{},{} 2>/dev/null | \
    pdfjam --nup 2x1 --landscape --outfile ${file}_nakatoji.pdf \
    /dev/stdin $(nakatoji_sequence $(expr \( $pages + 3 \) / 4)) 2>/dev/null

任意のフォルダに nakatoji.zsh と、A5縦書きの原稿PDFデータを入れて、

$ zsh nakatoji.zsh 原稿.pdf

とすれば、面付けされたA4データが作成されているはず。

markdown + reveal.js スライドと同時にレジュメ生成 2018年2月版

概要

注意事項

  • Pandocのバージョンによってはうまく動作しない場合があります。この記事は Pandoc 2.1.1 で動作確認しています。
  • reveal.js は、2018年2月6日時点のもので動作確認。こちらもその後、更新があった場合には、うまく動作しない場合があります。
  • wkhtmltopdf 0.12.4 で動作確認。上記と同じ注意事項。
  • LinuxUbuntu)では動作確認していますが、Windowsの方は動作確認していません。あしからず。

コマンド一発で、markdownからreveal.jsの「htmlスライド」と、そのスライドから配布資料用の「レジュメ」のpdfを生成する方法。

pandocで、markdownからreveal.jsのスライド作成は、まあ、普通。
markdown → (Pandoc + テンプレートを適用) → htmlスライド(reveal.js)

特徴的なのは、レジュメの方。
markdown →(pandoc)→ html + css →(wkhtmltopdf)→ pdf という流れ。

一般的にスライドを配布資料として印刷しようとすると、1枚の用紙にスライドを縮小させたのを4〜6枚程度並べたものになるだろう。しかし、それだと余白がもったいないし、余白がもったいないからと言ってさらにたくさんのスライドを並べたら、文字が小さくなって読みづらい。

そこで配布資料の方は、文書作成ソフトで作ったような、いわゆる「レジュメ」形式で生成できるようにした。

フォルダ内の構成

任意のフォルダ
 ┃
 ┣ reveal.jsフォルダ
 ┃ (reveal.js-master.zipを解凍してできたフォルダをreveal.jsにリネーム)
 ┣ adbird.css  (スライドに適用させるCSS
 ┣ adbird-text.css (レジュメに適用させるCSS
 ┣ makeslide.sh  (Linuxのみ。スクリプトファイル)
 ┣ makeslide.bat  (Windowsのみ。スクリプトファイル)
 ┣ テンプレート.html   (スライドのテンプレート)
 ┣ テスト.md   (スライド・レジュメ原稿ファイル)

下準備 インストール・ダウンロード編

  • Pandocをインストール
    • 「There is a package installer at pandoc’s download page.」のリンク先の下の方にあるインストーラーをダウンロードして、インストール。
  • reveal.jsをダウンロード
    • 「Clone or Download」をクリックして、zipをダウンロード。
    • zipを解凍、フォルダをreveal.jsにリネームして、上記のように、原稿のマークダウンファイルなどと同じ任意のフォルダ内に置く。
  • wkhtmltopdfをインストール

Windowsの場合、パスを通す必要があるかも。

Windowsでプログラムやスクリプトにパスを通す

下準備 設定ファイル編

adbird.css

スライドに適用させるcss

まあ、適当にいじってくださいw。

/*フォント大きさ*/
.reveal p{font-size:28pt;}
div.xxs {font-size: 13pt; }
div.xs {font-size: 15pt; }
div.s {font-size: 20pt; }
div.m{font-size: 25pt; }
div.l{font-size:large}
div.xl{font-size:x-large}
div.xxl{font-size:xx-large}
div.smaller { font-size: smaller }
div.footnote { font-size: smaller; margin-left: 2em; }
div.center { text-align: center }

.reveal h1{font-size:40pt;}
/* .reveal h1{font-size:35pt;} */
section h1.title{font-size:50pt;}
section h2.author{font-size:25pt;}
section h3.date{font-size:25pt;}
.reveal h2{font-size:30pt;}
section.xxs {font-size: 13pt; }
section.xs {font-size: 15pt; }
section.s {font-size: 20pt; }
section.m{font-size: 25pt; }
section.l{font-size:large}
section.xl{font-size:x-large}
section.xxl{font-size:xx-large}
section.smaller { font-size: smaller }
section.footnote { font-size: smaller; margin-left: 2em; }
section.center { text-align: center }

span.xxs {font-size: 13pt; }
span.xs {font-size: 15pt; }
span.s {font-size: 20pt; }
span.m{font-size: 25pt; }
span.l{font-size:large}
span.xl{font-size:x-large}
span.xxl{font-size:xx-large}
span.smaller { font-size: smaller }
span.footnote { font-size: smaller; margin-left: 2em; }
span.center { text-align: center }

.reveal table {font-size: 20pt; }

/*画像キャプションフォント*/
.reveal figcaption {font-size: 13pt; }


/*強調*/
em {
    color:yellow; 
    font-weight:bold;
    font-style:normal;
}

/*強調
em {
    color:#FF9900; 
    font-weight:bold;
    font-style:normal;
}*/

div.build{
margin:10pt;
}

/*リスト*/

.reveal li{font-size:28pt;}

/*定義リスト*/
dt {
    color:red; 
    font-weight:bold;
    font-style:normal;
}

dd{
    line-height:1.3;
}

/*下線 取り消し線*/
.underline{text-decoration:underline;}
.overline {text-decoration:overline}
.cancel {text-decoration:line-through}

/* スライド全体のテキスト位置 */
section {text-align: left;}

/* テキスト右寄せ */
.textright { text-align: right; }  

/* テキスト左寄せ */
.textleft { text-align: left; }  

/*画像センタリング*/
img.center{
    display:block;
    margin:0 auto 100 auto;
}

/*画像回りこみ解除*/
.newpara { clear:left }

/*ブロック・画像回り込み*/
div.floatleft{
    float: left;
}

div.floatright{
    float: right;
}

img.floatleft{
    float: left;
}

img.floatright{
    float: right;
}

/*画像キャプション
.imgcap{
    font-size:xx-small;
    margin:0;
    padding:0;
    line-height:1em;
}*/

/*コード*/
code, tt {
  margin: 0 2px;
  padding: 0 5px;
  white-space: nowrap;
  background-color: #669933;
  border-radius: 3px; }
 
pre code {
  margin: 0;
  padding: 0;
  white-space: pre;
  border: none;
  background: transparent; 
  text-indent: 0em;
}
 
.highlight pre {
  background-color: ;
  border: 1px solid #cccccc;
  font-size: 14px;
  line-height: 19px;
  overflow: auto;
  padding: 6px 10px;
  border-radius: 3px; }
 
pre {
  background-color: ;
  border: 1px solid #cccccc;
  font-size: 14px;
  line-height: 19px;
  overflow: auto;
  padding: 6px 14px;
  border-radius: 3px; }
  pre code, pre tt {
    background-color: transparent;
    border: none; }

/*引用*/
.reveal blockquote {
    text-align: left;
    font-size: 22pt;
width:90%;
    }
.reveal blockquote p{
    line-height:1.5;
}
    
/*スライド時の非表示*/
.SlideNoDisplay {display:none;}

adbird-text.css

レジュメに適用させるcss

これも適当にいじってくださいw。

/*フォント大きさ*/
.xxs {font-size: 7pt; }
.xs {font-size: 8pt; }
.s {font-size: 9pt; }
.m{font-size: 9pt; }
.l{font-size:large}
.xl{font-size:x-large}
.xxl{font-size:xx-large}
.smaller { font-size: smaller }
.footnote { font-size: smaller; margin-left: 2em; }
.center { text-align: center }

.reveal h1{font-size:50pt;}

h1{font-size:10pt}
h2{font-size:10pt}
h3{font-size:10pt}
p{font-size:10pt}

.date{font-size:10pt}

/*強調*/
em {
    color:black; 
    font-weight:bold;
    font-style:normal;
}

div.build{
margin:10pt;
}

/*リスト*/

li{font-size:10pt}

/* 表 */

th{ font-size:10pt;
}

td{ font-size:10pt;
}

/*定義リスト*/
dt {
    color:black; 
    font-weight:bold;
    font-style:normal;
    font-size:10pt;
}

dd{
    line-height:1.3;
    font-size:10pt;
}

/*下線 取り消し線*/
.underline {
    border-bottom:solid 2px black;
}

.overline {text-decoration:overline}
.cancel {text-decoration:line-through}

/* テキスト右寄せ */
.textright { text-align: right; }  

img.big{
max-width: 500px;
  max-height: 500px;
}

/*画像一括サイズリサイズ*/
img{
max-width: 230px;
  max-height: 230px;
}

/*画像センタリング*/
img.center{
    display:block;
    margin:0 auto 0 auto;
}

/*画像回りこみ解除*/
.newpara { clear:left }

/*ブロック・画像回り込み*/
div.floatleft{
    float: left;
}

div.floatright{
    float: right;
}

img.floatleft{
    float: left;
}

img.floatright{
    float: right;
}

/*画像キャプション*/
.imgcap{
    font-size:xx-small;
    margin:0;
    padding:0;
    line-height:1em;
}

/*引用*/
blockquote{font-size: 10pt;}

/*コード*/
code, tt {
  margin: 0 2px;
  padding: 0 5px;
  white-space: nowrap;
  border: 1px solid #eaeaea;
  background-color: #f8f8f8;
  border-radius: 3px; }
 
pre code {
  margin: 0;
  padding: 0;
  white-space: pre;
  border: none;
  background: transparent; 
  text-indent: 0em;
}
 
.highlight pre {
  background-color: #f8f8f8;
  border: 1px solid #cccccc;
  font-size: 14px;
  line-height: 19px;
  overflow: auto;
  padding: 6px 10px;
  border-radius: 3px; }
 
pre {
  background-color: #f8f8f8;
  border: 1px solid #cccccc;
  font-size: 14px;
  line-height: 19px;
  overflow: auto;
  padding: 6px 14px;
  border-radius: 3px; }
  pre code, pre tt {
    background-color: transparent;
    border: none; }

/*レジュメ時の非表示*/
.TextNoDisplay {display:none;}
.author {display:none;}
.date {display:none;}


/*改ページ*/
.pagebreak{
    page-break-before:always;
    padding-top:0em;
    text-align: justify;
    text-justify: inter-ideograph;
}

テンプレート.html

reveal.jsフォルダに入っているindex.htmlを以下のように編集して、「テンプレート.html」として保存。

元々のindex.htmlにあるcssやjsなどのリンク先の頭に「reveal.js/」をつけるのを忘れないように。

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

        <title>reveal.js</title>

        <link rel="stylesheet" href="reveal.js/css/reveal.css">
        <link rel="stylesheet" href="reveal.js/css/theme/black.css">

        <!-- Theme used for syntax highlighting of code -->
        <link rel="stylesheet" href="reveal.js/lib/css/zenburn.css">


        <!-- 自作カスタムcss -->
        <link rel="stylesheet" href="adbird.css">

        <!-- Printing and PDF exports -->
        <script>
            var link = document.createElement( 'link' );
            link.rel = 'stylesheet';
            link.type = 'text/css';
            link.href = window.location.search.match( /print-pdf/gi ) ? 'reveal.js/css/print/pdf.css' : 'reveal.js/css/print/paper.css';
            document.getElementsByTagName( 'head' )[0].appendChild( link );
        </script>
    </head>
    <body>
        <div class="reveal">
            <div class="slides">
<!--    ここをコメントアウト
                <section>Slide 1</section>
                <section>Slide 2</section>              -->

<!-- ここから追加 -->

<section id="title-slide">
  <h1 class="title">$title$</h1>
  <p class="author">$author$</p>
  <p class="date">$date$</p>
</section>

$body$

<!-- ここまで -->

            </div>
        </div>

        <script src="reveal.js/lib/js/head.min.js"></script>
        <script src="reveal.js/js/reveal.js"></script>

        <script>
            // More info about config & dependencies:
            // - https://github.com/hakimel/reveal.js#configuration
            // - https://github.com/hakimel/reveal.js#dependencies
            Reveal.initialize({
                dependencies: [
                    { src: 'reveal.js/plugin/markdown/marked.js' },
                    { src: 'reveal.js/plugin/markdown/markdown.js' },
                    { src: 'reveal.js/plugin/notes/notes.js', async: true },
                    { src: 'reveal.js/plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }
                ]
            });
        </script>
    </body>
</html>

makeslide.sh

Linuxスクリプト。以下のコマンドを並べただけ。

  • pandocで、スライド・レジュメ原稿のマークダウンファイルを、reveal.js用のhtmlスライドに変換。
  • pandocで、スライド・レジュメ原稿のマークダウンファイルを、レジュメ用のhtmlファイルに変換。
  • wkhtmltopdfで、レジュメ用のhtmlファイルを、レジュメpdfファイルに変換。
  • レジュメ用のhtmlファイルを削除。
#!/bin/sh

pandoc -t revealjs --template テンプレート.html $1.md -o $1_スライド.html
pandoc -c adbird-text.css  -s -t html -o $1_レジュメ.html $1.md
wkhtmltopdf --disable-smart-shrinking --margin-top 20 --margin-left 20 --margin-right 20 --margin-bottom 20 --footer-center '[page]/[topage]' $1_レジュメ.html $1_レジュメ.pdf
rm -f $1_レジュメ.html

makeslide.bat

動作確認はしていません。ちゃんと動くとは思いますが…。あしからず。

pandoc -t revealjs --template テンプレート.html -o %~n1.html %~n1.md
pandoc -c adbird-text.css -s -t html -o %~n1text.html %~n1.md
wkhtmltopdf --disable-smart-shrinking --margin-top 20 --margin-left 20 --margin-right 20 --margin-bottom 20 --footer-center '[page]/[topage]' %~n1text.html %~n1text.pdf
del %~n1text.html

スライド・レジュメ原稿を作成する(テスト.md)

% スライドタイトル
% 作成者
% 日付等

# 見出しレベル1(#)について

# 見出しレベル1(#)は横に移動する。

# 見出しレベル1(#)作成時の注意↓

## 見出しレベル1の下には本文を書かない。

```markdown
# 見出しレベル1

こんなふうに見出しレベル1の下に本文を書くと、スライドが正しく生成されない。  
あくまで見出しレベル1は大項目の表紙だと考える。
```

# 見出しレベル2(##)について

## 見出しレベル2(##){.TextNoDisplay}

見出し2は下にスライドが作成されていく。

## 見出しレベル2(##){.TextNoDisplay}

さらに下にスライドを作成。


# PDFレジュメのためのひと工夫 その1<br />見出しや画像を非表示にする

## CSSの設定

adbird-text.css

```
.TextNoDisplay {display:none;}
```

## レジュメ時に見出しを非表示にする

- 別々のスライド。しかし、連続した内容なので、*見出し(レベル2(##))*は*同じ*という場合がある。
- そのままレジュメにすると、同じ見出しが何度も出てきてしまう。
- そこで、`## 見出し2{.TextNoDisplay}`のように、見出しの後ろに`{.TextNoDisplay}`をつける。
- そうすると、adbird-text.css の設定でその見出しは、*レジュメの時だけ見えなくなる*。
- レベル1(#)の見出しの後ろにつけても同様。

## レジュメ時に見出しを非表示にする{.TextNoDisplay}

たとえば、これは上のスライドと見出しは同じだが、本文が違う。   
そこで以下のようにすると、このスライドの見出しはレジュメの時だけ非表示になる。

```
## レジュメ時に見出しを非表示にする{.TextNoDisplay}
```


## レジュメ時に画像を非表示にする

著作権の関係や、紙の節約のためにレジュメに画像は入れたくないと思えば、見出しと同じで画像の後ろに`{.TextNoDisplay}`をつける。

```
![](hoge.jpg){.TextNoDisplay}
```

## スライド1枚丸々を非表示にする{.pagebreak}

スライド1面丸々、レジュメにだけ表示したくない場合は、見出しの後ろに`{.TextNoDisplay}`をつけて、さらに本文もタグで囲めばよい。

```
## 見出し{.TextNoDisplay}

<div class="TextNoDisplay">
スライドの本文
</div>
```

## スライド1枚丸々を非表示にする{.TextNoDisplay}

<div class="TextNoDisplay">
たとえば、このスライドはレジュメのときには表示されない。
</div>

## スライド時に非表示

逆にレジュメには表示されるけれど、スライドのときには表示されないというのもできる。

adbird.css の設定。

`.SlideNoDisplay {display:none;}`

たとえば、

```
この→<span class="SlideNoDisplay">文字</span>←はスライドでは非表示。
```

この→<span class="SlideNoDisplay">文字</span>←はスライドでは非表示。


# PDFレジュメのためのひと工夫 その2<br />任意の場所で改ページ

## CSSの設定

adbird-text.css

```
.pagebreak{
    page-break-before:always;
    padding-top:0em;
    text-align: justify;
    text-justify: inter-ideograph;
}
```

## レジュメ時の改ページ

レジュメ時に、ある見出しのところで改ページを入れたいときは、見出しの後ろに`{.pagebreak}`を入れる。

## この見出しで改ページする{.pagebreak}

```
## この見出しで改ページする{.pagebreak}

```

# 最後のスライドについて

## レベル2(##)の見出しにする

最後のスライドはレベル2(##)の見出しにしないと、ちゃんとスライドが生成されない…。

## おしまい


<!-- 独自記法メモ
レジュメ時に表示しないようにするには、{.TextNoDisplay}
改ページつきの見出しには、{.pagebreak}
-->

コマンド実行

Linux

$ sh makeslide.sh テスト

Windowsエクスプローラーからのコマンドプロンプト起動

$ makeslide.bat テスト

フォルダ内に、「テスト_スライド.html」と「テスト_レジュメ.pdf」ができているはず。

「テスト_スライド.html」をブラウザで開けば、スライドが表示されるはず。

「テスト_レジュメ.pdf」を開けば、以下のようなレジュメができているはず。

レジュメのサンプル画像

f:id:adbird:20171102022749j:plain f:id:adbird:20171102121433j:plain f:id:adbird:20171102022951j:plain

Pandocで画像の幅・高さの比率を維持したまま縮小

Pandocを2.1.1にバージョンアップしてから発生した画像縮小の際のトラブルへの対処方法を教えてもらった。

前提としては、以前書いた「Pandoc で markdown から 論文PDF へ変換」 の記事のように、markdown→Pandocで自作テンプレートtexファイルに $body$ で流しこみ→PDF完成、という手順をとる。

Pandocの以前のバージョンでは

![画像のキャプション](image.jpg){width=5cm}

とすれば、画像の幅が5cmで、高さは自動的に比率を保ったまま、縮小されていた。

しかし、2.1.1(2.0.6からすでにそうだったらしい)に更新して、変換したら、画像の幅は5cmにはなるけど、高さには勝手に textheight がセットされてしまい、縦長に延びた状態の画像になってしまった。

この解決方法をツイッター@myon___ さんに教えていただいた。

自作テンプレートtexファイルのプリアンブルに、以下を貼り付ければ、以前と同様、画像の幅と高さの比率を維持したまま縮小してくれるようになった。

\makeatletter
\def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth\else\Gin@nat@width\fi}
\def\maxheight{\ifdim\Gin@nat@height>\textheight\textheight\else\Gin@nat@height\fi}
\makeatother
% Scale images if necessary, so that they will not overflow the page
% margins by default, and it is still possible to overwrite the defaults
% using explicit options in \includegraphics[width, height, ...]{}
\setkeys{Gin}{width=\maxwidth,height=\maxheight,keepaspectratio}

@myon___さん、本当にありがとうございました。

Geanyエディタのマークダウンプレビュー

プラグインのインストール

Ubuntu16.04の場合、

$ sudo apt-get install geany-plugin-markdown

プラグインをインストール。

ツール>プラグインマネージャ で「Markdownプラグインにチェックを入れて、設定をすればOK。

プレビュー画面を自分好みに設定

デフォルトのままだと見出しのフォントが大きすぎるなど、いまいちなので、

.config/geany/plugins/markdown/

に入っている template.html のcss部分をいじって、自分好みに設定する。

また、プレビュー画面(サイドバー)と編集画面を左右を入れ替えるには、

編集>設定>インターフェイス>サイドバー の、「位置」で左右好きな方に設定すればよい。

template.html の例

ちなみに現在の僕の template.html は以下のような感じ。

<html>
<head>
    <style type="text/css">
        body{
        background-color: @@bg_color@@;
        color: @@fg_color@@;
        }

    h1::before {
        content: counter(chapter) ".";}

        h1{font-family: @@font_name@@;
        font-size: @@font_point_size@@pt;
        font-weight:bold;
        line-height:1.5;
        text-align: justify;
        counter-increment: chapter;
        counter-reset:section;
        }

        h2{font-family: @@font_name@@;
        font-size: @@font_point_size@@pt;
        font-weight:bold;
        }

        p{font-family: @@font_name@@;
        font-size: @@font_point_size@@pt;
        line-height:1.5;
        }

        code {
        font-family: @@code_font_name@@;
        font-size: @@code_font_point_size@@pt;
        }

        /*リスト*/
        ul{list-style-type:circle;}

        /*数字リストをカタカナに*/
        ol {
        list-style-type: katakana;
        }

        li{font-family: @@font_name@@;
        font-size: @@font_point_size@@pt;
        line-height:1.5;}

        /*強調*/
        em {
        font-weight:bold;
        font-style:normal;
        }

    </style>
</head>
<body>
    @@markdown@@
</body>
</html>

章番号をつけないmarkdown記法

たぶん、pandoc-markdown拡張記法。

「はじめに」や「おわりに」、「参考文献」など、特定の章だけに通し番号をつけたくない場合は、見出しの末尾に {-}をつける。

参考リンク:まだ Word で消耗してるの? 大学のレポートを Markdown で書こう