developer's diary

最近はc#のエントリが多いです

C# (dotnetcore) iText7でスキャンした電子書籍に目次(しおり)をつけてみた(The Art of UNIX Programming)

The Art of UNIX Programmingの目次をつける

この本をスキャンしてPDFにしました。

The Art of UNIX Programming

The Art of UNIX Programming

結果

こんな感じに目次ができました。

f:id:mitsugi-bb:20200926085341p:plain
目次がついた様子

NuGetでiText7をインストール

f:id:mitsugi-bb:20200926085130p:plain
iText7をインストール

ソース

ゴリゴリに記述しました。またどこかで解説します。

using System;
using System.Collections.Generic;
using System.IO;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Navigation;

namespace iTextBookMarkAdd
{
    public class ChangeBookmarks
    {
        /// <summary>出力先ファイル名</summary>
        public static readonly String DEST = "/Users/mitsugi/Desktop/u_add.pdf";

        /// <summary>出力元ファイル名</summary>
        public static readonly String SRC = "/Users/mitsugi/Desktop/u.pdf";

        /// <summary>メイン処理</summary>
        public static void Main(String[] args)
        {
            //ファイルを新規作成
            FileInfo file = new FileInfo(DEST);
            file.Directory.Create();

            //PDFドキュメント作成(複製)
            PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(DEST));

            //アウトライン取得
            PdfOutline outline = pdfDoc.GetOutlines(true);

            //アウトラインの項目を全て、listに一旦掘り込む
            List<PdfOutline> list = new List<PdfOutline>();
            foreach (var item in outline.GetAllChildren())
            {
                list.Add(item);
            }

            //アウトライン項目を全て削除する
            foreach (var item in list)
            {
                item.RemoveOutline();
            }

            //アウトラインを作成
            PdfOutline outline0 = pdfDoc.GetOutlines(true).AddOutline("序章");
            outline0.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(8), 1, 1, 1));
            outline0.AddOutline("誰がこの本を読むべきか").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(9), 1, 1, 1));
            outline0.AddOutline("この本の使い方").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(10), 1, 1, 1));
            outline0.AddOutline("関連する参考文献").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(11), 1, 1, 1));
            outline0.AddOutline("ケーススタディについて").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(13), 1, 1, 1));
            outline0.AddOutline("著者の謝辞").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(14), 1, 1, 1));

            pdfDoc.GetOutlines(true).AddOutline("目次").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(17), 1, 1, 1));

            PdfOutline outline1 = pdfDoc.GetOutlines(true).AddOutline("第1部 コンテキスト");
            outline1.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(30), 1, 1, 1));
            PdfOutline outline1_1 = outline1.AddOutline("第1章 思想 :大切なのは思想だ");
            outline1_1.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(32), 1, 1, 1));
            outline1_1.AddOutline("1.1 文化? なんのこと?").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(32), 1, 1, 1));
            outline1_1.AddOutline("1.2 Unixの生命力").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(33), 1, 1, 1));
            outline1_1.AddOutline("1.3 Unix文化の学習に対する反対論").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(34), 1, 1, 1));
            outline1_1.AddOutline("1.4 Unixの短所").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(35), 1, 1, 1));
            PdfOutline outline1_1_5 = outline1_1.AddOutline("1.5 Unixの長所");
            outline1_1_5.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(37), 1, 250, 1));
            outline1_1_5.AddOutline("1.5.1 オープンソースソフトウエア").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(37), 1, 1, 1));
            outline1_1_5.AddOutline("1.5.2 プラツトフォームを越えた移植性とオープンな標準").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(37), 1, 1, 1));
            outline1_1_5.AddOutline("1.5.3 インターネットとWeb").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(37), 1, 1, 1));
            outline1_1_5.AddOutline("1.5.4 オープンソースコミュニティ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(38), 1, 1, 1));
            outline1_1_5.AddOutline("1.5.5 あらゆる面での柔軟性").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(39), 1, 1, 1));
            outline1_1_5.AddOutline("1.5.6 ハックして楽しい Unix").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(39), 1, 1, 1));
            outline1_1_5.AddOutline("1.5.7 他の場面にも応用できる Unixの 教訓").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(40), 1, 1, 1));
            PdfOutline outline1_1_6 = outline1_1.AddOutline("1.6 Unix思想の基礎");
            outline1_1_6.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(41), 1, 250, 1));
            outline1_1_6.AddOutline("1.6.1 モジュール化の原則 :クリーンなインターフエイスで結合される単純な部品を作れ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(44), 1, 1, 1));
            outline1_1_6.AddOutline("1.6.2 明確性の原則 :巧妙になるより明確であれ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(44), 1, 1, 1));
            outline1_1_6.AddOutline("1.6.3 組み立て部品の原則 :他のプログラムと組み合わせられるように作れ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(45), 1, 1, 1));
            outline1_1_6.AddOutline("1.6.4 分離の原則 :メカニズムからポリシーを切り離せ。エンジンからインターフェイスを切り離せ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(46), 1, 1, 1));
            outline1_1_6.AddOutline("1.6.5 単純性の原則 :単純になるように設計せよ。複雑な部分を追加").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(47), 1, 1, 1));
            outline1_1_6.AddOutline("1.6.6 倹約の原則 :他のものでは代えられないことが明確に実証されない限り、大きなプログラムを書くな").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(48), 1, 1, 1));
            outline1_1_6.AddOutline("1.6.7 透明性の原則 :デバッグや調査が簡単になるように、わかりやすさを目指して設計せよ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(48), 1, 1, 1));
            outline1_1_6.AddOutline("1.6.8 安定性の原則 :安定性は,透明性と単純性から生まれる").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(49), 1, 1, 1));
            outline1_1_6.AddOutline("1.6.9 表現性の原則 :知識をデータのなかに固め、プログラムロジックが楽で安定したものになるようにせよ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(50), 1, 1, 1));
            outline1_1_6.AddOutline("1.6.10 驚き最小の原則 :インターフェイスは、驚きが最小になるように設計せよ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(50), 1, 1, 1));
            outline1_1_6.AddOutline("1.6.11 沈黙の原則 :どうしてもいわなければならない想定外なことがないのなら.プログラムは何もいうな").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(51), 1, 1, 1));
            outline1_1_6.AddOutline("1.6.12 修復の原則 :エラーを起こさなければならないときには、できる限り早い段階でけたたましくエラーを起こせ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(52), 1, 1, 1));
            outline1_1_6.AddOutline("1.6.13 経済性の原則 :プログラマの時間は高価だ。マシンの時間よりもプログラマの時間を節約せよ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(52), 1, 1, 1));
            outline1_1_6.AddOutline("1.6.14 生成の原則 :手作業のハツクを避けよ。可能なら、プログラムを書くためのプログラムを書け").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(53), 1, 1, 1));
            outline1_1_6.AddOutline("1.6.15 最適化の原則 :磨 く前にプロトタイプを作れ。最適化する前にプロトタイプが動くようにせよ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(54), 1, 1, 1));
            outline1_1_6.AddOutline("1.6.16 多様性の原則 :「唯一の正しい方法」とする全ての主張を信用するな").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(55), 1, 1, 1));
            outline1_1_6.AddOutline("1.6.17 拡張性の原則 :未来は予想外に早くやつてくる。未来を見すえ て設計せよ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(55), 1, 1, 1));
            outline1_1.AddOutline("1.7 Unix思想を一言でまとめると").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(56), 1, 250, 1));
            outline1_1.AddOutline("1.8 Unix思想の応用").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(57), 1, 250, 1));
            outline1_1.AddOutline("1.9 姿勢も大切").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(57), 1, 250, 1));

            PdfOutline outline1_2 = outline1.AddOutline("第2章 歴史 :2つの文化の物語");
            outline1_2.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(60), 1, 1, 1));
            PdfOutline outline1_2_1 = outline1_2.AddOutline("2.1 Unixの起源と屈画史 :1969-1995");
            outline1_2_1.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(60), 1, 1, 1));
            outline1_2_1.AddOutline("2.1.1 創世記 :1969-1971").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(61), 1, 1, 1));
            outline1_2_1.AddOutline("2.1.2 出エジプト記 :1971-1980").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(63), 1, 1, 1));
            outline1_2_1.AddOutline("2.1.3 TCP/1PとUnix戦争 :1980-1990").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(66), 1, 1, 1));
            outline1_2_1.AddOutline("2.1.4 帝国への反撃 :1991-1995").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(66), 1, 1, 1));
            PdfOutline outline1_2_2 = outline1_2.AddOutline("2.2 ハッカーの起源と歴史 :1961-1995");
            outline1_2_2.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(74), 1, 1, 1));
            outline1_2_2.AddOutline("2.2.1 象牙の塔のなかでの遊び :1961-1980").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(75), 1, 1, 1));
            outline1_2_2.AddOutline("2.2.2 インターネットによる融合とフリーソフトウエア運動:1981-1991").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(76), 1, 1, 1));
            outline1_2_2.AddOutline("2.2.3 Linuxとプラグマティストの反応:1991-1998").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(79), 1, 1, 1));
            outline1_2.AddOutline("2.3 オープンソース運動 :1998年から現在まで").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(81), 1, 1, 1));
            outline1_2.AddOutline("2.4 Unixの歴史が示す教訓").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(83), 1, 1, 1));

            PdfOutline outline1_3 = outline1.AddOutline("第3章 対比 :Unix思想と他のOS");
            outline1_3.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(84), 1, 1, 1));
            PdfOutline outline1_3_1 = outline1_3.AddOutline("3.1 オペレーテイングシステムのスタイルを構成する要素");
            outline1_3_1.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(84), 1, 1, 1));
            outline1_3_1.AddOutline("3.1.1 オペレーテイングシステム基本思想").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(85), 1, 1, 1));
            outline1_3_1.AddOutline("3.1.2 マルチタスク機能").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(85), 1, 1, 1));
            outline1_3_1.AddOutline("3.1.3 プロセスの共同作業").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(86), 1, 1, 1));
            outline1_3_1.AddOutline("3.1.4 内部区分").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(87), 1, 1, 1));
            outline1_3_1.AddOutline("3.1.5 ファイル属性とレコード構造").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(88), 1, 1, 1));
            outline1_3_1.AddOutline("3.1.6 バイナリフアイルフオーマツト").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(89), 1, 1, 1));
            outline1_3_1.AddOutline("3.1.7 ユーザーインターフェイススタイル").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(89), 1, 1, 1));
            outline1_3_1.AddOutline("3.1.8 対象とするユーザー").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(90), 1, 1, 1));
            outline1_3_1.AddOutline("3.1.9 プログラマになるための障壁").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(91), 1, 1, 1));
            PdfOutline outline1_3_2 = outline1_3.AddOutline("3.2 オペレーティングシステムの比較");
            outline1_3_2.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(92), 1, 1, 1));
            outline1_3_2.AddOutline("3.2.1 VMS").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(94), 1, 1, 1));
            outline1_3_2.AddOutline("3.2.2 MacOS").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(95), 1, 1, 1));
            outline1_3_2.AddOutline("3.2.3 OS/2").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(97), 1, 1, 1));
            outline1_3_2.AddOutline("3.2.4 Windows NT").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(99), 1, 1, 1));
            outline1_3_2.AddOutline("3.2.5 BeOS").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(102), 1, 1, 1));
            outline1_3_2.AddOutline("3.2.6 MVS").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(104), 1, 1, 1));
            outline1_3_2.AddOutline("3.2.7 VM/CMS").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(106), 1, 1, 1));
            outline1_3_2.AddOutline("3.2.8 Linux").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(108), 1, 1, 1));
            outline1_3.AddOutline("3.3 死んだものと残つたもの、その理由").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(110), 1, 1, 1));

            PdfOutline outline2 = pdfDoc.GetOutlines(true).AddOutline("第2部 設計");
            outline2.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(114), 1, 1, 1));

            PdfOutline outline4 = outline2.AddOutline("第4章 モジュール化 :簡潔に、単純に");
            outline4.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(116), 1, 1, 1));
            PdfOutline outline4_1 = outline4.AddOutline("4.1 カプセル化と最適なモジュールサイズ");
            outline4_1.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(118), 1, 1, 1));
            PdfOutline outline4_2 = outline4.AddOutline("4.2 簡潔性と直交性");
            outline4_2.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(118), 1, 1, 1));
            outline4_2.AddOutline("4.2.1 簡潔性").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(120), 1, 1, 1));
            outline4_2.AddOutline("4.2.2 直交性").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(122), 1, 1, 1));
            outline4_2.AddOutline("4.2.3 SPOT原則").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(124), 1, 1, 1));
            outline4_2.AddOutline("4.2.4 簡潔性と強力な単純の中心にあるもの").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(125), 1, 1, 1));
            outline4_2.AddOutline("4.2.5 独立性の価値").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(127), 1, 1, 1));
            PdfOutline outline4_3 = outline4.AddOutline("4.3 ソフトウェアにはたくさんの階層がある");
            outline4_3.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(128), 1, 1, 1));
            outline4_3.AddOutline("4.3.1 トップダウン対ボトムアップ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(128), 1, 1, 1));
            outline4_3.AddOutline("4.3.2 グルーレイヤ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(130), 1, 1, 1));
            outline4_3.AddOutline("4.3.3 ケーススタディ:薄いグルーとしてのC").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(131), 1, 1, 1));
            PdfOutline outline4_4 = outline4.AddOutline("4.4 ライブラリ");
            outline4_4.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(133), 1, 1, 1));
            outline4_4.AddOutline("4.4.1 ケーススタデイ:GIMPプラグイン").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(134), 1, 1, 1));
            PdfOutline outline4_5 = outline4.AddOutline("4.5 Unixとオブジエクト指向言語");
            outline4_5.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(135), 1, 1, 1));
            PdfOutline outline4_6 = outline4.AddOutline("4.6 モジュール化を実現するコーデイング");
            outline4_6.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(137), 1, 1, 1));

            PdfOutline outline5 = outline2.AddOutline("第5章 テキスト形式 :優れたプロトコルが優れた実践を生む");
            outline5.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(140), 1, 1, 1));
            PdfOutline outline5_1 = outline5.AddOutline("5.1 テキストであることの重要性");
            outline5_1.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(142), 1, 1, 1));
            outline5_1.AddOutline("5.1.1 ケーススタディ :Unixバスワードファイルフォーマット").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(144), 1, 1, 1));
            outline5_1.AddOutline("5.1.2 ケーススタディ :.newsrc フォーマット").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(145), 1, 1, 1));
            outline5_1.AddOutline("5.1.3 ケーススタディ :PNGグラフィックスファイルフォーマット").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(146), 1, 1, 1));
            PdfOutline outline5_2 = outline5.AddOutline("5.2 データファイルメタフォーマット");
            outline5_2.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(147), 1, 1, 1));
            outline5_2.AddOutline("5.2.1 DSVスタイル").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(148), 1, 1, 1));
            outline5_2.AddOutline("5.2.2 RFC 822フォーマット").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(149), 1, 1, 1));
            outline5_2.AddOutline("5.2.3 クッキージャーフォーマット").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(150), 1, 1, 1));
            outline5_2.AddOutline("5.2.4 レコードジャーフォーマット").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(151), 1, 1, 1));
            outline5_2.AddOutline("5.2.5 XML").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(152), 1, 1, 1));
            outline5_2.AddOutline("5.2.6 Windows INIフォーマット").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(154), 1, 1, 1));
            outline5_2.AddOutline("5.2.7 Unixのテキストファイルフォーマットに見られる慣習").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(155), 1, 1, 1));
            outline5_2.AddOutline("5.2.8 ファイル圧縮のメリットとデメリット").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(157), 1, 1, 1));
            PdfOutline outline5_3 = outline5.AddOutline("5.3 アプリケーションプロトコルの設計");
            outline5_3.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(158), 1, 1, 1));
            outline5_3.AddOutline("5.3.1 ケーススタディ:SMTP〔Simple Mail Transfer Protocol)").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(159), 1, 1, 1));
            outline5_3.AddOutline("5.3.2 ケーススタディ:POP3 (Post Office Protocol)").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(160), 1, 1, 1));
            outline5_3.AddOutline("5.3.3 ケーススタディ:IMAP (Internet Message Access Protocol)").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(161), 1, 1, 1));
            PdfOutline outline5_4 = outline5.AddOutline("5.4 アプリケーションプロトコルメタフォーマット");
            outline5_4.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(162), 1, 1, 1));
            outline5_4.AddOutline("5.4.1 古典的なインターネットアプリケーションのメタプロトコル").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(163), 1, 1, 1));
            PdfOutline outline5_4_2 = outline5_4.AddOutline("5.4.2 普遍的なアプリケーションプロトコルとしてのHTTP");
            outline5_4_2.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(163), 1, 1, 1));
            outline5_4_2.AddOutline("5.4.2.1 ケーススタディ :CDDB/freedb.org データベース").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(164), 1, 1, 1));
            outline5_4_2.AddOutline("5.4.2.2 ケーススタディ :IPP (Internet Printing Protocol)").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(165), 1, 1, 1));
            outline5_4.AddOutline("5.4.3 BEEP (Blocks Extensible Exchange Protocol)").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(166), 1, 1, 1));
            outline5_4.AddOutline("5.4.4 XML-RPC、SOAP、Jabber").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(166), 1, 1, 1));

            PdfOutline outline6 = outline2.AddOutline("第6章 透明性 :光あれ");
            outline6.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(168), 1, 1, 1));
            PdfOutline outline6_1 = outline6.AddOutline("6.1 ケーススタディ");
            outline6_1.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(169), 1, 1, 1));
            outline6_1.AddOutline("6.1.1 ケーススタディ :audacity").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(170), 1, 1, 1));
            outline6_1.AddOutline("6.1.2 ケーススタディ :fetchmallの-vオプション").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(171), 1, 1, 1));
            outline6_1.AddOutline("6.1.3 ケーススタディ :GCC").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(173), 1, 1, 1));
            outline6_1.AddOutline("6.1.4 ケーススタディ :kmail").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(174), 1, 1, 1));
            outline6_1.AddOutline("6.1.5 ケーススタディ :SNG").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(176), 1, 1, 1));
            outline6_1.AddOutline("6.1.6 terminfoデータベース").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(178), 1, 1, 1));
            outline6_1.AddOutline("6.1.7 Freecivデータファイル").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(180), 1, 1, 1));
            PdfOutline outline6_2 = outline6.AddOutline("6.2 透明性と開示性が得られる設計");
            outline6_2.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(182), 1, 1, 1));
            outline6_2.AddOutline("6.2.1 透明性の禅").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(183), 1, 1, 1));
            outline6_2.AddOutline("6.2.2 透明性と開示性を実現するコーディング").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(184), 1, 1, 1));
            outline6_2.AddOutline("6.2.3 透明性と過剰防衛の回避").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(185), 1, 1, 1));
            outline6_2.AddOutline("6.2.4 透明性と編集可能な表現").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(186), 1, 1, 1));
            outline6_2.AddOutline("6.2.5 透明性、誤りの診断と修復").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(187), 1, 1, 1));
            PdfOutline outline6_3 = outline6.AddOutline("6.3 メンテナンス性を実現する設計");
            outline6_3.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(188), 1, 1, 1));


            PdfOutline outline7 = outline2.AddOutline("第7章 マルチプログラミング :プロセスを機能別に分割する");
            outline7.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(192), 1, 1, 1));
            PdfOutline outline7_1 = outline7.AddOutline("7.1 複雑さの支配とパフォーマンスのチューニングの分割");
            outline7_1.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(194), 1, 1, 1));
            PdfOutline outline7_2 = outline7.AddOutline("7.2 Unix IPCメソッドの分類学");
            outline7_2.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(195), 1, 1, 1));
            PdfOutline outline7_2_1 = outline7_2.AddOutline("7.2.1 専用プログラムに処理を委ねる");
            outline7_2_1.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(195), 1, 1, 1));
            outline7_2_1.AddOutline("7.2.1.1 ケーススタディ :muttメールユーザーエージェント").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(196), 1, 1, 1));
            PdfOutline outline7_2_2 = outline7_2.AddOutline("7.2.2 パイプ、リダイレクト、フィルタ");
            outline7_2_2.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(196), 1, 1, 1));
            outline7_2_2.AddOutline("7.2.2.1 ケーススタディ :ページャーへのパイプ出力").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(198), 1, 1, 1));
            outline7_2_2.AddOutline("7.2.2.3 ケーススタディ :pic2graph").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(199), 1, 1, 1));
            outline7_2_2.AddOutline("7.2.2.4 ケーススタディ :bc(1)とdc(1)").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(200), 1, 1, 1));
            outline7_2_2.AddOutline("7.2.2.5 反ケーススタディ :fetchmailはなぜパイプラインではないのか").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(200), 1, 1, 1));
            PdfOutline outline7_2_3 = outline7_2.AddOutline("7.2.3 ラッパー");
            outline7_2_3.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(201), 1, 1, 1));
            outline7_2_3.AddOutline("7.2.3.1 ケーススタディ:パックアップスクリプト").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(198), 1, 1, 1));
            PdfOutline outline7_2_4 = outline7_2.AddOutline("7.2.4 ラッパー");
            outline7_2_4.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(202), 1, 1, 1));
            PdfOutline outline7_2_5 = outline7_2.AddOutline("7.2.5 スレーブプロセス");
            outline7_2_5.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(203), 1, 1, 1));
            outline7_2_5.AddOutline("7.2.5.1 ケーススタディ:scpとssh").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(204), 1, 1, 1));
            PdfOutline outline7_2_6 = outline7_2.AddOutline("7.2.6 ビアツービアのプロセス間通信 (IPC)");
            outline7_2_6.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(204), 1, 1, 1));
            outline7_2_6.AddOutline("7.2.6.1 一時ファイル").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(204), 1, 1, 1));
            outline7_2_6.AddOutline("7.2.6.2 シグナル").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(205), 1, 1, 1));
            outline7_2_6.AddOutline("7.2.6.3 システムデーモンとシグナル").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(207), 1, 1, 1));
            outline7_2_6.AddOutline("7.2.6.4 fetchmailのシグナルの使い方").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(207), 1, 1, 1));
            PdfOutline outline7_2_6_5 = outline7_2_6.AddOutline("7.2.6.5 ソケット");
            outline7_2_6_5.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(208), 1, 1, 1));
            outline7_2_6_5.AddOutline("7.2.6.5.1 PostgreSQL").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(209), 1, 1, 1));
            outline7_2_6_5.AddOutline("7.2.6.5.2 Freeciv").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(210), 1, 1, 1));
            outline7_2_6.AddOutline("7.2.6.6 共有メモリ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(210), 1, 1, 1));
            PdfOutline outline7_3 = outline7.AddOutline("7.3 問題点や避けるべき方法");
            outline7_3.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(212), 1, 1, 1));
            PdfOutline outline7_3_1 = outline7_3.AddOutline("7.3.1 時代遅れになつた Unixの IPCメソッド");
            outline7_3_1.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(212), 1, 1, 1));
            outline7_3_1.AddOutline("7.3.1.1 System V IPC").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(212), 1, 1, 1));
            outline7_3_1.AddOutline("7.3.1.2 Streams").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(212), 1, 1, 1));
            outline7_3.AddOutline("7.3.2 リモートプロシージャ呼び出し").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(212), 1, 1, 1));
            outline7_3.AddOutline("7.3.3 マルチスレッド---脅威それとも厄介者").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(212), 1, 1, 1));
            outline7.AddOutline("7.4 設計レベルでのプロセス分割").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(217), 1, 1, 1));



            PdfOutline outline8 = outline2.AddOutline("第8章 ミニ言語 :歌いだす記法を探す");
            outline8.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(220), 1, 1, 1));
            outline8.AddOutline("8.1 言語の分類学").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(222), 1, 1, 1));
            PdfOutline outline8_2 = outline8.AddOutline("8.2 ミニ言語の応用");
            outline8_2.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(224), 1, 1, 1));
            outline8_2.AddOutline("8.2.1 ケーススタディ :sng").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(224), 1, 1, 1));
            outline8_2.AddOutline("8.2.2 ケーススタディ :正規表現").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(224), 1, 1, 1));
            outline8_2.AddOutline("8.2.3 ケーススタディ :Glade").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(227), 1, 1, 1));
            outline8_2.AddOutline("8.2.4 ケーススタディ :m4").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(229), 1, 1, 1));
            outline8_2.AddOutline("8.2.5 ケーススタディ :XSLT").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(230), 1, 1, 1));
            outline8_2.AddOutline("8.2.6 ケーススタディ :DWB").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(231), 1, 1, 1));
            outline8_2.AddOutline("8.2.7 ケーススタディ :fetchmailの実行制御ファイルの構文").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(126), 1, 1, 1));
            outline8_2.AddOutline("8.2.8 ケーススタディ :awk").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(237), 1, 1, 1));
            outline8_2.AddOutline("8.2.9 ケーススタディ :PostScript").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(238), 1, 1, 1));
            outline8_2.AddOutline("8.2.10 ケーススタディ :bcとdc").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(240), 1, 1, 1));
            outline8_2.AddOutline("8.2.11 ケーススタディ :Emacs Lisp").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(241), 1, 1, 1));
            outline8_2.AddOutline("8.2.12 ケーススタディ :Javascript").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(242), 1, 1, 1));
            PdfOutline outline8_3 = outline8.AddOutline("8.3 ミニ言語の設計");
            outline8_3.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(243), 1, 1, 1));
            outline8_3.AddOutline("8.3.1 適切な複雑度の選択").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(243), 1, 1, 1));
            outline8_3.AddOutline("8.3.2 言語の拡張と組み込みの言語").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(245), 1, 1, 1));
            outline8_3.AddOutline("8.3.3 カスタム文法の作成").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(246), 1, 1, 1));
            outline8_3.AddOutline("8.3.4 マクロには注意").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(246), 1, 1, 1));
            outline8_3.AddOutline("8.3.5 言語かアプリケーションプロトコルか").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(248), 1, 1, 1));


            PdfOutline outline9 = outline2.AddOutline("第9章 コード生成 :高い水準で規定する");
            outline9.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(250), 1, 1, 1));
            PdfOutline outline9_1 = outline9.AddOutline("9.1 データ駆動プログラミング");
            outline9_1.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(251), 1, 1, 1));
            outline9_1.AddOutline("9.1.1 ケーススタディ :ascii").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(252), 1, 1, 1));
            outline9_1.AddOutline("9.1.2 ケーススタディ :統計的SPAMフィルタ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(253), 1, 1, 1));
            outline9_1.AddOutline("9.1.3 ケーススタディ :fetchmailconfのメタクラスハック").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(254), 1, 1, 1));
            PdfOutline outline9_2 = outline9.AddOutline("9.2 その場限りのコード生成");
            outline9_2.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(259), 1, 1, 1));
            outline9_2.AddOutline("9.2.1 ケーススタディ :asciiの表示の為のコード生成").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(259), 1, 1, 1));
            outline9_2.AddOutline("9.2.2 ケーススタディ :表形式のリストに対応するHTMLコードの生成").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(262), 1, 1, 1));

            PdfOutline outline10 = outline2.AddOutline("第10章 設定 :気持ちよくスタートしよう");
            outline10.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(266), 1, 1, 1));
            outline10.AddOutline("10.1 何を設定可能にすべきか").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(251), 1, 1, 1));
            outline10.AddOutline("10.2 設定のありか").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(268), 1, 1, 1));
            PdfOutline outline10_3 = outline10.AddOutline("10.3 実行制御ファイル");
            outline10_3.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(269), 1, 1, 1));
            outline10_3.AddOutline("10.3.1 ケーススタディ:.netrcファイル").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(271), 1, 1, 1));
            outline10_3.AddOutline("10.3.2 他のオペレーティングシステムに対する移植性").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(273), 1, 1, 1));
            PdfOutline outline10_4 = outline10.AddOutline("10.4 環境変数");
            outline10_4.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(273), 1, 1, 1));
            outline10_4.AddOutline("10.4.1 システム環境変数").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(273), 1, 1, 1));
            outline10_4.AddOutline("10.4.2 ユーザー環境変数").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(274), 1, 1, 1));
            outline10_4.AddOutline("10.4.3 環境変数をいつ使うべきか").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(275), 1, 1, 1));
            outline10_4.AddOutline("10.4.4 他のオペレーションシステムへの移植性").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(276), 1, 1, 1));
            PdfOutline outline10_5 = outline10.AddOutline("10.5 コマンドライン行オプション");
            outline10_5.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(277), 1, 1, 1));
            outline10_5.AddOutline("10.5.1 コマンド行オプション-aから-zまで").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(278), 1, 1, 1));
            outline10_5.AddOutline("10.5.2 他のオペレーションシステムへの移植性").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(282), 1, 1, 1));
            PdfOutline outline10_6 = outline10.AddOutline("10.6 どの方法を選ぶか");
            outline10_6.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(283), 1, 1, 1));
            outline10_6.AddOutline("10.6.1 ケーススタディ:fetchmail").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(283), 1, 1, 1));
            outline10_6.AddOutline("10.6.2 ケーススタディ:XFree86サーバ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(285), 1, 1, 1));
            PdfOutline outline10_7 = outline10.AddOutline("10.7 これらのルールを破ると");
            outline10_7.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(287), 1, 1, 1));

            PdfOutline outline11 = outline2.AddOutline("第11章 ユーザーインターフェイス :Unix環境におけるユーザーインターフェイス設計");
            outline11.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(288), 1, 1, 1));
            outline11.AddOutline("11.1 驚き最小の原則をあてはめる").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(289), 1, 1, 1));
            outline11.AddOutline("11.2 Unixのインターフェイスの設計の歴史").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(291), 1, 1, 1));
            outline11.AddOutline("11.3 インターフェイス設計の評価方法").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(292), 1, 1, 1));
            PdfOutline outline11_4 = outline11.AddOutline("11.4 CLIとビジュアルンターフェイスのトレードオフ");
            outline11_4.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(294), 1, 1, 1));
            outline11_4.AddOutline("11.4.1 ケーススタディ:電卓プログラムを書くための2つの方法").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(298), 1, 1, 1));
            outline11.AddOutline("11.5 透明性、表現性、設定可能性").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(299), 1, 1, 1));
            PdfOutline outline11_6 = outline11.AddOutline("11.6 Unixのインターフェイス設計パターン");
            outline11_6.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(301), 1, 1, 1));
            outline11_6.AddOutline("11.6.1 フィルタパターン").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(302), 1, 1, 1));
            outline11_6.AddOutline("11.6.2 キャントリップパターン").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(303), 1, 1, 1));
            outline11_6.AddOutline("11.6.3 ソースパターン").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(304), 1, 1, 1));
            outline11_6.AddOutline("11.6.4 シンクパターン").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(304), 1, 1, 1));
            outline11_6.AddOutline("11.6.5 コンパイラパターン").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(305), 1, 1, 1));
            outline11_6.AddOutline("11.6.6 edパターン").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(305), 1, 1, 1));
            outline11_6.AddOutline("11.6.7 rogue風パターン").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(306), 1, 1, 1));
            PdfOutline outline11_6_8 = outline11_6.AddOutline("11.6.8 「エンジンとインターフェイスの分離」パターン");
            outline11_6_8.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(309), 1, 1, 1));
            outline11_6_8.AddOutline("11.6.8.1 コンフィギュレーター/アクタペア").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(310), 1, 1, 1));
            outline11_6_8.AddOutline("11.6.8.2 スプーラ/デーモンペア").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(310), 1, 1, 1));
            outline11_6_8.AddOutline("11.6.8.3 ドライバ/エンジンペア").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(311), 1, 1, 1));
            outline11_6_8.AddOutline("11.6.8.4 クライアント/サーバペア").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(313), 1, 1, 1));
            outline11_6.AddOutline("11.6.9 CLIパターン").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(314), 1, 1, 1));
            outline11_6.AddOutline("11.6.10 言語ベースのインターフェイスパターン").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(315), 1, 1, 1));
            PdfOutline outline11_7 = outline11.AddOutline("11.7 Unixインターフェイス設計パターンの使い方");
            outline11_7.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(316), 1, 1, 1));
            outline11_7.AddOutline("11.7.1 ポリバレントプログラムパターン").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(317), 1, 1, 1));
            outline11.AddOutline("11.8 普遍的なフロントエンドとしてのWebブラウザ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(318), 1, 1, 1));
            outline11.AddOutline("11.9 沈黙は金なり").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(320), 1, 1, 1));

            PdfOutline outline12 = outline2.AddOutline("第12章 最適化");
            outline12.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(322), 1, 1, 1));
            outline12.AddOutline("12.1 何かしなくちゃ、じゃない。じっとしていろ!").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(322), 1, 1, 1));
            outline12.AddOutline("12.2 最適化する前に計測せよ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(323), 1, 1, 1));
            outline12.AddOutline("12.3 局所化できていないことの害").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(325), 1, 1, 1));
            PdfOutline outline12_4 = outline12.AddOutline("12.4 スループットとレイテンシ");
            outline12_4.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(326), 1, 1, 1));
            outline12_4.AddOutline("12.4.1 バッチ処理").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(328), 1, 1, 1));
            outline12_4.AddOutline("12.4.2 処理のオーバーラップ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(328), 1, 1, 1));
            outline12_4.AddOutline("12.4.3 処理結果のキャッシュ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(329), 1, 1, 1));
            PdfOutline outline13 = outline2.AddOutline("第13章 複雑さ :できる限り単純に、それよりも単純でなく");
            outline13.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(332), 1, 1, 1));
            PdfOutline outline13_1 = outline13.AddOutline("13.1 複雑さとは何か");
            outline13_1.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(332), 1, 1, 1));
            outline13_1.AddOutline("13.1.1 複雑さを生む3つの源泉").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(333), 1, 1, 1));
            outline13_1.AddOutline("13.1.2 インターフェイスの複雑さと実装の複雑さのトレードオフ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(335), 1, 1, 1));
            outline13_1.AddOutline("13.1.3 本質的な複雑さ、選択上の複雑さ、付随的な複雑さ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(336), 1, 1, 1));
            outline13_1.AddOutline("13.1.4 複雑さの見取り図").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(337), 1, 1, 1));
            outline13_1.AddOutline("13.1.5 単純なだけでは十分でない場合").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(339), 1, 1, 1));
            PdfOutline outline13_2 = outline13.AddOutline("13.2 5エディタ物語");
            outline13_2.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(339), 1, 1, 1));
            outline13_2.AddOutline("13.2.1 ed").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(340), 1, 1, 1));
            outline13_2.AddOutline("13.2.2 vi").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(342), 1, 1, 1));
            outline13_2.AddOutline("13.2.3 Sam").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(343), 1, 1, 1));
            outline13_2.AddOutline("13.2.4 Emacs").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(344), 1, 1, 1));
            outline13_2.AddOutline("13.2.5 Wily").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(345), 1, 1, 1));
            PdfOutline outline13_3 = outline13.AddOutline("13.3 エディタの適性サイズ");
            outline13_3.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(346), 1, 1, 1));
            outline13_3.AddOutline("13.3.1 複雑さが問題となる場所").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(346), 1, 1, 1));
            outline13_3.AddOutline("13.3.2 妥協はつまづく").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(350), 1, 1, 1));
            outline13_3.AddOutline("13.3.3 Emacsは Unixの伝続に対する反証になるか").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(351), 1, 1, 1));
            PdfOutline outline13_4 = outline13.AddOutline("13.4 ソフトウェアの適正なサイズ");
            outline13_4.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(353), 1, 1, 1));


            PdfOutline outline3 = pdfDoc.GetOutlines(true).AddOutline("第3部 実装");
            outline3.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(356), 1, 1, 1));

            PdfOutline outline14 = outline3.AddOutline("第14章 言語 :CすべきかCせざるべきか?");
            outline14.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(358), 1, 1, 1));
            outline14.AddOutline("14.1 Unixの言語の打出の小槌").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(358), 1, 1, 1));
            outline14.AddOutline("14.2 なぜCではないのか").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(359), 1, 1, 1));
            outline14.AddOutline("14.3 インタープリタ言語と言語併用戦略").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(361), 1, 1, 1));
            PdfOutline outline14_4 = outline14.AddOutline("14.4 言語の評価");
            outline14_4.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(362), 1, 1, 1));
            PdfOutline outline14_4_1 = outline14_4.AddOutline("14.4.1 C");
            outline14_4_1.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(362), 1, 1, 1));
            outline14_4_1.AddOutline("14.4.1.1 Cケーススタディ:fetchmail").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(363), 1, 1, 1));
            PdfOutline outline14_4_2 = outline14_4.AddOutline("14.4.2 C++");
            outline14_4_2.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(364), 1, 1, 1));
            outline14_4_2.AddOutline("14.4.2.1 C++ケーススタディ:Qtツールキット").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(366), 1, 1, 1));
            PdfOutline outline14_4_3 = outline14_4.AddOutline("14.4.3 シェル");
            outline14_4_3.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(367), 1, 1, 1));
            outline14_4_3.AddOutline("14.4.3.1 ケーススタディ:xmlto").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(368), 1, 1, 1));
            outline14_4_3.AddOutline("14.4.3.2 ケーススタディ:Sorcery Linux").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(369), 1, 1, 1));
            PdfOutline outline14_4_4 = outline14_4.AddOutline("14.4.4 Perl");
            outline14_4_4.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(369), 1, 1, 1));
            outline14_4_4.AddOutline("14.4.4.1 小規模perlプログラムのケーススタデイ:blq").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(370), 1, 1, 1));
            outline14_4_4.AddOutline("14.4.4.2 大規模perlプログラムのケーススタデイ:keeper").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(371), 1, 1, 1));

            PdfOutline outline14_4_5 = outline14_4.AddOutline("14.4.5 Tcl");
            outline14_4_5.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(371), 1, 1, 1));
            outline14_4_5.AddOutline("14.4.5.1 ケーススタデイ:TkMan").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(373), 1, 1, 1));
            outline14_4_5.AddOutline("14.4.5.2 大規模 Tclプログラムのケーススタディ:Moodss").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(373), 1, 1, 1));

            PdfOutline outline14_4_6 = outline14_4.AddOutline("14.4.6 Python");
            outline14_4_6.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(373), 1, 1, 1));
            outline14_4_6.AddOutline("14.4.6.1 小規模 Pythonプログラムのケーススタデイ:imgsizer").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(375), 1, 1, 1));
            outline14_4_6.AddOutline("14.4.6.2 中規模 Pythonプログラムのケーススタデイ:fetchma‖ conf").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(375), 1, 1, 1));
            outline14_4_6.AddOutline("14.4.6.3 大規模 Pythonプログラムのケーススタディ:PIL").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(376), 1, 1, 1));

            PdfOutline outline14_4_7 = outline14_4.AddOutline("14.4.7 Java");
            outline14_4_7.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(377), 1, 1, 1));
            outline14_4_7.AddOutline("14.4.7.1 ケーススタディ:FreeNet").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(379), 1, 1, 1));


            outline14_4.AddOutline("14.4.8 Emacs Lisp").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(380), 1, 1, 1));
            outline14.AddOutline("14.5 未来に向けての流れ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(381), 1, 1, 1));
            outline14.AddOutline("14.6 Xツールキットの選び方").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(383), 1, 1, 1));


            PdfOutline outline15 = outline3.AddOutline("第15章 ツール :開発の戦略");
            outline15.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(386), 1, 1, 1));
            outline15.AddOutline("15.1 デベロッパフレンドリなオペレーテイングシステム").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(386), 1, 1, 1));
            PdfOutline outline15_2 = outline15.AddOutline("15.2 エデイタの選び方");
            outline15_2.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(387), 1, 1, 1));
            outline15_2.AddOutline("15.2.1 viについて知つていると便利なこと").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(388), 1, 1, 1));
            outline15_2.AddOutline("15.2.2 Emacsについて知つていると便利なこと").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(388), 1, 1, 1));
            outline15_2.AddOutline("15.2.3 新興宗教の信者的でない選び方 :両方を使う").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(389), 1, 1, 1));
            PdfOutline outline15_3 = outline15.AddOutline("15.3 専用コードジェネレータ");
            outline15_3.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(390), 1, 1, 1));
            PdfOutline outline15_3_1 = outline15_3.AddOutline("15.3.1 yaccとlex");
            outline15_3_1.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(390), 1, 1, 1));
            outline15_3_1.AddOutline("15.3.1.1 ケーススタディ:fetchmailrcの文法").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(393), 1, 1, 1));
            outline15_3.AddOutline("15.3.2 ケーススタディ:Glade").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(390), 1, 1, 1));
            PdfOutline outline15_4 = outline15.AddOutline("15.4 make:レシピの自動化");
            outline15_4.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(394), 1, 1, 1));
            outline15_4.AddOutline("15.4.1 makeの基本理論").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(395), 1, 1, 1));
            PdfOutline outline15_4_2 = outline15_4.AddOutline("15.4.2 C/C++以外の開発でのmake");
            outline15_4_2.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(397), 1, 1, 1));
            outline15_4_2.AddOutline("15.4.2.1 ケーススタディ:ドキュメントファイルの変換の為のmake").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(397), 1, 1, 1));
            outline15_4.AddOutline("15.4.3 ユーティリティプロダクション").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(397), 1, 1, 1));
            PdfOutline outline15_4_4 = outline15_4.AddOutline("15.4.4 メイクファイルの生成の生成");
            outline15_4_4.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(399), 1, 1, 1));
            outline15_4_4.AddOutline("15.4.4.1 makedepend").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(400), 1, 1, 1));
            outline15_4_4.AddOutline("15.4.4.2 Imake").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(400), 1, 1, 1));
            outline15_4_4.AddOutline("15.4.4.3 autoconf").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(401), 1, 1, 1));
            outline15_4_4.AddOutline("15.4.4.4 automake").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(402), 1, 1, 1));
            PdfOutline outline15_5 = outline15.AddOutline("15.5 バージョン管理システム");
            outline15_5.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(402), 1, 1, 1));
            outline15_5.AddOutline("15.5.1 なぜパージョン管理か").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(402), 1, 1, 1));
            outline15_5.AddOutline("15.5.2 手作業によるパージョン管理").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(403), 1, 1, 1));
            outline15_5.AddOutline("15.5.3 自動化されたバージョン管理").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(404), 1, 1, 1));
            PdfOutline outline15_5_4 = outline15_5.AddOutline("15.5.4 バージョン管理の為のUnixツール");
            outline15_5_4.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(405), 1, 1, 1));
            outline15_5_4.AddOutline("15.5.4.1 SCCS(Source Code Control System)").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(405), 1, 1, 1));
            outline15_5_4.AddOutline("15.5.4.2 RCS(Revision Control System)").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(405), 1, 1, 1));
            outline15_5_4.AddOutline("15.5.4.3 CVS(Control Version System)").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(406), 1, 1, 1));
            outline15_5_4.AddOutline("15.5.4.4 その他のバージョン管理システム").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(407), 1, 1, 1));
            outline15.AddOutline("15.6 実行時のデバッグ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(407), 1, 1, 1));
            outline15.AddOutline("15.7 プロファイリング").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(408), 1, 1, 1));
            PdfOutline outline15_8 = outline15.AddOutline("15.8 Emacsとツールの組み合わせ");
            outline15_8.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(409), 1, 1, 1));
            outline15_8.AddOutline("15.8.1 Emacsとmake").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(409), 1, 1, 1));
            outline15_8.AddOutline("15.8.2 Emacsと実行時デバッグ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(410), 1, 1, 1));
            outline15_8.AddOutline("15.8.3 Emacsとバージョン管理").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(410), 1, 1, 1));
            outline15_8.AddOutline("15.8.4 Emacsとプロファイリング").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(411), 1, 1, 1));
            outline15_8.AddOutline("15.8.5 IDEと同じかそれ以上").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(411), 1, 1, 1));


            PdfOutline outline16 = outline3.AddOutline("第16章 再利用 :やり直しを避けること");
            outline16.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(414), 1, 1, 1));
            outline16.AddOutline("16.1 J.Randam Newbleの物語").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(415), 1, 1, 1));
            outline16.AddOutline("16.2 再利用の鍵としての透明性").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(418), 1, 1, 1));
            outline16.AddOutline("16.3 再利用からオープンソースへ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(420), 1, 1, 1));
            outline16.AddOutline("16.4 もっとも優れたものはオープンだ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(421), 1, 1, 1));
            outline16.AddOutline("16.5 どこで探すか").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(423), 1, 1, 1));
            outline16.AddOutline("16.6 オープンソースソフトウェアを使ううえでの問題点").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(425), 1, 1, 1));
            PdfOutline outline16_7 = outline16.AddOutline("16.7 ライセンスの問題");
            outline16_7.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(426), 1, 1, 1));
            outline16_7.AddOutline("16.7.1 オープンソースと呼ばれる為の資格").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(427), 1, 1, 1));
            outline16_7.AddOutline("16.7.2 標準的なオープンソースライセンス").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(428), 1, 1, 1));
            outline16_7.AddOutline("16.7.3 法律家が必要になるとき").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(430), 1, 1, 1));


            PdfOutline outline_4 = pdfDoc.GetOutlines(true).AddOutline("第4部 コミュニティ");
            outline_4.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(432), 1, 1, 1));

            PdfOutline outline17 = outline_4.AddOutline("第17章 移植性 :ソフトウェアの移植性と標準の維持");
            outline17.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(434), 1, 1, 1));
            PdfOutline outline17_1 = outline17.AddOutline("17.1 Cの発達");
            outline17_1.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(435), 1, 1, 1));
            outline17_1.AddOutline("17.1.1 Cの初期の歴史").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(435), 1, 1, 1));
            outline17_1.AddOutline("17.1.2 C標準").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(437), 1, 1, 1));

            PdfOutline outline17_2 = outline17.AddOutline("17.2 Unix標準");
            outline17_2.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(438), 1, 1, 1));
            outline17_2.AddOutline("17.2.1 標準規格とUnix戦争").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(439), 1, 1, 1));
            outline17_2.AddOutline("17.2.2 勝利の宴に現れた亡霊").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(442), 1, 1, 1));
            outline17_2.AddOutline("17.2.3 オープンソースの世界におけるUnix標準").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(442), 1, 1, 1));


            outline17.AddOutline("17.4 DNAとしての仕様とRNAとしてのコード").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(444), 1, 1, 1));
            PdfOutline outline17_5 = outline17.AddOutline("17.5 移植性を確保するプログラミング");
            outline17_5.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(450), 1, 1, 1));

            PdfOutline outline17_5_1 = outline17_5.AddOutline("17.5.1 言語の選択と移植性");
            outline17_5_1.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(450), 1, 1, 1));
            outline17_5_1.AddOutline("17.5.1.1 Cの移植性").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(450), 1, 1, 1));
            outline17_5_1.AddOutline("17.5.1.2 C++の移植性").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(451), 1, 1, 1));
            outline17_5_1.AddOutline("17.5.1.3 シェルの移植性").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(451), 1, 1, 1));
            outline17_5_1.AddOutline("17.5.1.4 Perlの移植性").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(451), 1, 1, 1));
            outline17_5_1.AddOutline("17.5.1.5 Pythonの移植性").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(451), 1, 1, 1));
            outline17_5_1.AddOutline("17.5.1.6 TCLの移植性").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(452), 1, 1, 1));
            outline17_5_1.AddOutline("17.5.1.7 Javaの移植性").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(452), 1, 1, 1));
            outline17_5_1.AddOutline("17.5.1.8 Emacs Lispの移植性").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(453), 1, 1, 1));
            outline17_5.AddOutline("17.5.2 システムヘの依存を通けるには").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(453), 1, 1, 1));
            outline17_5.AddOutline("17.5.3 移植性を確保するためのツール").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(454), 1, 1, 1));


            outline17.AddOutline("17.6 国際化").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(454), 1, 1, 1));
            outline17.AddOutline("17.7 移植性、オープン標準、オープンソース").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(455), 1, 1, 1));



            PdfOutline outline18 = outline_4.AddOutline("第18章 ドキュメント:Web中心の世界でコードの説明をする");
            outline18.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(458), 1, 1, 1));
            outline18.AddOutline("18.1 ドキュメントの概念").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(459), 1, 1, 1));
            PdfOutline outline18_2 = outline18.AddOutline("18.2 Unixスタイル");
            outline18_2.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(461), 1, 1, 1));
            outline18_2.AddOutline("18.2.1 大規模ドキュメントへの偏り").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(461), 1, 1, 1));
            outline18_2.AddOutline("18.2.2 文化的なスタイル").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(462), 1, 1, 1));
            PdfOutline outline18_3 = outline18.AddOutline("18.3 Unixドキュメントフォーマット");
            outline18_3.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(463), 1, 1, 1));
            outline18_3.AddOutline("18.3.1 troffとDWBツール").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(463), 1, 1, 1));
            outline18_3.AddOutline("18.3.2 TEX").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(465), 1, 1, 1));
            outline18_3.AddOutline("18.3.3 Texinfo").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(466), 1, 1, 1));
            outline18_3.AddOutline("18.3.4 POD").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(467), 1, 1, 1));
            outline18_3.AddOutline("18.3.5 HTML").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(467), 1, 1, 1));
            outline18_3.AddOutline("18.3.6 DocBook").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(467), 1, 1, 1));
            outline18.AddOutline("18.4 現在の混沌と脱出口").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(468), 1, 1, 1));
            PdfOutline outline18_5 = outline18.AddOutline("18.5 DocBook");
            outline18_5.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(468), 1, 1, 1));
            outline18_5.AddOutline("18.5.1 DTD").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(469), 1, 1, 1));
            outline18_5.AddOutline("18.5.2 その他のDTD").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(470), 1, 1, 1));
            outline18_5.AddOutline("18.5.3 DocBookツールチェーン").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(470), 1, 1, 1));
            outline18_5.AddOutline("18.5.4 移植ツール").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(472), 1, 1, 1));
            outline18_5.AddOutline("18.5.5 編集ツール").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(474), 1, 1, 1));
            outline18_5.AddOutline("18.5.6 関連する標準と実績").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(475), 1, 1, 1));
            outline18_5.AddOutline("18.5.7 SGML").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(475), 1, 1, 1));
            outline18_5.AddOutline("18.5.7 XML-DocBookの参考文献").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(475), 1, 1, 1));
            outline18.AddOutline("18.6 Unixでドキュメント書く為の最良の方法").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(475), 1, 1, 1));


            PdfOutline outline19 = outline_4.AddOutline("第19章 オープンソース:新しいUnixコミュニティでのプログラミング");
            outline19.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(478), 1, 1, 1));
            outline19.AddOutline("19.1 Unixとオープンソース").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(478), 1, 1, 1));
            PdfOutline outline19_2 = outline19.AddOutline("19.2 オープンソースデベロッパたちと共同作業するための最良の方法");
            outline19_2.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(481), 1, 1, 1));
            PdfOutline outline19_2_1 = outline19_2.AddOutline("19.2.1 パッチの優れた方法");
            outline19_2_1.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(481), 1, 1, 1));
            outline19_2_1.AddOutline("19.2.1.1 パッチを送り、アーカイブ全体やファイルを送らないようにしよう").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(482), 1, 1, 1));
            outline19_2_1.AddOutline("19.2.1.2 コードの最新パージョンに対するパッチを送るようにしよう").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(482), 1, 1, 1));
            outline19_2_1.AddOutline("19.2.1.3 生成したファイルのパッチを入れないようにしよう").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(482), 1, 1, 1));
            outline19_2_1.AddOutline("19.2.1.4 RCSや SCCSの$シンボルを書き換えただけのパッチを送らないようにしよう").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(483), 1, 1, 1));
            outline19_2_1.AddOutline("19.2.1.5 デフォルト(-e)フォーマットではなく、-cまたは-uフォーマットを使おう").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(483), 1, 1, 1));
            outline19_2_1.AddOutline("19.2.1.6 パッチのドキュメントを組み込もう").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(483), 1, 1, 1));
            outline19_2_1.AddOutline("19.2.1.7 パッチの説明を組み込もう").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(484), 1, 1, 1));
            outline19_2_1.AddOutline("19.2.1.8 コードに役立つコメントを入れよう").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(484), 1, 1, 1));
            outline19_2_1.AddOutline("19.2.1.9 パッチが受け入れられなくても人格的な問題だと考え込まないようにしよう").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(485), 1, 1, 1));
            PdfOutline outline19_2_2 = outline19_2.AddOutline("19.2.2 プロジェクトとアーカイブの優れた命名方法");
            outline19_2_2.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(485), 1, 1, 1));
            outline19_2_2.AddOutline("19.2.2.1 プレフイツクスとメジャー.マイナー.パッチ番号という形式の GNU スタイルの名前を使おう").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(485), 1, 1, 1));
            outline19_2_2.AddOutline("19.2.2.2 しかし、通切な場合には、ローカルな習慣を尊重しよう").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(487), 1, 1, 1));
            outline19_2_2.AddOutline("19.2.2.3 ファイル名プレフィックスとしてユニークで入力しやすいものを選ぶことを心がけよう").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(488), 1, 1, 1));
            PdfOutline outline19_2_3 = outline19_2.AddOutline("19.2.3 開発の優れた方法");
            outline19_2_3.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(488), 1, 1, 1));
            outline19_2_3.AddOutline("19.2.3.1 プロプライエタリコードに依存しないようにしよう").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(488), 1, 1, 1));
            outline19_2_3.AddOutline("19.2.3.2 GNU autotoolsを 使おう").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(489), 1, 1, 1));
            outline19_2_3.AddOutline("19.2.3.3 リリースするまえにコードをテストしよう").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(489), 1, 1, 1));
            outline19_2_3.AddOutline("19.2.3.4 リリースするまえにコードに健全性チェックをかけよう").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(490), 1, 1, 1));
            outline19_2_3.AddOutline("19.2.3.5 リリース前にドキュメントとREADMEの スベルをチェックしよう").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(490), 1, 1, 1));
            outline19_2_3.AddOutline("19.2.3.6 C/C++の移植性を確保するためのよい方法").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(490), 1, 1, 1));
            PdfOutline outline19_2_4 = outline19_2.AddOutline("19.2.4 ディストリピューション作成のためのよい方法");
            outline19_2_4.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(492), 1, 1, 1));
            outline19_2_4.AddOutline("19.2.4.1 tarボールがかならず1つの新しいディレクトリに解凍されるように作ろう").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(492), 1, 1, 1));
            outline19_2_4.AddOutline("19.2.4.2 READMEファイルを入れよう").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(493), 1, 1, 1));
            outline19_2_4.AddOutline("19.2.4.3 標準的なファイル名の慣習を尊重して従おう").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(493), 1, 1, 1));
            outline19_2_4.AddOutline("19.2.4.4 アップグレード").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(494), 1, 1, 1));
            outline19_2_4.AddOutline("19.2.4.5 LinuxのもとではRPMを用意せよ").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(495), 1, 1, 1));
            outline19_2_4.AddOutline("19.2.4.6 チェックサムを提供しよう").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(496), 1, 1, 1));
            PdfOutline outline19_2_5 = outline19_2.AddOutline("19.2.5 コミュニケーションの優れた方法");
            outline19_2_5.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(496), 1, 1, 1));
            outline19_2_5.AddOutline("19.2.5.1 Freshmeatで発表しよう").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(496), 1, 1, 1));
            outline19_2_5.AddOutline("19.2.5.2 関連ニュースグループに発表しよう").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(496), 1, 1, 1));
            outline19_2_5.AddOutline("19.2.5.3 Webサイトを用意しよう").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(497), 1, 1, 1));
            outline19_2_5.AddOutline("19.2.5.4 プロジエクトメーリングリストを作ろう").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(497), 1, 1, 1));
            outline19_2_5.AddOutline("19.2.5.5 メジヤーなアーカイブでリリースしよう").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(498), 1, 1, 1));
            outline19.AddOutline("19.3 ライセンスの論理 :どれを選ぶか").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(498), 1, 1, 1));
            outline19.AddOutline("19.4 標準ライセンスを使つたほうがよい理由").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(498), 1, 1, 1));
            PdfOutline outline19_5 = outline19.AddOutline("19.5 さまざまなオープンソーススライセンス");
            outline19_5.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(499), 1, 1, 1));
            outline19_5.AddOutline("19.5.1 MITまたはXコンソーシアムライセンス").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(499), 1, 1, 1));
            outline19_5.AddOutline("19.5.2 BSD Classlc License").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(499), 1, 1, 1));
            outline19_5.AddOutline("19.5.3 Artlstlc License").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(500), 1, 1, 1));
            outline19_5.AddOutline("19.5.4 GPL").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(500), 1, 1, 1));
            outline19_5.AddOutline("19.5.5 MPL").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(501), 1, 1, 1));
            
            PdfOutline outline20 = outline_4.AddOutline("第20章 未来:危険と可能性");
            outline19.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(502), 1, 1, 1));
            outline19.AddOutline("20.1 Unixの伝統における本質と偶然").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(502), 1, 1, 1));
            outline19.AddOutline("20.2 Plan 9:未来はかつてどうだつたか").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(505), 1, 1, 1));
            PdfOutline outline20_3 = outline19.AddOutline("20.3 Unixの設計の問題点");
            outline20_3.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(507), 1, 1, 1));
            outline20_3.AddOutline("20.3.1 Unixフアイルはパイトを集めた大きな袋に過ぎない").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(508), 1, 1, 1));
            outline20_3.AddOutline("20.3.2 Unixの GUlサポートは弱い").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(509), 1, 1, 1));
            outline20_3.AddOutline("20.3.3 ファイルを削除すると復活できない").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(510), 1, 1, 1));
            outline20_3.AddOutline("20.3.4 Unixは静的なファイルシステムを前提としている").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(510), 1, 1, 1));
            outline20_3.AddOutline("20.3.5 ジョブ制御の設計がお粗末だつた").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(511), 1, 1, 1));
            outline20_3.AddOutline("20.3.6 Unix APIは例外を使わない").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(512), 1, 1, 1));
            outline20_3.AddOutline("20.3.7 iocti(2)と fcnti(2)がごちゃごちゃしている").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(513), 1, 1, 1));
            outline20_3.AddOutline("20.3.8 Unixのセキュリテイモデルが原始的過ぎる").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(513), 1, 1, 1));
            outline20_3.AddOutline("20.3.9 Unixは異なる種類の名前が多すぎる").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(514), 1, 1, 1));
            outline20_3.AddOutline("20.3.10 ファイルシステムはまちがっているかもしれない").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(514), 1, 1, 1));
            outline20_3.AddOutline("20.3.11 グローバルなインターネットアドレス空間に向かって").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(514), 1, 1, 1));
            outline19.AddOutline("20.4 Unixの環境の問題点").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(515), 1, 1, 1));
            outline19.AddOutline("20.5 Unix文化の問題点").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(517), 1, 1, 1));
            outline19.AddOutline("20.6 言じる理由").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(520), 1, 1, 1));

            PdfOutline outlineA = pdfDoc.GetOutlines(true).AddOutline("付録A 略語集");
            outlineA.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(522), 1, 1, 1));

            PdfOutline outlineB = pdfDoc.GetOutlines(true).AddOutline("付録B 参考文献");
            outlineB.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(526), 1, 1, 1));

            PdfOutline outlineC = pdfDoc.GetOutlines(true).AddOutline("付録C 寄稿者紹介");
            outlineC.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(538), 1, 1, 1));

            PdfOutline outlineD = pdfDoc.GetOutlines(true).AddOutline("付録D 無根的根 :不宇先生の Unix公案");
            outlineD.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(542), 1, 1, 1));
            outlineD.AddOutline("D.1 エディタのイントロダクション").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(542), 1, 1, 1));
            outlineD.AddOutline("D.2 不宇先生と 1万行").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(543), 1, 1, 1));
            outlineD.AddOutline("D.3 不宇先生とスクリプト").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(544), 1, 1, 1));
            outlineD.AddOutline("D.4 不宇先生が 2つの道を説く").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(545), 1, 1, 1));
            outlineD.AddOutline("D.5 不宇先生と方法論者").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(546), 1, 1, 1));
            outlineD.AddOutline("D.6 不宇先生がグラフイカルユーザーインターフェイスを説く").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(547), 1, 1, 1));
            outlineD.AddOutline("D.7 不宇先生とUnixの熱心な支持者").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(548), 1, 1, 1));
            outlineD.AddOutline("D.8 不宇先生がUnix相を説く").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(548), 1, 1, 1));
            outlineD.AddOutline("D.9 不宇先生とエンドユーザー").AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(549), 1, 1, 1));

            PdfOutline outlineE = pdfDoc.GetOutlines(true).AddOutline("索引");
            outlineE.AddDestination(PdfExplicitDestination.CreateXYZ(pdfDoc.GetPage(552), 1, 1, 1));

            //PDFを閉じる
            pdfDoc.Close();
        }
    }
}

C# (dotnetcore) CsvHelperでKEN_ALL.CSVを読み込み、郵便番号から住所を返答するコンソールアプリ作成

KEN_ALL.CSVとは

日本郵便が無償配布している、郵便番号と住所の対応が収録されたcsvファイル

www.post.japanpost.jp

KEN_ALL.CSVのレイアウト

No. 項目 説明
1 全国地方公共団体コード(JIS X0401、X0402) 半角数字 全国地方公共団体コード - Wikipedia
2 (旧)郵便番号(5桁) 半角数字 1999年まで利用されていた郵便番号
3 郵便番号(7桁) 半角数字 現在利用されている郵便番号(ハイフンなし)
4 都道府県名  半角カタカナ
5 市区町村名  半角カタカナ
6 町域名  半角カタカナ
7 都道府県名  漢字
8 市区町村名  漢字
9 町域名  漢字
10 一町域が二以上の郵便番号で表される場合の表示 半角数字 「1」は該当、
「0」は該当せず
11 小字毎に番地が起番されている町域の表示 半角数字 「1」は該当、
「0」は該当せず
12 丁目を有する町域の場合の表示 半角数字 「1」は該当、
「0」は該当せず
13 一つの郵便番号で二以上の町域を表す場合の表示 半角数字 「1」は該当、
「0」は該当せず
14 更新の表示 半角数字 「0」は変更なし、「1」は変更あり、
「2」廃止(廃止データのみ使用)
15 変更理由 半角数字 「0」は変更なし、
「1」市政・区政・町政・分区・政令指定都市施行、
「2」住居表示の実施、
「3」区画整理、
「4」郵便区調整等、
「5」訂正、
「6」廃止(廃止データのみ使用)

NuGet

dotnetcoreで読み込む場合は、Shift-Jisを読み込む為、「System.Text.Encoding.CodePages」を利用。 CSVの解析は、単純に「CsvHelper」が便利なので利用。

NuGet Gallery | CsvHelper 15.0.5

NuGet Gallery | System.Text.Encoding.CodePages 4.7.1

Install-Package CsvHelper
Install-Package System.Text.Encoding.CodePages

プログラム

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
using CsvHelper;
using CsvHelper.Configuration;

namespace KEN_ALL_CSV_READ
{
    /// <summary>
    /// 行オブジェクト
    /// </summary>
    internal class CsvRow
    {
        /// <summary>
        /// 全国地方公共団体コード(JIS X0401、X0402)
        /// </summary>
        public string col1 { get; set; }

        /// <summary>
        /// (旧)郵便番号(5桁)
        /// </summary>
        public string col2 { get; set; }

        /// <summary>
        /// 郵便番号(7桁)
        /// </summary>
        public string col3 { get; set; }

        /// <summary>
        /// 都道府県名(半角カタカナ)
        /// </summary>
        public string col4 { get; set; }

        /// <summary>
        /// 市区町村名(半角カタカナ)
        /// </summary>
        public string col5 { get; set; }

        /// <summary>
        /// 町域名(半角カタカナ)
        /// </summary>
        public string col6 { get; set; }

        /// <summary>
        /// 都道府県名(漢字)
        /// </summary>
        public string col7 { get; set; }

        /// <summary>
        /// 市区町村名(漢字)
        /// </summary>
        public string col8 { get; set; }

        /// <summary>
        /// 町域名(漢字)
        /// </summary>
        public string col9 { get; set; }

        /// <summary>
        /// 一町域が二以上の郵便番号で表される場合の表示
        /// </summary>
        public string col10 { get; set; }

        /// <summary>
        /// 小字毎に番地が起番されている町域の表示
        /// </summary>
        public string col11 { get; set; }

        /// <summary>
        /// 丁目を有する町域の場合の表示
        /// </summary>
        public string col12 { get; set; }

        /// <summary>
        /// 一つの郵便番号で二以上の町域を表す場合の表示
        /// </summary>
        public string col13 { get; set; }

        /// <summary>
        /// 更新の表示
        /// </summary>
        public string col14 { get; set; }

        /// <summary>
        /// 変更理由
        /// </summary>
        public string col15 { get; set; }
    }


    /// <summary>
    /// CSVと行オブジェクトのマッピング
    /// </summary>
    internal class CsvTable : ClassMap<CsvRow>
    {
        private CsvTable()
        {
            Map(c => c.col1).Index(0);//1番目
            Map(c => c.col2).Index(1);//2番目
            Map(c => c.col3).Index(2);//3番目
            Map(c => c.col4).Index(3);//4番目
            Map(c => c.col5).Index(4);//5番目
            Map(c => c.col6).Index(5);//6番目
            Map(c => c.col7).Index(6);//7番目
            Map(c => c.col8).Index(7);//8番目
            Map(c => c.col9).Index(8);//9番目
            Map(c => c.col10).Index(9);//10番目
            Map(c => c.col11).Index(10);//11番目
            Map(c => c.col12).Index(11);//12番目
            Map(c => c.col13).Index(12);//13番目
            Map(c => c.col14).Index(13);//14番目
            Map(c => c.col15).Index(14);//15番目
        }
    }


    class Program
    {

        //メモリ上の住所録データ
        private static List<CsvRow> Rows = new List<CsvRow>();

        //CSVファイルのパス
        private const string CSV_PATH = @"KEN_ALL.csv";

        static void Main(string[] args)
        {
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            ReadCsv();

            while (true)
            {
                Console.WriteLine("郵便番号を入力してください。");
                var postNo = Console.ReadLine();
                var flg = false;
                foreach (CsvRow row in Rows)
                {
                    if(row.col3 == postNo)
                    {
                        Console.Write(row.col7);
                        Console.Write(row.col8);
                        Console.WriteLine(row.col9);
                        flg = true;
                    }
                }
                if (!flg)
                {
                    Console.WriteLine("入力した郵便番号のデータが見つかりません。[{0}]", postNo);
                }

            }

        }

        static void ReadCsv()
        {
            //ファイルが無い場合は何もしない
            if (!System.IO.File.Exists(CSV_PATH)) return;

            using (var reader = new StreamReader(CSV_PATH, Encoding.GetEncoding("SHIFT_JIS")))
            using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
            {
                csv.Configuration.HasHeaderRecord = false;
                csv.Configuration.RegisterClassMap<CsvTable>();
                Rows.AddRange(csv.GetRecords<CsvRow>());
            }
        }
    }
}

結果

f:id:mitsugi-bb:20200922014534p:plain

参考

業務で「KEN_ALL.CSV」を使う場合は、他のリンクも参考にしておきましょう。

qiita.com

qiita.com

blog1.mammb.com

ken-all.hatenadiary.com

C# (dotnetcore) DataTableをSerialize/Deserializeする(System.Xml.SerializationとProtoBuf.Dataを比較)

DataTableをシリアライズ /デシリアライズ してみます。

また、XmlSerializerと、protobuf-net-dataでシリアライズで作成されたファイルのサイズ比較、 シリアライズ 、デシリアライズ の速度比較を行ってみました。

用語

用語 英語 意味
シリアライズ Serialize オブジェクトを文字列、バイト配列に置き換える
デシリアライズ Deserialize シリアライズ した文字列・バイト配列からオブジェクトに戻す

DataTableを作る

DataTable dt = new DataTable();
dt.TableName = "TABLE";
dt.Columns.Add("NO", typeof(int));
dt.Columns.Add("NAME", typeof(string));
dt.Columns.Add("COL1", typeof(string));
dt.Columns.Add("COL2", typeof(string));
dt.Columns.Add("COL3", typeof(string));
dt.Columns.Add("COL4", typeof(string));
dt.Columns.Add("COL5", typeof(string));
dt.Columns.Add("COL6", typeof(string));
dt.Columns.Add("COL7", typeof(string));

DataTableにデータを追加

MD5関数作成(サンプルデータに使います)

private static string MD5(int i)
{
    return System.Convert.ToBase64String(new System.Security.Cryptography.MD5CryptoServiceProvider().ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(i.ToString())));
}

データ追加用の関数作成

private static void AddRow(DataTable dt, int i)
{
    var dr = dt.NewRow();
    dr["NO"] = i;
    dr["NAME"] = "NAME:" + i.ToString();
    dr["COL1"] = MD5(i);
    dr["COL2"] = MD5(i * 2);
    dr["COL3"] = MD5(i * 3);
    dr["COL4"] = MD5(i * 4);
    dr["COL5"] = MD5(i * 5);
    dr["COL6"] = MD5(i * 6);
    dr["COL7"] = System.DBNull.Value;
    dt.Rows.Add(dr);
}

データ追加の様子(i<1;の1を増やすと作成するレコード数が増えます)

for (var i = 0; i < 1; i++) AddRow(dt, i);

XmlSerializerでシリアライズ

using (Stream stream = new FileStream("data.xml", FileMode.Create))
{
    XmlSerializer serializer = new XmlSerializer(dt.GetType());
    serializer.Serialize(stream, dt);
}

XmlSerializerでデシリアライズ

using (Stream stream = File.OpenRead("data.xml"))
{
    XmlSerializer serializer = new XmlSerializer(dt.GetType());
    xmlSerializerDt = (DataTable)serializer.Deserialize(stream);
}

ProtoBufでシリアライズ

using (Stream stream = new FileStream("data.data", FileMode.Create))
{
    DataSerializer.Serialize(stream, dt);
}

ProtoBufでデシリアライズ

var protoBufDt = new DataTable();
using (Stream stream = File.OpenRead("data.data"))
{
    protoBufDt.Load(DataSerializer.Deserialize(stream));
}

速度比較用プログラム

using System;
using System.Data;
using System.Linq;
using System.Diagnostics;
using System.IO;
using System.Xml.Serialization;
using ProtoBuf.Data;

namespace serializeExample
{
    class Program
    {
        static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.TableName = "TABLE";
            dt.Columns.Add("NO", typeof(int));
            dt.Columns.Add("NAME", typeof(string));
            dt.Columns.Add("COL1", typeof(string));
            dt.Columns.Add("COL2", typeof(string));
            dt.Columns.Add("COL3", typeof(string));
            dt.Columns.Add("COL4", typeof(string));
            dt.Columns.Add("COL5", typeof(string));
            dt.Columns.Add("COL6", typeof(string));
            dt.Columns.Add("COL7", typeof(string));

            for (var i = 0; i < 1; i++) AddRow(dt, i);
            Console.WriteLine("Count:{0:#,#}", dt.Rows.Count);
            diff(dt);

            for (var i = 0; i < 10; i++) AddRow(dt, i);
            Console.WriteLine("Count:{0:#,#}", dt.Rows.Count);
            diff(dt);

            for (var i = 0; i < 100; i++) AddRow(dt, i);
            Console.WriteLine("Count:{0:#,#}", dt.Rows.Count);
            diff(dt);

            for (var i = 0; i < 1000; i++) AddRow(dt, i);
            Console.WriteLine("Count:{0:#,#}", dt.Rows.Count);
            diff(dt);

            for (var i = 0; i < 10000; i++) AddRow(dt, i);
            Console.WriteLine("Count:{0:#,#}", dt.Rows.Count);
            diff(dt);

            for (var i = 0; i < 100000; i++) AddRow(dt, i);
            Console.WriteLine("Count:{0:#,#}", dt.Rows.Count);
            diff(dt);

            for (var i = 0; i < 1000000; i++) AddRow(dt, i);
            Console.WriteLine("Count:{0:#,#}", dt.Rows.Count);
            diff(dt);
        }

        private static void diff(DataTable dt)
        {
            DataTable xmlSerializerDt = null;
            DataTable protoBufDt = null;

            Stopwatch sw = new Stopwatch();
            sw.Start();
            using (Stream stream = new FileStream("data.xml", FileMode.Create))
            {
                XmlSerializer serializer = new XmlSerializer(dt.GetType());
                serializer.Serialize(stream, dt);
            }
            sw.Stop();
            Console.WriteLine("XML.Serialize:{0:#,#}ms", sw.ElapsedMilliseconds);

            Console.WriteLine("File Size:{0:#,#} byte", new FileInfo("data.xml").Length);

            sw.Reset();
            sw.Start();
            using (Stream stream = File.OpenRead("data.xml"))
            {
                XmlSerializer serializer = new XmlSerializer(dt.GetType());
                xmlSerializerDt = (DataTable)serializer.Deserialize(stream);
            }
            sw.Stop();
            Console.WriteLine("XML.Deserialize:{0:#,#}ms", sw.ElapsedMilliseconds);


            sw.Reset();
            sw.Start();
            using (Stream stream = new FileStream("data.data", FileMode.Create))
            {
                DataSerializer.Serialize(stream, dt);
            }
            sw.Stop();
            Console.WriteLine("ProtoBuf.Serialize:{0:#,#}ms", sw.ElapsedMilliseconds);

            Console.WriteLine("File Size:{0:#,#} byte", new FileInfo("data.data").Length);

            sw.Reset();
            sw.Start();
            protoBufDt = new DataTable();
            using (Stream stream = File.OpenRead("data.data"))
            {
                protoBufDt.Load(DataSerializer.Deserialize(stream));
            }
            sw.Stop();
            Console.WriteLine("ProtoBuf.Deserialize:{0:#,#}ms", sw.ElapsedMilliseconds);


            DataTable dtDiff = new DataTable();

            var wkDiffs2 = dt.AsEnumerable().Except(xmlSerializerDt.AsEnumerable(), DataRowComparer.Default);
            Console.WriteLine("Difference between original and XmlSerializer:{0}", wkDiffs2.Count());
            var wkDiffs3 = dt.AsEnumerable().Except(protoBufDt.AsEnumerable(), DataRowComparer.Default);
            Console.WriteLine("Difference between original and ProtoBuf:{0}", wkDiffs3.Count());

        }

        private static void AddRow(DataTable dt, int i)
        {

            var dr = dt.NewRow();
            dr["NO"] = i;
            dr["NAME"] = "NAME:" + i.ToString();
            dr["COL1"] = MD5(i);
            dr["COL2"] = MD5(i * 2);
            dr["COL3"] = MD5(i * 3);
            dr["COL4"] = MD5(i * 4);
            dr["COL5"] = MD5(i * 5);
            dr["COL6"] = MD5(i * 6);
            dr["COL7"] = System.DBNull.Value;
            dt.Rows.Add(dr);

        }

        private static string MD5(int i)
        {
            return System.Convert.ToBase64String(new System.Security.Cryptography.MD5CryptoServiceProvider().ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(i.ToString())));
        }
    }
}

結果

1回目が遅いですね。JIT(Just-In-Time)によって、2回目以降早くなっているんでしょうか。

レコード件数 XML.Serialize File Size ProtoBuf File Size XML.Serialize ProtoBuf.Serialize XML.Deserialize ProtoBuf.Deserialize
1 1,909 258 65ms 32ms 18ms 14ms
11 6,112 1,938 2ms 1ms 2ms 1ms
111 48,515 18,828 2ms 1ms 2ms 1ms
1,111 476,518 189,590 10ms 4ms 23ms 4ms
11,111 4,796,521 1,908,352 105ms 29ms 102ms 82ms
111,111 48,396,524 19,280,730 851ms 275ms 834ms 835ms
1,111,111 488,396,527 194,153,108 9,106ms 3,085ms 11,941ms 8,853ms

結果(コンソール出力)

Count:1
XML.Serialize:65ms
File Size:1,909 byte
XML.Deserialize:18ms
ProtoBuf.Serialize:32ms
File Size:258 byte
ProtoBuf.Deserialize:14ms
Difference between original and XmlSerializer:0
Difference between original and ProtoBuf:0
Count:11
XML.Serialize:2ms
File Size:6,112 byte
XML.Deserialize:2ms
ProtoBuf.Serialize:1ms
File Size:1,938 byte
ProtoBuf.Deserialize:1ms
Difference between original and XmlSerializer:0
Difference between original and ProtoBuf:0
Count:111
XML.Serialize:2ms
File Size:48,515 byte
XML.Deserialize:1ms
ProtoBuf.Serialize:1ms
File Size:18,828 byte
ProtoBuf.Deserialize:2ms
Difference between original and XmlSerializer:0
Difference between original and ProtoBuf:0
Count:1,111
XML.Serialize:10ms
File Size:476,518 byte
XML.Deserialize:23ms
ProtoBuf.Serialize:4ms
File Size:189,590 byte
ProtoBuf.Deserialize:4ms
Difference between original and XmlSerializer:0
Difference between original and ProtoBuf:0
Count:11,111
XML.Serialize:105ms
File Size:4,796,521 byte
XML.Deserialize:102ms
ProtoBuf.Serialize:29ms
File Size:1,908,352 byte
ProtoBuf.Deserialize:82ms
Difference between original and XmlSerializer:0
Difference between original and ProtoBuf:0
Count:111,111
XML.Serialize:851ms
File Size:48,396,524 byte
XML.Deserialize:834ms
ProtoBuf.Serialize:275ms
File Size:19,280,730 byte
ProtoBuf.Deserialize:835ms
Difference between original and XmlSerializer:0
Difference between original and ProtoBuf:0
Count:1,111,111
XML.Serialize:9,106ms
File Size:488,396,527 byte
XML.Deserialize:11,941ms
ProtoBuf.Serialize:3,085ms
File Size:194,153,108 byte
ProtoBuf.Deserialize:8,853ms
Difference between original and XmlSerializer:0
Difference between original and ProtoBuf:0

参考

C# (dotnetcore) 異体字セレクタ(辻辻󠄀)、サロゲートペア文字(𠀋)、絵文字(💡)を扱ってみる。(Visual Studio for Mac環境)

日本語文字ってややこしいです。

「💡辻辻󠄀𠀋」なんて文字をc#で扱ってみました。

lengthが正しい文字数でないことをご確認ください。

Visual Studio for Mac環境だと文字化け

辻󠄀が文字化け

f:id:mitsugi-bb:20200915235117p:plain

Visual Studio Codeは惜しい

辻と辻󠄀の違いが分からない。

f:id:mitsugi-bb:20200915235250p:plain

ソース

using System;

namespace StringExample
{
    class Program
    {
        static void Main(string[] args)
        {
            String str1 = "test";
            Console.WriteLine(str1);
            Console.WriteLine(str1.Length);
            Console.WriteLine(str1.LengthInTextElements());

            String str2 = "日本語";
            Console.WriteLine("string:" + str2);
            Console.WriteLine("Length:" + str2.Length);
            Console.WriteLine("LengthInTextElements" + str2.LengthInTextElements());

            string str3 = "💡";
            Console.WriteLine("string:" + str3);
            Console.WriteLine("Length:" + str3.Length);
            Console.WriteLine("LengthInTextElements:" + str3.LengthInTextElements());

            string str4 = "辻";
            Console.WriteLine("string:" + str4);
            Console.WriteLine("Length:" + str4.Length);
            Console.WriteLine("LengthInTextElements:" + str4.LengthInTextElements());

            string str5 = "辻󠄀";
            Console.WriteLine("string:" + str5);
            Console.WriteLine("Length:" + str5.Length);
            Console.WriteLine("LengthInTextElements:" + str5.LengthInTextElements());

            string str6 = "𠀋";
            Console.WriteLine("string:" + str6);
            Console.WriteLine("Length:" + str6.Length);
            Console.WriteLine("LengthInTextElements:" + str6.LengthInTextElements());

        }
    }

    static class StringExtention
    {
        public static int LengthInTextElements(this string str)
        {
            return (new System.Globalization.StringInfo(str)).LengthInTextElements;
        }
    }
}

結果

コンソールには、異体字セレクタ(辻辻󠄀)、サロゲートペア文字(𠀋)、絵文字(💡)が正しく表示されている

f:id:mitsugi-bb:20200915234901p:plain
コンソールには正しく表示される

参考

サロゲートペア文字

ja.wikipedia.org

qiita.com

qiita.com

異体字セレクタ

ja.wikipedia.org

【改善】C# (dotnetcore) CSVファイルを永続化に利用したコンソールアプリを改善

本エントリは以下の解答をもう一歩改善した内容

mitsugeek.net

前回の、「カンマを含められない」、「Main関数の行数が多い」を改善。

解答(ソース)

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using CsvHelper;
using CsvHelper.Configuration;

namespace csvExample
{
    /// <summary>
    /// 行オブジェクト
    /// </summary>
    internal class CsvRow
    {
        public string name { get; set; }
        public string telNo { get; set; }
    }

    /// <summary>
    /// CSVと行オブジェクトのマッピング
    /// </summary>
    internal class CsvTable : ClassMap<CsvRow>
    {
        private CsvTable()
        {
            Map(c => c.name).Index(0);//0番目
            Map(c => c.telNo).Index(1);//1番目
        }
    }


    class Program
    {
        //メモリ上の住所録データ
        private static List<CsvRow> Rows = new List<CsvRow>();

        //CSVファイルのパス
        private const string CSV_PATH = @"data.csv";

        static void Main(string[] args)
        {
            //CSVファイルを読み込む
            ReadCsv();

            while (true) {
                //コマンドの一覧を表示
                Console.WriteLine("Command:list or add or init or exit");

                //コマンドの入力を求める
                string command = Console.ReadLine();

                if(command == "list") List();
                else if(command == "add") Add();
                else if(command == "init") Init();
                else if (command == "exit") break;
            }
        }

        /// <summary>
        /// 一覧表示
        /// </summary>
        static void List()
        {
            foreach (var row in Rows)
            {
                //メモリ上の内容を表示
                Console.Write("name:[");
                Console.Write(row.name);
                Console.Write("] telno:[");
                Console.Write(row.telNo);
                Console.WriteLine("]");
            }
        }

        /// <summary>
        /// 追加
        /// </summary>
        static void Add()
        {
            //追加の場合

            //追加する内容の読み込み
            Console.WriteLine("name?");
            string name = Console.ReadLine();
            Console.WriteLine("telno?");
            string telno = Console.ReadLine();

            //メモリに追加
            Rows.Add(new CsvRow() { name = name, telNo = telno });

            //ファイルに書き込む
            WriteCsv();
        }

        /// <summary>
        /// 初期化
        /// </summary>
        static void Init()
        {

            //初期化の場合
            if (System.IO.File.Exists(CSV_PATH))
            {
                System.IO.File.Delete(CSV_PATH);
                Rows = new List<CsvRow>();
            }
        }

        /// <summary>
        /// CSV書き込み
        /// </summary>
        static void WriteCsv()
        {
            using (var writer = new StreamWriter(CSV_PATH))
            using (var csv = new CsvWriter(writer, CultureInfo.CurrentCulture))
            {
                csv.Configuration.HasHeaderRecord = false;
                csv.Configuration.RegisterClassMap<CsvTable>();
                csv.WriteRecords(Rows);
            }
        }

        /// <summary>
        /// CSV読み込み
        /// </summary>
        static void ReadCsv()
        {
            //ファイルが無い場合は何もしない
            if (!System.IO.File.Exists(CSV_PATH)) return;

            using (var reader = new StreamReader(CSV_PATH))
            using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
            {
                csv.Configuration.HasHeaderRecord = false;
                csv.Configuration.RegisterClassMap<CsvTable>();
                Rows.AddRange(csv.GetRecords<CsvRow>());
            }
        }
    }
}

各項目の解説

ここでの項目は、プロパティやメソッドのことを表しています。 それぞれ、以下のような役割があります。

項目 説明
CsvRow csvの項目を指定したPOCO(Plain Old CLR Object )
CsvTable csvの項目とクラスの項目のマッピング
Rows CSVから読み込んだデータを保持する領域。データを追加した場合、ここに追加される
CSV_PATH CSVファイルのパス
Main プログラムのエントリポイント。
初期処理で、ReadCSVを実行し、
その後はlist、add、init、exitのコマンドを受け付け、各コマンドに合わせた処理を行っている
List 一覧表示処理
Add 項目追加処理
Init データ初期化処理
WriteCsv Rowsの内容をCSVファイルに保存する関数
ReadCsv CSVファイルを読み込み、内容をRowsに設定する関数

【解答】C# (dotnetcore) CSVファイルを永続化に利用したコンソールアプリの作成

本エントリは、以下のエントリに対する解答の1つです。

mitsugeek.net

解答(ソース)

以下が回答となります。このプログラムには、改善ポイント(課題)があります。

using System;
using System.Collections.Generic;

namespace csvExample
{
    class Program
    {
        //メモリ上の住所録データ
        private static List<string[]> Rows = new List<string[]>();

        //CSVファイルのパス
        private const string CSV_PATH = @"data.csv";

        static void Main(string[] args)
        {
            //CSVファイルを読み込む
            ReadCsv();

            while (true) {
                //コマンドの一覧を表示
                Console.WriteLine("Command:list or add or init or exit");

                //コマンドの入力を求める
                string command = Console.ReadLine();

                if(command == "list")
                {
                    //一覧表示の場合
                    foreach(var row in Rows)
                    {
                        //メモリ上の内容を表示
                        Console.Write("name:[");
                        Console.Write(row[0]);
                        Console.Write("] telno:[");
                        Console.Write(row[1]);
                        Console.WriteLine("]");
                    }
                }
                else if(command == "add")
                {
                    //追加の場合

                    //追加する内容の読み込み
                    Console.WriteLine("name?");
                    string name = Console.ReadLine();
                    Console.WriteLine("telno?");
                    string telno = Console.ReadLine();

                    //メモリに追加
                    Rows.Add(new string[] { name, telno });

                    //ファイルに書き込む
                    WriteCsv();

                }
                else if(command == "init")
                {
                    //初期化の場合
                    if (System.IO.File.Exists(CSV_PATH))
                    {
                        System.IO.File.Delete(CSV_PATH);
                        Rows = new List<string[]>();
                    }
                }
                else if (command == "exit")
                {
                    //終了の場合
                    break;
                }
            }
            

        }

        //CSV書き込み
        static void WriteCsv()
        {
            //ファイルを書き込む
            using (var writer = new System.IO.StreamWriter(CSV_PATH))
            {
                //現在の内容を回す
                foreach (var row in Rows)
                {
                    //1行ずつ書き込む(項目をカンマ区切りでつなげる)
                    writer.WriteLine(String.Join(",", row));
                }
            }
        }

        //CSV読み込み
        static void ReadCsv()
        {
            //ファイルが無い場合は何もしない
            if (!System.IO.File.Exists(CSV_PATH)) return;

            //ファイルがある場合、読み込む
            using (var reader = new System.IO.StreamReader(CSV_PATH))
            {
                //1行ずつ読み込む
                string line;
                while((line = reader.ReadLine()) != null)
                {
                    //カンマ区切りを分解
                    Rows.Add(line.Split(","));
                }
            }
        }
    }
}

各項目の解説

ここでの項目は、プロパティやメソッドのことを表しています。 それぞれ、以下のような役割があります。

項目 説明
Rows CSVから読み込んだデータを保持する領域。データを追加した場合、ここに追加される
CSV_PATH CSVファイルのパス
Main プログラムのエントリポイント。
初期処理で、ReadCSVを実行し、
その後はlist、add、init、exitのコマンドを受け付け、各コマンドに合わせた処理を行っている
WriteCsv Rowsの内容をCSVファイルに保存する関数
ReadCsv CSVファイルを読み込み、内容をRowsに設定する関数

プログラム上の課題

カンマを含められない

nameや、telnoにカンマを含められません。 このプログラムでカンマを入力することは想定されていませんが、 できれば、CSVの標準的な保存、読み込みとしたいところです。

Main関数の行数が多い

もう少し分割したいところですね。

コマンド毎に関数に分けるっていうアプローチが良さそうですね。

Dictionary<string, Action >というアプローチもありかもしれません。

ファイルの行数に伴いレスポンスが悪化する

保存する毎に、ファイルを作り直しているため、レコード数が増えると遅くなっていく設計となっている。

追加しか行わないなら、追記というアプローチを行うべき。

ファイルの場合、固定長とすることで、部分編集、レコードの削除等も高速にできそう。

今風の作りにする場合は、データベースを利用するという事になる。

この場合はSQLiteが良さそう。

RDBMSが今風というのは少し違う気もするが・・・

BerkeleyDBとか・・・

発展のアプローチ

本プログラムの発展を考えたアプローチとして、以下のようなことができれば便利そう。

コマンドライン引数を使った操作ができれば便利かもしれない

コマンドライン引数で、list、add、initを操作できれば、以下のように、パイプやリダイレクトを利用した、他プログラムとの連携も可能となる。

dotnet csvExample.dll list > data.txt

改善エントリ追加しました。

mitsugeek.net

【課題】C# (dotnetcore) CSVファイルを永続化に利用したコンソールアプリの作成

本エントリは、以下のようなコンソールアプリで、データの保存にCSVを使うというプログラミングの課題です。

f:id:mitsugi-bb:20200912231707g:plain

仕様

起動時に永続化したデータを読み込み、以下のコマンドを受け付ける

exitを選ぶまで、説明→コマンド→説明→コマンドの繰り返し(無限ループ)

CSVファイルは単純なカンマ区切りで良いものとする。 (名前と電話番号を登録する仕組みなので、改行やカンマが含まれることは無いため、単純なカンマ区切りで良い)

コマンド 説明
list 登録したデータの一覧表示
add 追加モード(名前と電話番号を登録)
init 初期化
exit 終了

動作の流れ

  1. 起動時に、CSVファイルを読み込み、メモリに退避
  2. 無限ループ
    1. コマンドの説明を表示
    2. コマンドを読み込む
    3. listの場合
      1. メモリ領域の内容を表示
    4. addの場合
      1. 追加項目を入力してもらう
      2. メモリに内容を追加
      3. メモリの内容をファイルに書き込む
    5. initの場合
      1. ファイルの削除
    6. exitの場合
      1. プログラム終了

利用する部品

  • while (true) {} (無限ループ)
  • Console.WriteLine
  • Console.ReadLine
  • System.IO.StreamReader
  • System.IO.StreamWriter
  • String.Join メソッド
  • String.Split メソッド

解答

mitsugeek.net

C# (dotnetcore) int型の最大値、最小値を超えるとどうなるか

早速実行

using System;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {

            int i = int.MinValue;
            Console.WriteLine(i);
            --i;
            Console.WriteLine(i);
            ++i;
            Console.WriteLine(i);

        }
    }
}

結果

-2147483648
2147483647
-2147483648

C# (dotnetcore) Docker コンテナで実行するコンソールアプリケーションのチュートリアルを実施してみた

このエントリは、個人的にメモをまとめたものになります。 個人的なチュートリアルの補助的役割です。

実施したチュートリアル

docs.microsoft.com

事前の準備

Docker Desktop on Macをインストール

docs.docker.jp

インストールが成功すると、Dockerコマンドが利用できるようになります。

f:id:mitsugi-bb:20200909233926p:plain
docker --version

準備完了

これでチュートリアルを進めていきます。

docs.microsoft.com

実際チュートリアルを進めるところは記事にしません。 リンク先を参照ください。

プログラムを書き換えた際に再度実行して確認する流れ

(1) コンパイル

dotnet publish -c Release   

(2) dockerイメージのビルド

docker build -t <container image name> -f Dockerfile .

(3) コンテナの実行

docker run -it --rm <container image name>

感想

これだけいろんなOS、ミドルウェア、アプリケーション、プログラミング言語、ライブラリ、パッケージ等がどんどん複雑化されていく中で、 アプリケーションをコンテナ化するということは、1つ抽象化することに貢献してくれるのだろう。

抽象化されることによって、複雑なアプリケーションを認識しやすいようにしてくれる。

メモ

コンテナイメージの作成

docker build -t <container image name> -f Dockerfile .

コンテナイメージの一覧

docker images

コンテナの作成

docker create --name <container name> <container image name>

コンテナ一覧の確認

docker ps -a

コンテナのstart

docker start <container name>

コンテナのstop

docker stop <container name>

コンテナへ接続

--sig-proxy=falseを付与すると、Ctrl+c押下時に、コンテナに対して、SIGINTが送信されなくなる

docker attach --sig-proxy=false <container name>

コンテナの削除

docker rm <container name>

コンテナの起動、実行、終了

docker run -it --rm <container image name>

コンテナ内のアプリに対して、引数を渡すこともできる。

docker run -it --rm <container image name> 引数

ENTRYPOINT をbashに変更して起動

docker run -it --rm --entrypoint "bash" <container image name>

dockerイメージの削除

docker rmi <container image name>:<tag name>

C# (dotnetcore) 暗黙的な型指定(var)を利用する際の指針

参考書籍

独習C# 新版

独習C# 新版

参考書籍に、「暗黙的な型指定(var)」の使い所が書かれていたので、自分なりに調べてまとめておく。

Q:結局のところ、暗黙的な型指定(var)と明示的な型(2.3.3 項)と、いずれを利用すべきなので しょうか。使い分けのルールなどがあれば、教えてください。

A:マイクロソフトのドキュメントでは、以下のような指針が示されています。

[1] 変数の型が右辺から明らかである場合、または厳密な型が重要でない場合は、暗黙の型指定を使用します。

[2] 右辺から型が明らかではない場合、var を使用しないでください。

[3] 型を指定する際に変数名に頼らないでください。変数名が正しくない場合があります。

[4] dynamic(11.3 節)の代わりに var を使用しないでください。

[5] for / foreach(4.2.3 項)のカウンター変数では、暗黙の型指定を使用します。

マイクロソフトのドキュメントを探す。

ドキュメントみっけ。

docs.microsoft.com

以下ドキュメントの引用と、参考書籍の番号を合わせてみる。

[1] 変数の型が割り当ての右側から明らかである場合、または厳密な型が重要でない場合は、ローカル変数の暗黙の型指定を使用します。

[2] 割り当ての右側から型が明らかではない場合、var を使用しないでください。

[3] 変数の型を指定するときに変数名に頼らないでください。 変数名が正しくない場合があります。

[4] dynamic の代わりに var を使用しないようにしてください。

[5] for ループでループ変数の型を決定するときは、暗黙の型指定が使用されます。

[5] foreach ループでループ変数の型を決定するときは、暗黙の型指定は使用されません。

[5]が少し怪しいが、ほぼほぼこのことを仰られているのでしょう。

英語のドキュメントをGoogle翻訳にかけてみる。

「Do not use implicit typing to determine the type of the loop variable in foreach loops.」

f:id:mitsugi-bb:20200908223635p:plain
Google翻訳の結果

というわけで、この指針がvarの使い所。

dynamic に対するサンプルコードが無いので書いてみる。

Microsoftのドキュメントには、dynamicに関するサンプルがなかったので、 参考書籍のp.557にあるIronPythonを参考にメモっておく。

このコードの実行には、NuGetでIronPythonを追加する必要がある。

        static void Main(string[] args)
        {
            var py = IronPython.Hosting.Python.CreateRuntime();

            using(var sw = new System.IO.StreamWriter("test.py"))
            {
                sw.Write($@"
class ExampleClass:
  def greet(self, name):
    return ""Hello "" + name + "" !""
");
            }

            dynamic script = py.UseFile("test.py");
            dynamic example = script.ExampleClass();
            Console.WriteLine(example.greet("mitsugeek"));
        }

結果

Hello mitsugeek !