手动添加djvu电子文档的书签

Vanabel/ 7月 3, 2015/ 互联网/ 5 comments

这里将介绍如何快速的手动添加djvu电子书的书签.

  • 准备书签数据:利用djvulibre可以很方便的导出目录页为pdf, 利用Acobat Adobe文字识别可以很方便的得到目录, 但是格式不太标准. 我们可以利用mma的替换功能标准化目录, 其代码如下:
    (*非目录项*)
    $precontent="Geometric Measure Theory ---- An Introduction.....1
    Series Preface.......3
    Introduction.......5
    Acknowledgements.......9
    Contents.......11";
    $firstpagenumber=13;
    (*pdf导出的目录*)
    $contentsall="从pdf文件把目录内容复制粘贴进来";
    (*处理非标准目录, 我定义了一些规则, 你可以自己添加*)
    sametostop[ini_?StringQ,beg_?StringQ,end_?StringQ]:=Module[{i=1,tini=ini,tbeg=beg,tend=end,temp},
    While[
    tbeg!=tend&& i<= 100,
    temp=StringReplace[tbeg,RegularExpression["[\"\[Bullet]]"]->"."];
    temp=StringReplace[temp,RegularExpression["[\r\n]\\.\\s*\\."]->"."];
    temp=StringReplace[temp,RegularExpression["[a-zA-Z]+\\s*[\r\n][a-zA-Z]+"]->"."];
    temp=StringReplace[temp,"\[CenterDot]"->"."];
    temp=StringReplace[temp,".."-> ". . "];
    temp=StringReplace[temp,RegularExpression["(\\d\\.)\\s+(\\d)"]->"$1"~~"$2"];
    i++;
    tend=tbeg;
    tbeg=temp;
    ]
    tend]
    (*输出为标准的djvu能够识别的格式*)
    reformart[sec_?StringQ, con_?StringQ, pgnum_?StringQ] := 
     Module[{len = Length[StringCases[sec, "."]], pref = "(", suff = ")", 
       midd = " \"" ~~ sec ~~ " " ~~ con ~~ "\" \"#" ~~ pgnum ~~ "\""},
      Switch[len,
       0, pref ~~ midd ~~ suff,
       1, pref ~~ midd ~~ suff,
       2, pref ~~ midd ~~ suff,
       3, pref ~~ midd ~~ suff
       ]
      ]
    (*最终的目录数据, 可以直接被djvused处理*)
    $sectionprecontent=StringCases[$precontent,RegularExpression["([a-zA-Z]+)\\.+(\\d+)"]:>  reformart["","$1",ToString[ToExpression["$2"]]]]//ColumnForm
    $contentsall=sametostop[$contentsall,$contentsall,""]//ToString;
    $sectionlist=StringCases[
    $contentsall,RegularExpression["(.*?)((\\.\\s*){2,})(\\d+)[\\r\\n]*?"]:>  reformart["","$1",ToString[ToExpression["$4"]+$firstpagenumber-1]]];
    List["(bookmarks",$sectionprecontent,$sectionlist,")"]//Flatten//ColumnForm
  • 添加djvused的路径到系统, 首先搜索djvulibre安装路径下djvuused的路径, 然后采用类似命令添加到系统路径:path C:\Program Files (x86)\DjVuLibre;%path%
  • 利用djvused写入数据到文件:djvused linyang.djvu -v -e "set-outline linyang.dsed" -s
    这里, linyang.djvu是djvu文件, 而上面通过mma得到的数据保存在linyang.dsed文本文档中, 我采用的是utf8格式.
Share this Post

5 Comments

  1. 这里, 输出格式如下:
    (bookmarks
    ( ” 封面” “#1″)
    ( ” 序言” “#3″)
    ( ” 目录 ” “#5″)
    ( ” 第一章. 引言” “#7″)
    ( ” 第二章. Riemann 度量” “#12″)
    ( ” 第三章. Levi-Civita 联络” “#15″)
    ( ” 第四章. 曲率张量” “#18″)
    ( ” 第五章. 测地线, 指数映照, 测地凸邻域” “#27″)
    ( ” 第六章. 完备性” “#36″)
    ( ” 第七章. Jacobi场与共轭点” “#42″)
    ( ” 第八章. 等距和全测地子流形” “#52″)
    ( ” 第九章. Cartan-Hadamard 定理” “#55″)
    ( ” 第十章. 空间形式” “#59″)
    ( ” 第十一章. 测地线的第二变分公式及其应用” “#69″)
    ( ” 第十二章. Morse 指标形式与 Morse 指标定理” “#78″)
    ( ” 第十三章. 割迹与单射半径” “#87″)
    ( ” 第十四章. 比较定理” “#93″)
    ( ” 第十五章. 体积和体积比较定理” “#113″)
    ( ” 附录. 完备性” “#125″)
    ( ” 索引” “#188″)
    ( ” 参考文献” “#192”)
    )

  2. 要导出书签, 只需执行
    djvused "filename.djvu" -e 'print-outline' > filename.dsed

  3. 你也可以添加如下脚本到~/.bash_aliases

    
    function djvu_print_outline(){
      if [ "$#" -ne 1 ]; then
        echo 'Please provide the djvu filename without .djvu'
        return
      else
        djvused $1.djvu -u -v -e print-outline > $1.dsed
      fi
    }
    
    function djvu_set_outline(){
      if [ "$#" -ne 1 ]; then
        echo 'Please provide the djvu filename without .djvu'
        return
      else
        djvused $1.djvu -v -e "set-outline $1.dsed" -s
      fi
    }
    
  4. 小节的话可以用这种结构:

    
    (bookmarks
     ('Section' '#1’
      ('Subsection' '#2')
      ('Subsection 2' '#3')
     )
     ('Section 2' '#4')
    )
    
  5. 如果用vim的话, 结合Ultsnip插件, 可以这样

    
    snippet () "new section" bA
    ("${1:section title}" "#${2:page number}")
    endsnippet
    

    此外, 利用vim的替换功能还可以实现自动增加页码(12)

    
    :%s/\#\zs\(\d\+\)\=/\=submatch(0)+12/gc
    

    当然, 你也可以用更强大的快捷键(AP), 添加如下代码到你的vimrc

    
    fu! Addpnum()
      call inputsave()
      let w:addedn = input("The number to be added to current page: \n", '')
      call inputrestore()
      if (w:addedn == '') 
        let w:addedn=0
      endif
      exec '%s/\#\zs\(\d\+\)\=/\=submatch(0)+' . w:addedn . '/gc'
    endfu 
    
    nnoremap AP :call Addpnum()
    

Leave a Comment

您的电子邮箱地址不会被公开。

*
*

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据