summaryrefslogtreecommitdiff
path: root/macros/luatex/optex/outlines.opm
blob: a66c3161294fcdd815308c523766491f91a4f443 (plain)
1
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
%% This is part of OpTeX project, see http://petr.olsak.net/optex

\_codedecl \outlines {PDF outlines <2020-03-12>} % preloaded in format

\_def\_outlines#1{\_pdfcatalog{/PageMode/UseOutlines}\_openref
   \_ifx\_toclist\_empty
     \_opwarning{\noexpand\outlines -- data unavailable. TeX me again}%
   \_else
     \_ifx\_dest\_destactive \_else
        \opwarning{\_noexpand\outlines doesn't work when \_noexpand\hyperlinks isn't declared}\_fi
     {\_let\_tocline=\_outlinesA
      \_count0=0 \_count1=0 \_count2=0 \_count3=0 \_toclist % calculate numbers o childs
      \_def\_outlinelevel{#1}\_let\_tocline=\_outlinesB
      \_tocrefnum=0 \_count0=0 \_count1=0 \_count2=0 \_count3=0 
      \_toclist}% create outlines
   \_fi
}
\_def\_outlinesA#1#2#3#4#5#6{%
   \_advance\_count#1 by1
   \_ifcase#1\_or
      \_addoneol{_ol:\_the\_count0}\_or
      \_addoneol{_ol:\_the\_count0:\_the\_count1}\_or
      \_addoneol{_ol:\_the\_count0:\_the\_count1:\_the\_count2}\_or
      \_addoneol{_ol:\_the\_count0:\_the\_count1:\_the\_count2:\_the\_count3}\_fi
}
\_def\_addoneol#1{%
   \_ifcsname #1\_endcsname
           \_tmpnum=\_csname#1\_endcsname\_relax
           \_advance\_tmpnum by1 \_sxdef{#1}{\_the\_tmpnum}%
   \_else \_sxdef{#1}{1}%
   \_fi
}
\_def\_outlinesB#1#2#3#4#5#6{%
   \_advance\_count#1 by1
   \_ifcase#1%
      \_tmpnum=\_trycs{_ol:\_the\_count0}{0}\_or
      \_tmpnum=\_trycs{_ol:\_the\_count0:\_the\_count1}{0}\_relax\_or
      \_tmpnum=\_trycs{_ol:\_the\_count0:\_the\_count1:\_the\_count2}{0}\_relax\_or
      \_tmpnum=\_trycs{_ol:\_the\_count0:\_the\_count1:\_the\_count2:\_the\_count3}{0}\_relax\_or
      \_tmpnum = 0\_relax\_fi
   \_pdfunidef\_tmp{#4}%
   \_advance\_tocrefnum by1
   \_outlinesC{#1}{toc:\_the\_tocrefnum}{\_ifnum#1<\_outlinelevel\_space\_else-\_fi}{\_tmpnum}{\_tmp}%
}
\_def\_outlinesC#1#2#3#4#5{\_pdfoutline goto name{#2} count #3#4{#5}\_relax}

\_newcount\_oulnum
\_def\_insertoutline#1{\_global\_advance\_oulnum by1
   \_pdfdest name{oul:\_the\_oulnum} xyz\_relax
   \_pdfunidef\_tmp{#1}%
   \_pdfoutline goto name{oul:\_the\_oulnum} count0 {\_tmp}\_relax
}
\_public \outlines \insertoutline ;

\_endcode % ----------------------------

The problem is that PDF format needs to know the number of direct
descendants of each outline if we need to create the tree of structured
outlines. But we know only the level of each outline. The required data
should be calculated from TOC data. We use two steps over TOC data saved in
the `\_toclist` where each record is represented by one `\_tocline`.

First step, the \`\outlines` macro sets `\_tocline` to \`\_outlinesA` and
calculates the number of direct descendants of each record. Second step, 
the `\outlines` macro sets `\_tocline` to \`\_outlinesB` and it uses prepared 
data and create outlines.

Each ouline is mapped to the control sequence of the type
`\_ol:<num>` or `\_ol:<num>:<num>` or `\_ol:<num>:<num>:<num>` or etc.
The first one is reserved for level 0, the second one for level 1 (chapters), third
one for level 2 (sections) etc. The number of direct descentants will be stored
in these macros after first step is finished. Each new outline of given level
increases the `<num>` at given level. When the first step is processed then
(above that) the `\_ol:..` sequence of the parent inceases its value too. The
`_ol:...` sequences are implemented by `\_ol:\_count0:\_count1:\count2` etc.
For example, when section (level 2) is processed in the first step then we do:

\begtt
   \advance \count2 by 1  
                    % increases the mapping pointer of the type 
                    % \_ol:<\_count0:\_count1:\_count2> of this section
   \advance \<_ol:\_count0:\_count1> by 1  
                    % increases the number of descendants connected 
                    % to the parent of this section.
\endtt

When second step is processed, then we only read the stored data about the
number of descentants. Ad we use it in `count` parameter of `\_pdfoutline`
primitive.

For linking, we use the same links as in TOC, i.e. the `toc:\_the\_tocrefnum` 
labels are used.

\`\insertoutline` `{<text>}` inserts one outline with zero direct descendants.
It creates link destination of the type `oul:<num>` into the document
(where \^`\insertoutline` is used) and the link itself is created too in the
outline.