[pdftex] \escapes and /Limits

Heiko Oberdiek oberdiek at uni-freiburg.de
Sat Jul 3 19:36:38 CEST 2004


Hello,

On Sat, Jul 03, 2004 at 04:03:14PM +0200, Hartmut Henkel wrote:

> On Fri, 2 Jul 2004, Karl Berry wrote:
> 
> > (I apologize in advance for not knowing enough to be sure if I really
> > understand what's happening, not to mention the complexity of the
> > question.)

I agree with your analysis.

> > It appears to me that the generated PDF file may be incorrect.  With the
> > attached test file, run through the attached (unreleased) texinfo.tex,
> > the resulting (also attached) PDF contains:
> >
> >     /Names [(-1) 13 0 R (1) 4 0 R (\no) 5 0 R]
> >     /Limits [(-1) (\no)]
> ...
> 
> Maybe, once things are interpreted as strings, the escaping should work,
> after PDF reference Table 3.2, to keep the PDF file valid. But pdfTeX's
> str_less_str() function, which does the sorting here, does not deal with
> escaped chars at all. So before thinking (any further), i tried to let
> the sorting handle also these escaped things. Below is some buggy change
> file, but at least, on some input file like

> In the change file missing is octal interpretation, and the case that
> the character after the backslash is not in the list, and therefore the
> backslash itself should be ignored. Further if the backslash is alone at
> the end of the string. All these gory cases...

I have also written a version of str_less_str
including octal interpretation, but I do not think, that this
is the right approach:
* pdfTeX checks for equal destinations, (0) and (\060) are both
  the same, but pdfTeX does not warn here.

Therefore the approach should be:
* converting the input into a string with 8-bit characters
* str_less_str then can be let unchanged
* converting during output (\\, \(, \), which else?)

Yours sincerely
  Heiko <oberdiek at uni-freiburg.de>

PS: my hack of str_less_str:

The following procedures sort the table of destination names
@p function str_less_str(s1, s2: str_number): boolean; {compare two strings}
var i1, i2: pool_pointer;
    k1, k2: pool_pointer;
    c1, c2: integer;
begin
    i1 := str_start[s1];
    i2 := str_start[s2];
    k1 := str_start[s1 + 1];
    k2 := str_start[s2 + 1];
    while (i1 < k1) and (i2 < k2) do begin
        c1 := str_pool[i1];
        if (c1 = 92) then begin
            if (i1 + 1 < k1) then begin
                incr(i1);
                c1 := str_pool[i1];
                case c1 of
                     92, 40, 41: begin end;
                    { backspace, left and right parenthesis }
                    110: c1 := 10; { line feed (LF) }
                    114: c1 := 13; { carriage return (CR) }
                    116: c1 :=  9; { horizontal tab (HT) }
                     98: c1 :=  8; { backspace (BS) }
                    102: c1 := 12; { form feed (FF) }
                othercases
                    { octal escape sequences }
                    if (c1 >= 48) and (c1 <= 57) then begin
                        c1 := c1 - 48;
                        if (i1 + 1 < k1) and
                                (str_pool[i1 + 1] >= 48) and
                                (str_pool[i1 + 1] <= 57) then begin
                            incr(i1);
                            c1 := 8 * c1 + str_pool[i1] - 48;
                            if (i1 + 1 < k1) and
                                    (str_pool[i1 + 1] >= 48) and
                                    (str_pool[i1 + 1] <= 57) then begin
                                incr(i1);
                                c1 := 8 * c1 + str_pool[i1] - 48;
                            end
                        end
                    end;
                endcases;
            end
        end;
        c2 := str_pool[i2];
        if (c2 = 92) then begin
            if (i2 + 1 < k2) then begin
                incr(i2);
                c2 := str_pool[i2];
                case c2 of
                     92, 40, 41: begin end;
                    110: c2 := 10;
                    114: c2 := 13;
                    116: c2 :=  9;
                     98: c2 :=  8;
                    102: c2 := 12;
                othercases 
                    if (c2 >= 48) and (c2 <= 57) then begin
                        c2 := c2 - 48;
                        if (i2 + 1 < k2) and
                                (str_pool[i2 + 1] >= 48) and
                                (str_pool[i2 + 1] <= 57) then begin
                            incr(i2);
                            c2 := 8 * c2 + str_pool[i2] - 48;
                            if (i2 + 1 < k2) and
                                    (str_pool[i2 + 1] >= 48) and
                                    (str_pool[i2 + 1] <= 57) then begin
                                incr(i2);
                                c2 := 8 * c2 + str_pool[i2] - 48;
                            end
                        end
                    end;
                endcases;
            end
        end;
        if (c1 < c2) then begin
            str_less_str := true;
            return;
        end;
        if (c1 > c2) then begin
            str_less_str := false;
            return;
        end;
        incr(i1);
        incr(i2);
    end;
    if (i1 < k1) then
        str_less_str := true
    else
        str_less_str := false;
end;

-- 



More information about the pdftex mailing list