summaryrefslogtreecommitdiff
path: root/macros/luatex/optex/pdfuni-string.opm
blob: dac1c5c3b820b7d94462de05257964388deb7ebb (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
%% This is part of OpTeX project, see http://petr.olsak.net/optex

\_codedecl \pdfunidef {PDFunicode strings for outlines <2020-02-14>}

\_edef\_octalprint#1#2{\_noexpand\_directlua{% #1=character-code #2=character
    if ('#2'>='A' and '#2'<='Z') or ('#2'>='a' and '#2'<='z') then
      tex.print(string.format('000\_pcent s',"#2"))
    else
      local num=#1\_pcent256
      tex.print(string.format('\_pcent 03o\_nbb\_pcent03o',(#1-num)/256,num))
    end
}}
\_def\_pdfunidef#1#2{%
   \_begingroup
      \_catcode`\\=12 \_let\\=\_nbackslash
      \_the\_pdfstringout % extra defnitions of logos etc.
      \_edef#1{#2}%
      \_replstring#1{ }{{ }}%  text text -> text{ }text
      \_edef\_out{\\376\\377}%
      \_ea\_pdfunidefB#1^%  text -> \_out in octal
      \_ea
   \_endgroup
   \_ea\_def\_ea#1\_ea{\_out}
}
\_def\_pdfunidefB#1{%
   \_ifx^#1\_else 
      \_tmpnum=`#1
      \_ea\_ifx\_nbackslash#1\_pdfunidefC{#1#1}\_else\_pdfunidefC{#1}\_fi
   \_ea\_pdfunidefB \_fi
} 
\_def\_pdfunidefC #1{\_edef\_out{\_out \\\_ea\_octalprint\_ea{\_the\_tmpnum}{#1}}}

\_newtoks \_pdfstringout

\public \pdfunidef \pdfstringout ;

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

There are only two encodings for PDF strings (used in PDFoutlines, PDFinfo
etc.). First one is PDFDocEncoding which is one-byte encoding, but most
Czech or Slovak characters are missing here.

The second encoding is PDFunicode encoding wich is implemented in this file. 
This encoding is TeX-dicomfortable, because it looks like

\376\377\000C\000v\000i\001\015\000e\000n\000\355\000\040\000j\000e\000\040
\000z\000\341\000t\001\033\001\176 

This example is real encoding of the string "Cvičení je zátěž". You can see
that this is UTF-16 encoding (two bytes per character) with two starting
bytes FEFF. Moreover, each byte is encoded by three octal digits preceded by
backslash. The only exception is the visible ASCII character encoding: such
a character is encoded by its real byte preceded by \000.

The pdfuni.tex macro implements the command

\pdfunidef\macro{string}

We implemented the octal string printing of one character using \directlua.
The input string is preprocessed: detokenized, converted `\word /` to
`\word/` (used in logos) preprocessed spaces using \replstring and then the
\_pdfunidefB is repeated on each character. It calls the `\directlua` chunk
to print octal numbers.