Open3

dorper開発メモ

togatogatogatoga

課題

zennのscrapsで読書記録をつけるようになった、体験としては素晴らしいがいくつか不満点がある。

  • プライベートなscrapが作成できない
    • 読書メモなど本の内容を過度に公開してしまうのは著作権的に怪しい
  • preview機能がない
    • 数式を書いてる最中は正しくレンダリングされているか確認したい
      • 動作的にはQiitaの機能

なので趣味も兼ねて自作で作ることにした。自分が欲しい物なので技術書のメモ書きするために特化したものにしたい。

まずやること

  • privateなメモ作成
  • 技術書のpdfから目次の抽出とmarkdownのtemplate作成
  • 何ページ読んだかの管理
  • 蔵書の管理
  • 技術書の検索・登録

アイディア・妄想

  • グループ機能・編集
  • 分からない箇所についてユーザーが質問を投稿できる
  • ユーザーがmarkdownのテンプレートを投稿
  • 同じ本を読んでる他のユーザー記事を閲覧
  • 輪読会の参加募集機能
togatogatogatoga

Online Markdown エディター

やること

一旦習作でアプリを作ったほうが良い。特にディレクトリの構成など完全に手探り状態

togatogatogatoga

PDF/epubから目次(Table of content)やメタ情報(出版日、タイトル、著者)を抽出

バックエンド側で抽出も考えたがpdfみたいな大きなファイルはフロントエンド側で処理すべき

参考になりそうなサイト

<outlines>
<outline level="1" title="表紙">
<dest><list size="2">
<ref id="4863" />
<literal>Fit</literal>
</list></dest>
<pageno>1</pageno>
</outline>
<outline level="1" title="権利表記">
<dest><list size="2">
<ref id="1" />
<literal>Fit</literal>
</list></dest>
<pageno>2</pageno>
</outline>
<outline level="1" title="原書大扉">
<dest><list size="2">
<ref id="3" />
<literal>Fit</literal>
</list></dest>
<pageno>3</pageno>
</outline>
<outline level="1" title="クレジット">
<dest><list size="2">
<ref id="10" />
<literal>Fit</literal>
</list></dest>
<pageno>4</pageno>
</outline>
<outline level="1" title="本書への称賛の声">
<dest><list size="2">
<ref id="12" />
<literal>Fit</literal>
</list></dest>
<pageno>5</pageno>
</outline>
<outline level="1" title="監訳者まえがき">
<dest><list size="2">
<ref id="21" />
<literal>Fit</literal>
</list></dest>
<pageno>9</pageno>
</outline>
<outline level="1" title="はじめに">
<dest><list size="2">
<ref id="35" />
<literal>Fit</literal>
</list></dest>
<pageno>15</pageno>
</outline>
<outline level="1" title="目次">
<dest><list size="2">
<ref id="65" />
<literal>Fit</literal>
</list></dest>
<pageno>25</pageno>
</outline>
<outline level="1" title="I部 データベース論理設計のアンチパターン ">
<dest><list size="2">
<ref id="100" />
<literal>Fit</literal>
</list></dest>
<pageno>37</pageno>
</outline>
<outline level="2" title="1章 ジェイウォーク(信号無視)">
<dest><list size="2">
<ref id="105" />
<literal>Fit</literal>
</list></dest>
<pageno>39</pageno>
</outline>
<outline level="3" title="1.1 目的:複数の値を持つ属性を格納する ">
<dest><list size="2">
<ref id="111" />
<literal>Fit</literal>
</list></dest>
<pageno>40</pageno>
</outline>
<outline level="3" title="1.2 アンチパターン:カンマ区切りフォーマットのリストを格納する ">
<dest><list size="2">
<ref id="111" />
<literal>Fit</literal>
</list></dest>
<pageno>40</pageno>
</outline>
<outline level="4" title="1.2.1 特定のアカウントに関連する製品の検索 ">
<dest><list size="2">
<ref id="113" />
<literal>Fit</literal>
</list></dest>
<pageno>41</pageno>
</outline>
<outline level="4" title="1.2.2 特定の製品に関連するアカウントの検索 ">
<dest><list size="2">
<ref id="113" />
<literal>Fit</literal>
</list></dest>
<pageno>41</pageno>
</outline>
<outline level="4" title="1.2.3 集約クエリの作成 ">
<dest><list size="2">
<ref id="113" />
<literal>Fit</literal>
</list></dest>
<pageno>41</pageno>
</outline>
<outline level="4" title="1.2.4 特定の製品に関連するアカウントの更新 ">
<dest><list size="2">
<ref id="115" />
<literal>Fit</literal>
</list></dest>
<pageno>42</pageno>
</outline>
<outline level="4" title="1.2.5 製品IDの妥当性検証 ">
<dest><list size="2">
<ref id="117" />
<literal>Fit</literal>
</list></dest>
<pageno>43</pageno>
</outline>
<outline level="4" title="1.2.6 区切り文字の選択 ">
<dest><list size="2">
<ref id="117" />
<literal>Fit</literal>
</list></dest>
<pageno>43</pageno>
</outline>
<outline level="4" title="1.2.7 リストの長さの制限 ">
<dest><list size="2">
<ref id="117" />
<literal>Fit</literal>
</list></dest>
<pageno>43</pageno>
</outline>
<outline level="3" title="1.3 アンチパターンの見つけ方 ">
<dest><list size="2">
<ref id="117" />
<literal>Fit</literal>
</list></dest>
<pageno>43</pageno>
</outline>
<outline level="3" title="1.4 アンチパターンを用いてもよい場合 ">
<dest><list size="2">
<ref id="119" />
<literal>Fit</literal>
</list></dest>
<pageno>44</pageno>
</outline>
<outline level="3" title="1.5 解決策:交差テーブルを作成する ">
<dest><list size="2">
<ref id="119" />
<literal>Fit</literal>
</list></dest>
<pageno>44</pageno>
</outline>
<outline level="4" title="1.5.1 特定のアカウントに関連する製品の検索/特定の製品に関連するアカウントの検索 ">
<dest><list size="2">
<ref id="121" />
<literal>Fit</literal>
</list></dest>
<pageno>45</pageno>
</outline>
<outline level="4" title="1.5.2 集約クエリの作成 ">
<dest><list size="2">
<ref id="121" />
<literal>Fit</literal>
</list></dest>
<pageno>45</pageno>
</outline>
<outline level="4" title="1.5.3 製品の連絡先の更新 ">
<dest><list size="2">
<ref id="126" />
<literal>Fit</literal>
</list></dest>
<pageno>46</pageno>
</outline>
<outline level="4" title="1.5.4 製品IDの妥当性検証 ">
<dest><list size="2">
<ref id="126" />
<literal>Fit</literal>
</list></dest>
<pageno>46</pageno>
</outline>
<outline level="4" title="1.5.5 区切り文字の選択 ">
<dest><list size="2">
<ref id="128" />
<literal>Fit</literal>
</list></dest>
<pageno>47</pageno>
</outline>
<outline level="4" title="1.5.6 リストの長さの制限 ">
<dest><list size="2">
<ref id="128" />
<literal>Fit</literal>
</list></dest>
<pageno>47</pageno>
</outline>
<outline level="4" title="1.5.7 交差テーブルの他のメリット ">
<dest><list size="2">
<ref id="128" />
<literal>Fit</literal>
</list></dest>
<pageno>47</pageno>
</outline>
<outline level="2" title="2章 ナイーブツリー(素朴な木)">
<dest><list size="2">
<ref id="132" />
<literal>Fit</literal>
</list></dest>
<pageno>49</pageno>
</outline>
<outline level="3" title="2.1 目的:階層構造を格納し、クエリを実行する ">
<dest><list size="2">
<ref id="136" />
<literal>Fit</literal>
</list></dest>
<pageno>50</pageno>
</outline>
<outline level="3" title="2.2 アンチパターン:常に親のみに依存する ">
<dest><list size="2">
<ref id="136" />
<literal>Fit</literal>
</list></dest>
<pageno>50</pageno>
</outline>

dumppdf.pyの目次抽出のコード

コード

  • 'Outlines'を抜き出してる
  • Title, Dest, A(action), SEを抜き出してる。詳細は不明
  • First, Lastを抜き出して再帰的に呼び出してる
    • おそらく1章の中での1.1章の部分?
  • 'Next'を抜き出して再帰的に呼び出してる