TeX にSVGを貼る方法(2019年版)

TeXsvgを貼る場合は一度 inkscape でファイルを変換する必要があります.

詳しい手順は過去記事をごらんください.TeX に svg を貼る方法 - pyopyopyo - Linuxとかプログラミングの覚え書き -

svgパッケージを使うと,これを自動化できます

\usepackage{svg}
\includesvg{svgファイル名}

svgファイルのサイズを自動調整したい場合は

\def\svgwidth{\textwidth}
\includesvg{svgファイル名}

という感じで svgwidth を調整します


注意事項


コンパイルすると svg-inkscape というディレクトリが自動生成されます.inkscapeで変換したファイルが保存されます.これらのファイルはキャッシュとして利用され,キャッシュが利用できる場合は inkscape の起動は省略されます.

複数の静的ライブラリを結合する方法 (2019年版)

2つの static library, libX.a と libY.a を結合して libAll.a を生成する方法です

この記事は 複数の静的ライブラリ (.a) を結合する方法 - pyopyopyo - Linuxとかプログラミングの覚え書き - の改訂版です

Linux の場合 (方法1)

ar scripts を使います.
ar scripts (GNU Binary Utilities)

具体的にはarコマンドに "-M" オプションを付与して起動します.

$ ar -M

すると標準入力からスクリプトを受け付けるので,libAll.a を生成して libX.a と libY.a を追加するスクリプトを入力します

create libAll.a
addlib libX.a
addlib libY.a
save

これを Makefile で自動実行するには次のようなルールを書きます

libAll.a : libX.a libY.a
        @echo "create $@\n" $(addprefix addlib , $(addsuffix \\n, $^)) "save" | ar -M
動作原理

  • create $@ は create libAll.a に置換されます
  • $^ は "libX.a libY.a" のリストに置換されます
  • $(addsuffix \\n, $^)で "libX.a\n libY.a\n"に置換されます
  • $(addprefix addlib , "libX.a\n libY.a\n") は "addlib libX.a\n addlib libY.a\n"に置換されます

まとめると

echo "create libAll.a \n " "addlib libX.a\n  addlib libY.a\n" "save" 

をまず実行して ar script を stdoutに出力,パイプ経由で ar -M のstdin に渡すことになります


Linux の場合 (方法2)

少し違う Makefile の書き方もあります

libZ.a: libX.a libY.a
        $(RM) $@
	$(AR) cqT $@ $^
	echo "create $@\naddlib $@\nsave\nend" | ar -M
動作原理

仕組みとしては

$ ar cqT libZ.a libX.a libY.a

で,まず一時的なライブラリとして libZ.a を生成します

この libZ.a は thin archive 形式で作成されていて

  • シンボルテーブル
  • 元ファイルのパス名

のみを保持していて,データやコードの実体は含んでいません

次に thin archive 形式のライブラリを ar scriptで変換します.

create libZ.a
addlib libZ.a
save
end

これで新しい libZ.a を作成し,データやコードも含んだ スタティックライブラリを出力します

mac OS の場合

mac OS の場合は /usr/bin/libtool を使うと簡単に結合できます

$ /usr/bin/libtool -o libZ.a   libX.a libY.a

なおこの方法は Linux では使えません.Linux の /usr/bin/libtool は GNU版で,mac OS のそれとは動作が異なるためです.

svnからgitへの移行方法

久しぶりにSubversionリポジトリをgitに移行したので手順をまとめておきます

subversion側の状況を確認する

SVNでcheckout済みの作業ディレクトリにて,svn リポジトリのURLやパスを確認します

$ cd SVNの作業
$ svn info
  • URL: svn+ssh:///サーバ名/hogehoge/src/trunk
  • Relative URL: ^/src/trunk

SVNリポジトリは サーバ上の hogehogeディレクトリにあり,
SVNリポジトリの直下には src というディレクトリ,その下に trunkというディレクトリがあることがわかります

src ディレクトリの中身を確認します

$ svn list ^/src/
branches/
tags/
trunk/

trunk, branches, tags というディレクトリがあります.つまりこのリポジトリSVNの標準的な構成になっています.

このような標準的な構成のSVNリポジトリは以下の手順で簡単にgitに移行できます.

また変則的な構成の場合でも,以下の手順を参考に git svnのhelpを読みながらオプションを大量に指定すればgitに移行できます

git側の準備

git のサブコマンド git-svn を使います.インストールされてない環境も多いので,予め確認&追加インストールしておきます.

まず試しに起動してみます.インストール済みならヘルプが表示されます.

未インストールの場合は 以下のようなエラーメッセージが出ます

$ git svn 
git: 'svn' is not a git command. See 'git --help'.

この場合は追加インストールします.debian とか ubuntu なら

$ sudo apt install git-svn

でOK

SVNからgitへの変換

$ git svn clone --stdlayout  --prefix=svn/ [svn-repo] [git-dir]

[svn-repo]は,上記の svn infoで調べたURLです.
上記の例に従えば svn+ssh:///サーバ名/hogehoge/src/ になります

オプションの意味は以下の通りです

  • [svn-repo]は tagsやtrunkがある標準構成になっているので --stdlayout をつける
  • svn由来のブランチで有ることを示すため "--prefix=svn/" をつけます.これで git の remote-tracking ref が refs/remotes/svn/ となります.

[git-dir]は出力先ディレクトリ名です. ここに作業デレクトリが作成されます

確認

ログやブランチの状況を確認します

$ git log
$ git branch -a

jupyter notebook が起動しない時の対処方法

jupyter notebook が以下のエラーを出して起動しない場合の対処法

  File "*********/.local/lib/python3.7/site-packages/tornado/netutil.py", line 174, in bind_sockets
    sock.bind(sockaddr)
OSError: [Errno 99] Cannot assign requested address

暫定的に回避する方法

とりあえず以下のようにオプションをつければ起動する

jupyter-notebook --ip='127.0.0.1' 

根本的に解決する方法


このエラーは "localhost" のIPアドレスを正しく検出できない時に発生する.

その原因は,多くの場合 /etc/hosts の記述ミス.

具体例を挙げると,例えば以下の/etc/hostsでこのエラーが再現する

ダメな/etc/hostsの例(その1)

127.0.0.0.1       localhost 

これはIPアドレスが間違っている.127.0.0.1 に修正すれば jupyter notebook は起動するようになる

ダメな/etc/hostsの例(その2)

127.0.0.1       localhost 
::1             localhost 

これはIPv6の方のエントリを消せば良い

Debianが起動しない場合の復旧方法 (Bug#932935)

2019年7月28日に Debianが起動しなくなりました.原因は sid(unstable)と呼ばれる開発版のみに存在するバグです.

バグレポートも出ています.症状としては,システムを再起動すると" logsave not found - requires manual a fsck "と表示されるだけでシステムが起動しなくなる,という恐ろしいものになります.

Debian Bug report logs - #932935 System refuses to boot, logsave not found - requires manual a fsck
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=932935

このバグはすでに修正されています.しかし不幸にも debianが起動しなくなった場合の対処方法として,復旧手順をメモしておきます.

復旧手順の概要

パッケージのバグが原因でブートしない場合は,バグ修正版のパッケージでアップグレード(つまり上書きインストール)すれば復旧できます.

その手順は

  1. 無理やり手動でシステムを起動
  2. IPアドレスを手動設定
  3. 無理やり apt update して apt install

となります

この手順は,知っておくと結構役に立つので,以下詳しく手順を説明します*1

手順1: 状況の確認

Linuxの起動に失敗すると,次のような画面が表示されます.

Busybox バージョン情報
Enter 'help' for a list of built-in commands.

(initramfs)

この画面では,ディスクのエラーチェックだとか,設定ファイルの修正,などが行えます.今回は手動で無理やりシステムを起動させます.

手順2: IPアドレスの付与

まず余っているIPアドレスを手動設定します

(initramfs) ifconfig eth0  IPアドレス

次にデフォルトゲートウェイを手動設定します

(initramfs) route add default gw ルーターのIPアドレス

手順3: システムの root (/) のマウント

まずマウントポイントを作成します./tmp 以下に作るのが無難だと思います.

(intiramfs) mkdir /tmp/root

ディスクをマウントします.カーネルモジュールを手動でロードする必要があります.例えば ext4 でフォーマットしている場合は,次のようなコマンドを実行します.

(intiramfs) modprobe ext4
(initramfs) mount -t ext4 /dev/デバイス  /tmp/root

これでマウントできるはずです.確認は df コマンドを使います

(initramfs) df

手順4: システムの起動

chroot でディスク上のシステムに切り替えます.

(initramfs) chroot /tmp/root 

本来なら /proc や /dev などをマウントしてから chroot すべきですが,今回は緊急事態なので,細かいことは省略します.

いくつか警告が出ますがそれも無視

手順5: 確認

これで bashに切り替わるはずです.apt コマンドが起動できるか確認します.

$ apt 

問題なければ apt update します

$ apt  update

ネットワークの設定が合っていれば,update が始まるはずです.これでバグ修正済みのパッケージ情報がgetできます

手順6: バグ修正版パッケージの上書きインストール

上記bugレポートに纏められているように,今回システムが起動しなくなった原因は e2fsprogs というパッケージのバグにあります.すでにバグは修正済みなので,修正済みのe2fsprogs を apt で上書きインストールします

$ apt install e2fsprogs 

これで作業は終わりです.再起動すればシステムは元どおり正常起動するようになります.

手順7: それでも復旧できない場合

バグの原因が特定できない場合は,とりあえず更新済みパッケージを全部インストールする,つまり

$ apt upgrade

するという方法もあります.

ただし,/dev や /procを準備してない状態で apt upgrade をすると想定外の事故が起こる可能性もあります.個人的には apt upgrade は最後の手段にとっておいたほうが良いとおもいます.

*1:ブートローダーであるgrub2 ,initramfsの中にあるシェル busybox が壊れていない限りはまずこの方法でシステムは復元できます

macOS に Tex Live 2019をインストールする

macOS mojave の TeX環境を texlive2019 に更新したので手順をまとめます.

この記事は以下のエントリを macOS mojaveと Tex Live 2019 に合わせて更新・加筆したものです.

BasicTeX

パッケージはMacTeXのサブセット版である BasicTeX を使いました.

MacTeXは全パッケージをインストールします.そのため 2.4GB ものディスク容量を消費します (Tex live 2014の場合).

一方サブセット版である BasicTeX は最低限のパッケージしかインストールしません.必要な容量は 248MB程度です.不足パッケージは後から簡単にインストールできるので実用上の問題もありません

ダウンロード&インストール

https://tug.org/mactex/morepackages.html から mactex-basic.pkg をダウンロード,インストールします

なおMacTeXは

  • 2019 通常版 /usr/local/texlive/2019
  • 2019 BasicTeX /usr/local/texlive/2019basic
  • 2018 BasicTeX /usr/local/texlive/2018basic

という感じでディレクトリを分けてファイルを配置します

デフォルトのTeX環境の選択は,"TeX Distribution"というアプリで行います.
(メニューの”システム環境設定"にアイコンがあります.Spotlight検索で TeX Distribution でも起動できます)
このアプリは

  • /Library/TeX/texbin
  • /Library/TeX/Root
  • /Library/TeX/Local
  • /Library/TeX/Documentation

というシンボリックリンクを管理していて,これらリンクでデフォルトのtex環境を選択する仕組みになっています.

たとえば mactex-basic.pkg をインストールすると,/Library/TeX/texbin のリンク先は

$ readlink -f  /Library/TeX/texbin
/usr/local/texlive/2019basic/bin/x86_64-darwin

という感じで,/usr/local/texlive/2019basic/bin/x86_64-darwin になります

初期設定

basictex をインストールしたら,必要なパッケージを追加インストールします

方法は二つ

  • Tex Live ユーティリティーというGUIを使う方法
  • CUIでtlmgrコマンドを使う方法

あります.

ここでは,説明が簡単,という理由でCUIを使います.

まずターミナルを起動します.そして以下のコマンドを実行します.これで tlmgr 自身を更新します

$ sudo tlmgr update --self 

次にインストール済みパッケージの更新

$ sudo tlmgr update  --all

最後に,個人的に良く使うパッケージを追加インストールします.

$ sudo tlmgr install  type1cm subfigure dvipdfmx multirow xstring logreq biblatex latexmk  biber 

日本語環境の設定

Tex live 2018同様の方法で日本語の設定を行います.

TLContirb リポジトリの追加登録

ライセンスの関係で Tex live 2018 でパッケージ構成に変更がありました.

macOS 同梱のフォントを使うためのパッケージ達は別リポジトリ( TLContrib )へ分離されたので,
まずはこのリポジトリを登録します.

$ sudo tlmgr repository add http://contrib.texlive.info/current tlcontrib
$ sudo  tlmgr pinning add tlcontrib '*'


フォント周りで重要なパッケージは

  • cjk-gs-integrate-macos (cjk-gs-integrateのmacOS版,フォントの設定を行うスクリプトです)
  • japanese-otf-nonfree japanese-otf-uptex-nonfree ptex-fontmaps-macos

です

リポジトリの登録が済んだら,日本語関連のパッケージをまとめてインストールします

$ sudo tlmgr  install japanese-otf-nonfree japanese-otf-uptex-nonfree  ptex-fontmaps-macos cjk-gs-integrate-macos ptex platex jsclasses japanese-otf cjk-gs-integrate adobemapping ptex-fontmaps
フォントの登録

cjk-gs-integrate-macos というスクリプト(cjk-gs-integrate のmac os 版)がインストールされるので,これを使って mac OS のフォントを登録します

$ sudo cjk-gs-integrate --link-texmf --cleanup
$ sudo cjk-gs-integrate-macos --link-texmf --force
$ sudo mktexlsr
登録ずみフォントの確認

フォントの設定用に kanji-config-updmap-sys というスクリプトがインストールされます.

このスクリプトで現在の設定を確認します.

$ sudo kanji-config-updmap-sys status

以下の出力が得られます

CURRENT family for ja: ipaex
Standby family : hiragino-highsierra
Standby family : hiragino-highsierra-pron
Standby family : ipa
Standby family : kozuka
Standby family : ms
Standby family : yu-win

先頭行は現在の設定で,日本語フォントは埋め込まない,という意味です
残りは利用可能なフォントの一覧です

フォントの変更

フォントが登録できたら,pdfに埋め込むフォントを指定します

$ sudo kanji-config-updmap-sys --jis2004 hiragino-highsierra-pron

自動で extractbb が実行されるようにする

以下の内容で /usr/local/texlive/texmf-local/web2c/texmf.cnf を用意します

shell_escape_commands = \
bibtex,bibtex8,bibtexu,upbibtex,biber,\
kpsewhich,\
makeindex,mendex,texindy,xindy,\
mpost,upmpost,\
repstopdf,epspdf,extractbb

古い TeX環境の削除

uninstallは簡単です

MacTex 2018 を消したい場合は /usr/local/texlive/2018basic をディレクトリ毎削除するだけです

$ sudo rm -rf /usr/local/texlive/2017basic

トラブルシューティング

pdfに画像が貼れない/gsコマンドが無い
ghostscript (gsコマンド) がインストールされていないと dvipdfmx 経由で作成する pdf に画像が貼れない場合があります.ghostscript をインストールするには https://tug.org/mactex/morepackages.html の mactex-additions.pkg から ghostscriptを選択してインストールするのが楽そうです.
LaTeX It を使いたい
gsコマンドが必要なので,あらかじめ上記の手順でghostscriptをインストールして http://www.chachatelier.fr/latexit/ からdmgをダウンロード,インストールする.
TeX Live Utility.app を使いたい
https://code.google.com/p/mactlmgr/
dvipdfmx がCould not find encoding file “H”. というエラーを出す
adobemapping パッケージをインストールすると直ります
日本語フォントが使えなくなった
Tex live 2018 でフォント周り(パッケージ構成やコマンド名)に少し変更が入っているようです.上記手順を参考にフォント周りの設定を見直してください

まとめ

インストール後の /usr/local/texlive/2019basicのサイズは 586MBでした

参考までに

  • /usr/local/texlive/2018basicのサイズは 546MB
  • /usr/local/texlive/2018basicのサイズは 766MB

でした.

Tex live 2014は全部インストールすると 2.4GB程度なので,それに比べるとかなりディスク容量を節約できたようです.






[改訂第7版]LaTeX2ε美文書作成入門
奥村 晴彦 黒木 裕介
技術評論社
売り上げランキング: 4,008


学生・研究者・技術者のためのLATEXを用いた論文作成術
渡辺 徹
プレアデス出版
売り上げランキング: 233,232

迷惑メール対策に負けない,exim4 の正しい設定方法

ラズパイやPC Linuxで構築したサーバ機では, ログの監視結果などをメール送信できると格段に使い勝手が向上します.

しかし今のインターネットは迷惑メール対策がしっかりしています.例えば

  • プロバイダのOutbound Port 25 Blocking
  • SPFによる送信ドメイン認証(SPF

などの迷惑メール対策があり,これらの対策を突破しないとメールは相手に届きません.

迷惑メール対策に負けない Linux の設定

と言うわけで,これら迷惑メール対策に負けない設定として, exim4を使う方法を説明します.

ポイントは三つあります.

  1. exim4を使います
    • 軽量です
    • ラズパイのような組み込みシステム,利用形態で問題なく利用できます.
  2. 外部のメールサーバ(SMTPサーバー)経由で送信します
    • 外部のSMTPサーバーとして,以下のサーバーを使ってメールを送信します.
    • SPF対策済みのSMTPサーバーを使用するので,メールがSPAMと誤判定されにくくなります.
  3. SSL使います
    • SMTP authを使うので,SSLでユーザ名,パスワードを保護します.

exim4の基本設定

基本的な設定は dpkg-reconfigure で行うのが楽です.

$ sudo dpkg-reconfigure exim4-config

慣れている人は /etc/exim4/update-exim4.conf.conf を直接編集してもOKです.


設定で大事なのは smarthost の設定です.smarthost で中継先のSMTPサーバを指定します.書式は

SMTPサーバ名::ポート番号

です.区切りは":"ではなくて "::" とコロンを2回連続で書くことに注意してください.

googleSMTPを使うなら

smarthost = "smtp.gmail.com::465"

となります

SMTP-authのパスワード設定

/etc/exim4/passwd.client にパスワードを記入します

*:アカウント名:パスワード

"*"の部分はSMTPサーバーの名前です.今回の設定方法では,SMTPサーバーは一つしか設定しないので,"*"と書いておきましょう.

パスワードは平文で記入します.

心配な人は /etc/exim4/passwd.client のパーミッションを確認しましょう.デフォルトでroot以外はファイルの中身を閲覧できないようなっているはずです(一般ユーザでpasswd.clientの中身が読めたらセキュリティホールです.開発者にバグレポートを出しましょう)

exim4の設定ファイルの更新

/etc/exim4/exim4.conf.localmacros の末尾に以下の行を追加します

    MAIN_TLS_ENABLE = 1 
    REMOTE_SMTP_SMARTHOST_HOSTS_REQUIRE_TLS = *
        TLS_ON_CONNECT_PORTS = 465 
    REQUIRE_PROTOCOL = smtps 

続けて /etc/exim4/exim4.conf.template の .ifdef REMOTE_SMTP_SMARTHOST_HOSTS_REQUIRE_TLS ... .endif の部分に以下の行を追加します

    .ifdef REQUIRE_PROTOCOL
        protocol = REQUIRE_PROTOCOL 
    .endif 

さらに下記3行を /etc/exim4/exim4.conf.template の .ifdef MAIN_TLS_ENABLE の次の行に追加します.

    .ifdef TLS_ON_CONNECT_PORTS
        tls_on_connect_ports = TLS_ON_CONNECT_PORTS 
    .endif 

設定の反映と exim4 の再起動

$ sudo  /usr/sbin/update-exim4.conf
$ sudo  /etc/init.d/exim4 restart

動作確認

配信経路確認

/usr/sbin/exim4 を使うと,メールの配信経路を確認できます.

$ /usr/sbin/exim4 -bt  hogehoge@example.com
R: smarthost for hogehoge@example.com
hogehoge@example.com
  router = smarthost, transport = remote_smtp_smarthost
  host 外部SMTPサーバ名 [IPアドレス] port=465
  • smarthostの設定で,外部SMTPサーバーに中継されていること
  • 465ポートに送信していること

が確認できます

送信テスト

mailコマンドでメールを送信してみましょう

$ echo "hogehoge" | mail -s test   hogehoge@example.com

トラブルシューティング

ログ

エラーなどはすべてログファイルに出力されます.うまく行くときも,うまく行かないときも,ログファイルを見るのが基本です.

$ sudo tail -f /var/log/exim4/maillog
メールキューを全削除
$ sudo -s
 exim -bp | exiqgrep -i | xargs exim -Mrm