Doxygenの設定メモ
今までpdf出力は文字化けがするので諦めていた。 以下のサイトを参考に色々と試したら、文字化けが治ったしフォントも綺麗になった。
残念ながら、今はもう紙の関数仕様書を要求する仕事は無いし、おそらくこれからも無いので単純に趣味の世界です。
で、作業メモ。
環境
環境は、macPortsで構築した。
- macosx 10.12.4
- xcode 8.3.1
- MacPorts 2.4.1
- TeX Live 2016/MacPorts 2016_4
- doxygen 1.8.13
構築したと言っても以下の1行を入力しただけ。
$ sudo port install texlive +full
Doxyfileファイルの設定
最低限、以下の3項目を変更すれば良い。
OUTPUT_LANGUAGE = English
LATEX_CMD_NAME = latex
USE_PDFLATEX = YES
これらの項目を以下のように変える。
OUTPUT_LANGUAGE = Japanese
LATEX_CMD_NAME = uplatex
USE_PDFLATEX = NO
それぞれの意味は、参考にしたサイトに載っているので特にここでは書かない。
ソースコードの位置や出力ファイルの位置も各自に合わせること。
最初の出力
一度、doxygenコマンドを実行して、latexディレクトリを生成する。
生成されたmakeファイルを実行すると文字化けのするpsファイルやpdfファイルしか作成できない。
その壊れたlatexディレクトリ中のmakeファイルを修正する。
修正箇所は3箇所。
1. pdfの生成にはdvipdfmxを使う
PostScriptファイルから生成している箇所をdvipdfmxから生成するように変更するだけです。
以下の箇所を変更します。
refman.pdf: refman.ps
ps2pdf refman.ps refman.pdf
変更後は以下のようになります。
refman.pdf: refman.dvi
dvipdfmx refman.dvi
2. pdfの複数のページを1ページにまとめるにはpdfnupを使う
ps2pdfはうまく日本語が通らないようなので、pdfnupを使います。
以下の箇所を変更します。
refman_2on1.pdf: refman_2on1.ps
ps2pdf refman_2on1.ps refman_2on1.pdf
変更後は以下のようになります。
refman_2on1.pdf: refman.pdf
pdfnup refman.pdf
mv refman-nup.pdf refman_2on1.pdf
3. 複数のpdfをまとめたファイルの後片付けをする
おそらく、doxygenの記載漏れ。clean時にrefman_2on1.pdfも含めるだけ。
以下の箇所を変更します。
clean:
rm -f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl refman.pdf
変更後は以下のようになります。
clean:
rm -f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl refman.pdf refman_2on1.pdf
pdfに目次を作る
ここまでの変更を行うとpdfの文字化けは治ります。ここから先は、大抵の人には関係ありません。
印刷時の目次はあります。ここで作る目次は、pdfのbookmarkと呼ばれる機能です。
リンクの色は黒。bookmarkはdvipdfmxに対応させる。
% Hyperlinks (required, but should be loaded last)
\usepackage{ifpdf}
\ifpdf
\usepackage[pdftex,pagebackref=true]{hyperref}
\else
\usepackage[ps2pdf,pagebackref=true]{hyperref}
\fi
\hypersetup{%
colorlinks=true,%
linkcolor=blue,%
citecolor=blue,%
unicode%
}
上記のコードを以下に置き換え。
% Hyperlinks (required, but should be loaded last)
% hyperrefをdvipdffmx用に決め打ち
\usepackage[dvipdfmx,
pagebackref=true,
colorlinks=true,
linkcolor=darkgray,
urlcolor=darkgray,
bookmarks
]{hyperref}
\usepackage{pxjahyper} % 日本語で'しおり'したい
これで、目次も出来て、リンクも作成された。
見た目を整える
完全に趣味です。
本文を明朝体にして、章立てやラベルはゴシック体に変更する。
% Custom commandsの末尾にでも以下のコードを追加する。
\usepackage[uplatex,deluxe, expert]{otf}
% sectionの書体を"ゴシック体、サンセリフ体、太字"
\allsectionsfont{
\gtfamily\sffamily
\color{darkgray}
}
% labelの書体を"ゴシック体、サンセリフ体、太字"
\renewcommand{\DoxyLabelFont}{
\gtfamily\sffamily
\color{darkgray}
}
\renewcommand{\kanjifamilydefault}{\mcdefault} % 日本語書体を明朝体
\renewcommand{\familydefault}{\rmdefault} % 欧文書体をローマン体
また、細すぎるので表紙のタイトルはゴシック体のボールドにする。begin{titlepage}の次の行に追加。
\begin{titlepage}
\gtfamily\sffamily\bfseries % <-- これを追加
ヒラギノフォントを使っているかも
macPorts の場合以下のコマンドでヒラギノを有効にした記憶があるが定かでは無い。
$ cd /opt/local/share/texmf-texlive/scripts/cjk-gs-integrate
$ sudo perl cjk-gs-integrate.pl --link-texmf --force
$ sudo mktexlsr
$ sudo kanji-config-updmap-sys hiragino-elcapitan-pron
以下のコマンドではヒラギノが埋め込まれているように見える。
$ pdffonts refman.pdf
参考URL
- DoxygenのLaTeX出力で日本語を使う(2015年版) http://dev.activebasic.com/egtra/2015/06/29/814/
次は、上記のサイトのように、スクリプトで自動化したい。
Cocoaからのライブ変換(LiveConversion)の変更と監視
今の所、専用のAPIは見つかっていない。設定ファイルやDistributedNotificationの監視で見つかった事を書く。
- 変更の監視
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
[[NSDistributedNotificationCenter defaultCenter]
addObserver:self
selector:@selector(jimPreferencesDidChangeNotification:)
name:@"com.apple.inputmethod.JIM.PreferencesDidChangeNotification"
object:nil
suspensionBehavior:0];
}
- (void) jimPreferencesDidChangeNotification:(NSNotification*)note
{
NSLog(@"jimPreferencesDidChangeNotification => %@",
[note.userInfo valueForKey:@"JIMPrefLiveConversionKey"]);
}
- 現在の設定の確認
NSUserDefaults* theUD = [[NSUserDefaults alloc] initWithSuiteName:@"com.apple.inputmethod.Kotoeri"];
NSLog(@"[theUD valueForKey:JIMPrefLiveConversionKey] => %@",
[theUD valueForKey:@"JIMPrefLiveConversionKey"]);
Warning
ImputMethodのprefarenceを参照しているだけなので、sandbox環境では正常に動作しない。
- ライブ変換を有効/無効にする
有効
[[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"com.apple.inputmethod.JIM.PreferencesDidChangeNotification"
object:@"com.apple.JIMSession"
userInfo:/*@{@"JIMPrefLiveConversionKey" : @(1)}*/ // <--コメントアウトを外して使用すること
options:0];
[[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"com.apple.inputmethod.JIM.PreferencesDidChangeNotification"
object:@"com.apple.JIMPreferences"
userInfo:/*@{@"JIMPrefLiveConversionKey" : @(1)}*/ // <--コメントアウトを外して使用すること
options:0];
無効
[[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"com.apple.inputmethod.JIM.PreferencesDidChangeNotification"
object:@"com.apple.JIMSession"
userInfo:/*@{@"JIMPrefLiveConversionKey" : @(0)}*/ // <--コメントアウトを外して使用すること
options:0];
[[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"com.apple.inputmethod.JIM.PreferencesDidChangeNotification"
object:@"com.apple.JIMPreferences"
userInfo:/*@{@"JIMPrefLiveConversionKey" : @(0)}*/ // <--コメントアウトを外して使用すること
options:0];
Warning
sandbox環境では、NSDistributedNotificationはuserInfoにデータを渡すことはできない。sandbox環境では動作しない。
以上のコードでライブ変換の監視/変更が出来るが、sandbox環境では正常動作しない。 sandbox環境で動作するのは変更したタイミングの取得だけ。
“HIToolbox/TextInputSources.h”にあるInputSourceの変更が正規のAPIの可能性があると思い、TISCreateInputSourceListで取得できるリストを見たがそれらしきものはなかった。
最小限アウトラインプロセッサの作り方
Cocoa勉強会松戸用の資料。
NSOutlineViewとNSTreeControllerを使って、”Copy&Paste”,”書類の保存と読み込み”,”Drag&Drop”の実装までの最小限アウトラインプロセッサの作り方の資料です。
なお、ソースコードとPDFはここです。
( TreeOutliner_01.zip ) ( 最小限アウトラインプロセッサの作り方.zip )
解説は当日に行います。
pragma markによるメソッドの分類
この記事は、pragma markを最初にコピペする事でクラス実装の抜けや漏れを防ぐ方法の紹介です。
コメントと同じく機械側には無くても良いが、プログラマ側に実装すべきメソッドを思い出しやすくします。
最初にpragma mark のリストをコピペする
クラスを作成すると、.hと.mに以下のコードをコピペします。
#pragma mark - class methods
#pragma mark - init methods
#pragma mark - dealloc
#pragma mark - NSCopying, hash, isEqual:
#pragma mark - NSCoding methods
#pragma mark - restorableState methods
#pragma mark - life cycle methods
#pragma mark - action methods
#pragma mark - event handling methods
#pragma mark - drawing methods
#pragma mark - delegate/datasource methods
#pragma mark - accessor methods (in pairs)
#pragma mark - Utility methods
あとは、メソッドを書いてゆくだけです。
メリットは、以下の2点です。
- 次に書くべきメソッドを思い出しやすい。
人間は穴埋め問題の様に場所が決まっていると、何をすれば良いかが思い出しやすい。
- コードのブラウズ時に検索や移動がやりやすい。
メソッドの分類毎に、”mark -“の文字列があるので、”⌘F mark -“と”⌘G”で分類の間を移動できる。
Note
今まで私は”ハイフン”行と”分類名”行で2行に分けて記述していました。 しかし、先ほど試した結果1行でも問題なくXCodeが動作しました。 ですので、今後は1行で記述するつもりです。
次は、それぞれの分類に何を書いているかの説明です。
pragma mark - class methods
クラスメソッドを書く場所。
[NSDocument autosavesInPlace]などのクラス特有の性質を示すメソッドやインスタントイニシャライザを書く。
例:
+ (BOOL) autosavesInPlace;
+ (NSURL*) fileURLWithPath:(NSString*) path;
pragma mark - init methods
イニシャライザを書く場所。
引数が少ないメソッドを上の方に、引数の多いメソッドをしたの方に書く様に気をつける事。
書くときはすこし手間が増えるが、コードを読むときに流れが上から下になるので分かりやすくなる。
Objective-Cのイニシャライザでは最も引数の多いメソッドが、指定イニシャライザ になるので、必然的に上記の様になる。
例:
- (instancetype) init;
- (instancetype) initFileURLWithPath:(NSString *)path;
pragma mark - dealloc
deallocを書く場所。
各種プロパティをnilに戻す事や、KVOの停止、Notificationの受信の停止など。
例:
- (void) dealloc;
pragma mark - NSCopying, hash, isEqual:
オブジェクトのコピーや同一性に関わるメソッドの実装を書く場所。
MVCで言うところのViewクラスやControllerクラスでは必要ありませんが、逆にmodelクラスに相当するクラスの場合は実装はほぼ必須です。
例:
- (id) copyWithZone:(NSZone *)zone;
- (id) mutableCopyWithZone:(NSZone *)zone;
- (BOOL) isEqual:(id)object;
- (NSUInteger) hash;
pragma mark - NSCoding methods
シリアライズ化メソッドを書く場所。
Cut&PasteやDrag&Drop、ファイル保存の実装にはNSCodingのメソッドを使うと簡単になる。
例:
- (void)encodeWithCoder:(NSCoder *)aCoder;
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder;
pragma mark - restorableState methods
状態保存関係のコードを書く場所。
クラスメソッドであるが[NSResponder (NSRestorableState) restorableStateKeyPaths]もここに書く。
例:
+ (NSArray *)restorableStateKeyPaths;
- (void) encodeRestorableStateWithCoder:(NSCoder *)coder;
- (void) restoreStateWithCoder:(NSCoder *)coder;
pragma mark - life cycle methods
オブジェクトのライフサイクルのコードを書く場所。
ViewControllerやWindowControllerのライフサイクルに関するメソッドを書きます。 場合によっては、delegateやnotificationに分類される様なメソッドも書きます。
例:
- (void)awakeFromNib;
// windowControllerの場合
- (void)windowWillLoad;
- (void)windowDidLoad;
// ViewControllerの場合
- (void)viewDidLoad;
- (void)viewWillAppear;
- (void)viewDidAppear;
- (void)viewWillDisappear;
- (void)viewDidDisappear;
// NSApplicationDelegateの場合
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification;
- (void)applicationWillTerminate:(NSNotification *)aNotification;
pragma mark - action methods
IBActionのメソッドを書く場所。
ユーザーが実行できるコマンドの単位になる、IBAction系のメソッドを書く。
また、enable/disableを制御するためのcanAction系のメソッドも一緒に書いておくと楽。 ライブラリcontrolEnablerを使用すると良い。 validateuserinterfaceitem(7)
例:
- (IBAction) anAction:(id)sender; // action
- (BOOL) canAnAction:(id)sender; // actionを呼出すボタンの有効無効を制御
pragma mark - event handling methods
イベント処理のメソッドをこの場所に書く。
NSResponderのサブクラスでない場合でも、KVOの監視メソッドや、Notificationの受信メソッドをイベント処理と考えて、この場所に書いておくと楽。
例:
// KVOの監視メソッド
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context;
// なんらかのnotificationのレシーバー
- (void) nanikanoNotificationNoReciver:(NSNotification *)aNotification;
// キーダウンイベントを処理したり
- (void)keyDown:(NSEvent *)event;
pragma mark - drawing methods
描画系のメソッドを書く場所。
NSViewのサブクラスしか関係ないが、当然まとめておくと楽。
例:
- (void)drawRect:(NSRect)dirtyRect;
pragma mark - delegate/datasource methods
他の分類には分けられない、delegateメソッドやdatsourceメソッドを書く場所。
例:
// NSSpliterViewのdelegate
- (void)splitViewWillResizeSubviews:(NSNotification *)notification;
- (void)splitViewDidResizeSubviews:(NSNotification *)notification;
pragma mark - accessor methods (in pairs)
アクセッサとKVCに関連するものを書く。
依存関係の記述の”keyPathsForValuesAffectingプロパティ名”クラスメソッドもここに書く。 インデックス付きアクセッサパターンのメソッドもここにまとめます。
例:
+ (NSSet *)keyPathsForValuesAffectingObject
- (id) object
- (void) setObject:(id)inObject
pragma mark - Utility methods
その他のユーティリティメソッドを書く。例は特になし。
参考文献
元ネタは、ヒレガス本かその前後のはずだがググっても出てこない。