summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/tagpdf/tagpdf-mc-code-lua.sty
blob: 4387d3b80857b9cb3d827594eb4dd00e5e3a722d (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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
\ProvidesExplPackage {tagpdf-mc-code-lua} {2019/07/02} {0.61}
  {tagpdf - mc code only for the luamode }

% the two attibutes are defined in the driver file.
% it also load the lua (as it can also contain functions needed by generic mode.
% (new) attributes for mc are local:
% \newattribute \l__uftag_mc_type_attr     %the value represent the type
% \newattribute \l__uftag_mc_cnt_attr      %will hold the \c@g__uftag_MCID_abs_int value


% An attribute for the current structure probably doesn't make sense as mc chunks can be used later.
% \newattribute \g__uftag_struct_type_attr %represent the current structure type. Not sure if needed
% \newattribute \g__uftag_struct_cnt_attr  %will hold \c@g__uftag_struct_abs_int a cnt

% handling attribute needs a different system to number the page wise mcid's:
% a tagmcbegin ... tagmcend pair no longer surrounds exactly one mc chunk: it can be split
% at page breaks. We know the included mcid(s) only after the ship out. So for the struct-> mcid mapping we
% need to record struct -> mc-cnt (in \g__uftag_mc_parenttree_prop and/or a lua table
% and at shipout mc-cnt-> {mcid, mcid, ...} (in a table?)
% and when building the trees connect both

% key definitions are overwritten for luatex to store that data in tables
% the data for the mc are in uftag.mc[absnum]
% the fields of the table are
% tag : the type (a string)
% raw : more properties (string)
% label: a string. Do we need a way to retrieve the num from the label from lua??
% artifact: the presence indicates an artifact, the value (string) is the type.
% kids: a array of tables {1={kid=num2,page=pagenum1}, 2={kid=num2,page=pagenum2},...},
% this describes the chunks the mc has been split to by the traversing code
% parent: the number of the structure it is in. Needed to build the parent tree.

% The main function which wanders through the shipout box to inject the literals.
\AtBeginDocument
 {
  \bool_if:NT\g_uftag_active_mc_bool
   {
    \AtBeginShipout
     {
      \directlua{uftag.func.mark_shipout ()}
     }
   }
 }

\prg_new_conditional:Nnn \__uftag_mc_if_in: {p,T,F,TF}
 {
  \int_compare:nNnTF {-2147483647}={\l__uftag_mc_type_attr}
   { \prg_return_true:  }
   { \prg_return_false: }
 }

\prg_new_eq_conditional:NNn \uftag_mc_if_in: \__uftag_mc_if_in: {p,T,F,TF}

% the keys
\tl_new:N \l__uftag_mc_key_tag_tl
\tl_new:N \l__uftag_mc_key_label_tl
\tl_new:N \l__uftag_mc_key_properties_tl

\keys_define:nn { uftag / mc }
 {
  tag .code:n = %
   {%%????????? \pdfescapename??
    \tl_set:Nx  \l__uftag_mc_key_tag_tl { #1 }
    \directlua
     {
      uftag.func.store_mc_data(\__uftag_get_mc_abs_cnt:,"tag","#1")
     }
   },
  raw .code:n =
   {
    \tl_put_right:Nx \l__uftag_mc_key_properties_tl { #1 }
    \directlua
     {
      uftag.func.store_mc_data(\__uftag_get_mc_abs_cnt:,"raw","#1")
     }
   },
  alttext .code:n      = % Alt property
   {
    \str_set_convert:Nnon
     \l__uftag_tmpa_str
     { #1 }
     { \g__uftag_inputencoding_tl }
     { utf16/hex }
    \tl_put_right:Nn \l__uftag_mc_key_properties_tl { /Alt~< }
    \tl_put_right:No \l__uftag_mc_key_properties_tl { \l__uftag_tmpa_str>~ }
    \directlua
     {
      uftag.func.store_mc_data(\__uftag_get_mc_abs_cnt:,"alt","/Alt~<\str_use:N \l__uftag_tmpa_str>")
     }
   },
  alttext-o .code:n      = % Alt property
   {
    \str_set_convert:Noon
     \l__uftag_tmpa_str
     { #1 }
     { \g__uftag_inputencoding_tl }
     { utf16/hex }
    \tl_put_right:Nn \l__uftag_mc_key_properties_tl { /Alt~< }
    \tl_put_right:No \l__uftag_mc_key_properties_tl { \l__uftag_tmpa_str>~ }
    \directlua
     {
      uftag.func.store_mc_data(\__uftag_get_mc_abs_cnt:,"alt","/Alt~<\str_use:N \l__uftag_tmpa_str>")
     }
   },
  actualtext .code:n      = % Alt property
   {
    \str_set_convert:Nnon
     \l__uftag_tmpa_str
     { #1 }
     { \g__uftag_inputencoding_tl }
     { utf16/hex }
    \tl_put_right:Nn \l__uftag_mc_key_properties_tl { /Alt~< }
    \tl_put_right:No \l__uftag_mc_key_properties_tl { \l__uftag_tmpa_str>~ }
    \directlua
     {
      uftag.func.store_mc_data(\__uftag_get_mc_abs_cnt:,"actualtext","/ActualText~<\str_use:N \l__uftag_tmpa_str>")
     }
   },
  actualtext-o .code:n      = % Alt property
   {
    \str_set_convert:Noon
     \l__uftag_tmpa_str
     { #1 }
     { \g__uftag_inputencoding_tl }
     { utf16/hex }
    \tl_put_right:Nn \l__uftag_mc_key_properties_tl { /Alt~< }
    \tl_put_right:No \l__uftag_mc_key_properties_tl { \l__uftag_tmpa_str>~ }
    \directlua
     {
      uftag.func.store_mc_data(\__uftag_get_mc_abs_cnt:,"actualtext","/ActualText~<\str_use:N \l__uftag_tmpa_str>")
     }
   },
  label .code:n =
   {
    \tl_set:Nn\l__uftag_mc_key_label_tl { #1 }
    \directlua {uftag.func.store_mc_data(\__uftag_get_mc_abs_cnt:,"label","#1")}
   },
  __artifact-store .code:n =
   {
    \directlua {uftag.func.store_mc_data(\__uftag_get_mc_abs_cnt:,"artifact","#1")}
   },
  artifact .code:n       =
    {
     \exp_args:Nnx \keys_set:nn {uftag / mc} { artifact-bool, artifact-type=#1, tag=Artifact }
     \exp_args:Nnx \keys_set:nn {uftag / mc }{ __artifact-store=\l__uftag_mc_artifact_type_tl }
    },
  artifact .default:n    = { notype }
 }


% attributes
% set the mc from a tag name

\cs_set_protected:Npn \__uftag_attribute_gset:Nn #1 #2
 {
  \tex_global:D \setattribute #1 #2
 }

\cs_set_protected:Npn \__uftag_attribute_set:Nn #1 #2
 {
  \setattribute #1 #2
 }

\cs_set_protected:Npn \__uftag_attribute_gunset:N #1
 {
  \tex_global:D \unsetattribute #1
 }

\cs_set_protected:Npn \__uftag_attribute_unset:N #1
 {
   \unsetattribute #1
 }


\cs_new:Nn \__uftag_mc_lua_set_mc_type_attr:n % #1 is a tag name
 {
  \__uftag_attribute_set:Nn \l__uftag_mc_type_attr { \directlua {uftag.func.output_num_from ("#1") } }
  \__uftag_attribute_set:Nn \l__uftag_mc_cnt_attr  { \__uftag_get_mc_abs_cnt: }
 }

\cs_generate_variant:Nn\__uftag_mc_lua_set_mc_type_attr:n { o }

\cs_new:Nn \__uftag_mc_lua_unset_mc_type_attr:
 {
  \__uftag_attribute_unset:N \l__uftag_mc_type_attr
  \__uftag_attribute_unset:N \l__uftag_mc_cnt_attr
 }



%This command will in the finish code replace the dummy for a mc by the real mcid kids
%we need a variant for the case that it is the only kid, to get the array right
\cs_new:Nn \__uftag_mc_insert_mcid_kids:n
 {
  \directlua {uftag.func.mc_insert_kids (#1,0) }
 }

\cs_new:Nn \__uftag_mc_insert_mcid_single_kids:n
 {
  \directlua {uftag.func.mc_insert_kids (#1,1) }
 }


% we need to pass the info if the kids are alone or already in an array
% so we add a second argument, which should == 1 if the kids are single


% puts an mcid absolute number in the current structure
\cs_new:Nn \__uftag_mc_handle_stash:n %1 mcidnum
 {
  \__uftag_check_mc_used:n { #1 }
  \seq_gput_right:cn % Don't fill a lua table due to the command in the item, so the kernel command
   { g__uftag_struct_kids_\g__uftag_struct_stack_current_tl _seq }
   {
    \__uftag_mc_insert_mcid_kids:n {#1}%
   }
  \directlua
   {
    uftag.func.store_struct_mcabs(\g__uftag_struct_stack_current_tl,#1)
   }
  \prop_gput:Nxx
   \g__uftag_mc_parenttree_prop
   { #1 }
   { \g__uftag_struct_stack_current_tl }
 }

\cs_generate_variant:Nn \__uftag_mc_handle_stash:n { o }

\cs_new_protected:Nn \uftag_mc_begin:n
 {
   %\group_begin:
   %\__uftag_check_mc_if_nested:
   %\bool_gset_true:N \g__uftag_in_mc_bool
   \int_gincr:N \c@g__uftag_MCID_abs_int
   \tl_clear:N\l__uftag_mc_key_properties_tl
   \keys_set:nn { uftag / mc }{ label={}, #1 }
   %check that a tag or artifact has been used
   \__uftag_check_mc_tag:N \l__uftag_mc_key_tag_tl
   %set the attributes:
   \__uftag_mc_lua_set_mc_type_attr:o  { \l__uftag_mc_key_tag_tl }
   \bool_if:NF \l__uftag_mc_artifact_bool
    { % store the absolute num name in a label:
      \tl_if_empty:NF {\l__uftag_mc_key_label_tl}
       {
        \__uftag_mc_handle_mc_label:n { \l__uftag_mc_key_label_tl }
       }
      % if not stashed record the absolute number
      \bool_if:NF \l__uftag_mc_key_stash_bool
      {
        \exp_args:Nx \__uftag_mc_handle_stash:n { \__uftag_get_mc_abs_cnt: }
      }
    }
   \bool_set_false:N\l__uftag_mc_artifact_bool
  %\group_end:
 }

\cs_new_protected:Nn \uftag_mc_end:
 {
  %\__uftag_check_mc_if_open:
  %\bool_gset_false:N \g__uftag_in_mc_bool
  \__uftag_mc_lua_unset_mc_type_attr:
  \tl_set:Nn  \l__uftag_mc_key_tag_tl { }
 }

\cs_new_protected:Nn \uftag_mc_use:n %#1: label name
 {
  \tl_set:Nx  \l_tmpa_tl { \zref@extractdefault{tagpdf-#1}{tagmcabs}{} }
  \tl_if_empty:NTF\l_tmpa_tl
   {
    \msg_warning:nnn {uftag} {mc-label-unknown} { #1 }
   }
   {
    \__uftag_mc_handle_stash:o { \l_tmpa_tl }
   }
 }

\cs_new:Nn \__uftag_get_data_mc_tag: { \l__uftag_mc_key_tag_tl }


\endinput