Mathematica export notebook into pdf files with table of contents and bookmarks
Mathematica
I have been using Mathemtica to write notes. It’s really convenient to use notebook files because we can write program, formular, figures and text in one file. However, not everyone uses Mathematica, If we want to share our notes with others, exporting nb files into pdf format is necessary.
In default, the generated pdf by Mathematica is relatively simple, and there is no TOC or bookmarks in the generated pdf files. It will be very inconvenient to read if the notes are very long. I have searched on stack exchange, but it seems that there is no existing good solution. According to the question, may be we can save the nb files into tex
format and then compile it into pdf, but (according to my experience) problem exists when the nb file is long and the formular is complicated.
Finally, I myself try to add bookmarks mannually. I use python to process the generated pdf files, what I want to realize can be summarized as follows:
- Using Mathematica: For a long notebook file, we directly generate the pdf files (
pdf file 1
) - Using Mathematica: Then I will extract the chapter/section information and generate a pdf file (
pdf file 2
) containing the table of contents (with suitable pdf page numbers) - Using Python:Finally, I will use python to merge the two pdfs into
pdf file 3
and add bookmarks into this merged pdf (pdf file 3
).
It seems that the above process is cumbersome, but it can be automated by the program, and the operation is very simple. I will show an example:
Assuming that the notebook file to be processed is test.nb
, then in Mathematica
(1) we just need run the following program to generate the helping files
1 | (*The notebook directory*) |
NOTES:
By runing above Mathematica program, two pdf files will be generated (
pdf file 1
,pdf file 2
). Extra txt file namestest.txt
is also generated. In this txt file, information about the TOC are saved.
(2)then we use the corresponding python program (see appendix II) to generate the final pdf files.
If you don’t want to install python, I have also written a program with simple GUI and compiled it into Exe format. This can be directly run on windows. Original code can be found on this
the final pdf files will have toc and bookmarks:
However, by using python, the original links in PDF will be lost, so you can’t jump into certain page by clicking the links, this is the problem of the python package PyPDF2
.
Appendix
the Mathematica function
modefied from the question1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52*helper file for creating cell*)
createCell[text_,tag_,level_]:=Cell[BoxData[TagBox[GridBox[{{"",text,CounterBox["Page",{bookUrl,tag}]}},GridBoxAlignment->{"Columns"->{Left,Left,Right}},GridBoxItemSize->{"Columns"->{2 level-1,35-2 level,5}}],"Grid"]],"Text",FontColor->Blue];
(*helper file for creating cell version II*)
createCellPy[text_,tag_,level_]:=Cell[BoxData[TagBox[GridBox[{{"",text,";",level,";",CounterBox["Page",{bookUrl,tag}],";"}},GridBoxAlignment->{"Columns"->{Left,Left,Left,Left,Right}},GridBoxItemSize->{"Columns"->{2 level-1,35-2 level,5}}],"Grid"]],"Text"];
GenTOCtoPDFTZH[fileDir_,fileNb_]:=Block[{typeList,filepdf,filepdfToc,filetxt,bookUrl,tocPDF,tocPy,book,fexp},
typeList={"Section","Subsection"};
filepdf=StringReplace[fileNb,".nb"->".pdf"];
filepdfToc=StringReplace[fileNb,".nb"->"Toc.pdf"];
filetxt=StringReplace[fileNb,".nb"->".txt"];
bookUrl=FileNameJoin[{fileDir,fileNb}];
SetDirectory[fileDir];
tocPDF=CreateDocument[];
SelectionMove[tocPDF,Before,Notebook];
NotebookWrite[tocPDF,Cell["目录","Text",20,Blue]];
tocPy=CreateDocument[];
book=NotebookOpen[bookUrl];
SetOptions[book,ShowPageBreaks->True];
(*iterate over cells to set tags and write lines to TOC*)
Scan[(counter[#]=0)&,typeList];
SelectionMove[book,Before,Notebook];
SelectionMove[book,Next,Cell];
While[(cell=NotebookRead[book])=!={},If[Length[cell]>=2,type=cell[[2]];
If[MemberQ[typeList,type],counter[type]+=1;
tag=type<>ToString[counter[type]];
SetOptions[NotebookSelection[book],CellTags->Union[Flatten[{Options[NotebookSelection[book],CellTags][[1,2]],tag}]]];
SelectionMove[book,All,CellContents];
NotebookWrite[tocPDF,createCell[NotebookRead[book],tag,Position[typeList,type][[1,1]]]];
NotebookWrite[tocPy,createCellPy[NotebookRead[book],tag,Position[typeList,type][[1,1]]]]];];
SelectionMove[book,Next,Cell]];
(*存储为txt文件*)
fexp=FileNameJoin[{fileDir,filetxt}];
FrontEndExecute[FrontEndToken[tocPy,"Save",{fexp,"Text"}]];
(*存储笔记本文件为pdf文件供Python使用*)
fexp=FileNameJoin[{fileDir,filepdf}];
Export[fexp,book];
(*存储目录文件为pdf文件供Python使用*)
fexp=FileNameJoin[{fileDir,filepdfToc}];
Export[fexp,tocPDF];
(*关闭所有*)
NotebookClose[book];
NotebookClose[tocPDF];
NotebookClose[tocPy];]
(*(*复制目录到目标笔记本*)
SelectionMove[tocPDF,All,Notebook];
data=NotebookRead[tocPDF];
SelectionMove[book,Before,Notebook];
NotebookWrite[book,Cell["目录","Text",20,Blue]];
NotebookWrite[book,NotebookRead[tocPDF]];*)
(*存储为txt文件供Python使用*)
Python program to generate TOC
1 | # we set the file name to be processed |