Skip to main content
Source Link
user202729
  • 9.1k
  • 1
  • 34
  • 41

Some tips for large log file:

  • Since it's really hard to look for (file and ) in that case, you can use some LaTeX hook to log some message when the file changes:

    \ExplSyntaxOn
    \seq_new:N \__file_list
    \seq_put_right:Nn \__file_list {\msg_expandable_error:nn{}{this~cannot~happen!}}
    \seq_put_right:Nn \__file_list {<main~file>}
    \AddToHook{file/before}{
        \seq_put_right:NV \__file_list \CurrentFile
        \wlog {enter~file\use_none:n{}::\CurrentFile}
    }
    \AddToHook{file/after}{
        \seq_pop_right:NN \__file_list \__last_file
        \seq_get_right:NN \__file_list \__last_file
        \wlog {return~to~file\use_none:n{}::\__last_file}
    }
    \ExplSyntaxOff
    

    (obviously the effect is, you get a line enter file::X and return to file::X in the log. Search for file::. The \use_none:n {} is to prevent the message from being found while doing macro expansion, if macro logging is enabled.)

  • A "binary search" alternative is to insert a (commented) empty line to some TeX files, then see if the line number increases. (it's "brute force", but works most of the time, except if catcode is weird.)

  • Note that, even if some particular \if is reported as the culprit, it's not necessarily the cause. For example

    \if ... % A
    
        \if ... % B (accidentally inserted)
    
    \fi % C
    

    Clearly the one at B is at fault here, nevertheless TeX will report A is incomplete. And A might be deep buried inside some library code (e.g. if you have incomplete \if within some .sty file this can happen)

  • Generally speaking, it's useful to search for if.* <line number>} (regex) from the end of the file, since you can observe that if there are multiple such \if, the last one will be likely at fault; nevertheless if the first hit is a \fi then skip through one \if.

    Example log

    {\if entered on line X}
    {\else: \if entered on line X}
    {\fi: \if entered on line X}
    
    {\if entered on line X}
    {\else: \if entered on line X}
    {\fi: \if entered on line X}
    
    {\if entered on line X}
    {\else: \if entered on line X}
    {\fi: \if entered on line X}
    
    {\if entered on line X}
    
    {\if entered on line X}
    {\else: \if entered on line X}
    {\fi: \if entered on line X}
    

    In this example it can be seen that if you search for the log lines from the end backwards, you'll first see a \fi, then skip one \if, then find the offending command immediately. (there's (level X) to partially help with search for matching lines, but no more than that.)