SyncTeX 可以修改吗,以便向后搜索到单个单词?

SyncTeX 可以修改吗,以便向后搜索到单个单词?

TeX 或 Synctex 在单词定位的设计上存在明显的缺陷。

给定 .tex 文件中的文本:

Blah blah blah. This is a sentence blah! Blah Blah!

整个段落被视为一个单位,而不是单个的单词。

事实证明,如果在每个单词或行中添加新行,那么同步效果就会很好:

Blah 
blah 
blah. 
This 
is 
a 
sentence 
blah! 
Blah 
Blah!

我们得到的是单词的准确度。

问题在于,它使得读取 tex 文件变得毫无意义,因此它不是一个合适的解决方案。

一个真正的解决方案是让编译器自动将单词(或行)翻译成单独的行。

这将为单词或行解析提供适当的语法,但反向传播不会与原始未改变的 .tex 文件匹配。

需要跟踪线路信息,然后进行反向映射。

有什么方法可以轻松做到这一点?

例如,

Line1:
Blah blah blah. This is a sentence blah! Blah Blah!
Line2:

变成

Line1:
Blah 
Line 2:
blah 
Line 3:
blah. 
Line 4:
This 
Line 5:
is 
Line 6:
a 
Line 7:
sentence 
Line 8:
blah! 
Line 9:
Blah 
Line 10:
Blah!

然后跟踪这些插入的新行的位置,并将其逆映射回插入它们的列。

这都是基本的映射,除了一些问题外,只需几行代码就很容易完成。

1:不得在无效位置插入新行,否则会破坏 .tex 文件或更改其输出。2:响应 synctex 的编辑器必须能够执行从行到行/列的逆映射。

本质上,只要不破坏 .tex 代码并能获得单词级精度,就可以在每个空格中插入一个新行。如果可以确定正确的单词边界,则可以在编译前完成此操作。我认为,如果可以在以下环境中完成,效果会更好:

\begin{synctexing}
\end{synctexing}

这实质上是将新行添加到中间的所有文本并忽略里面的任何环境,因此可以插入诸如 tikz 图片之类的内容,而不必创建一堆环境。

它只会输出映射文件(行/列到行),并且编辑器必须能够反转映射(很容易,但它需要支持它,除非它们已经支持列(但 synctex 总是给它们 0)。

问题不在于这很难,而在于我对具体细节一无所知。

事实上,即使我们必须做一些事情,比如\snl在 synctex 中添加一个新行,也比什么都不做要好。

答案1

SyncTeX 架构目前将 PDF 页面上的位置映射到输入文件中的行和“标签”(我真的不知道“标签”是什么)。

这是来自的 SyncTeX 数据结构syntex.c

/*  Here are all the local variables gathered in one "synchronization context"  */
static struct {
    void *file;                 /*  the foo.synctex or foo.synctex.gz I/O identifier  */
    synctex_fprintf_t fprintf;  /*  either fprintf or gzprintf */
    char *busy_name;            /*  the real "foo.synctex(busy)" or "foo.synctex.gz(busy)" name, with output_directory  */
    char *root_name;            /*  in general jobname.tex  */
    integer count;              /*  The number of interesting records in "foo.synctex"  */
    /*  next concern the last sync record encountered  */
    halfword node;              /*  the last synchronized node, must be set 
                                 *  before the recorder */
    synctex_recorder_t recorder;/*  the recorder of the node above, the
                                 *  routine that knows how to record the 
                                 *  node to the .synctex file */
    integer tag, line;          /*  current tag and line  */
    integer curh, curv;         /*  current point  */
    integer magnification;      /*  The magnification as given by \mag */
    integer unit;               /*  The unit, defaults to 1, use 8192 to produce shorter but less accurate info */
    integer total_length;       /*  The total length of the bytes written since    the last check point  */
    integer options;            /* unsigned options */
    integer lastv;              /* compression trick if
                                 |synctex_options&4|>0.  */
    integer form_depth;        /*  pdf forms are an example of nested sheets */
    struct _flags {
        unsigned int option_read:1; /*  Command line option read (in case of problem or at the end) */
        unsigned int content_ready:1; /*  Command line option read (in case of problem or at the end) */
        unsigned int off:1;         /*  Definitely turn off synctex, corresponds to cli option -synctex=0 */
        unsigned int no_gz:1;       /*  Whether zlib is used or not */
        unsigned int not_void:1;    /*  Whether it really contains synchronization material */
        unsigned int warn:1;        /*  One shot warning flag */
        unsigned int quoted:1;      /*  Whether the input file name was quoted by tex or not, for example "\"my input file.tex\"", unused by XeTeX */
        unsigned int output_p:1;    /*  Whether the output_directory is used */
        unsigned int reserved:SYNCTEX_BITS_PER_BYTE*sizeof(int)-8; /* Align */
    } flags;
} synctex_ctxt = {

要在输入文件中记录该列,您必须向数据结构添加另一个字段,并调整所有记录器功能以将此条目写入 SyncTeX 文件。下一步是调整 SyncTeX 解析器以从 SyncTeX 文件中选取该列。然后,您必须编辑编辑器的源代码,使其知道反向搜索现在也映射到该列。最难的部分是,以上所有操作都必须以向后兼容的方式完成,以便您的编辑器仍然可以读取旧版本的 SyncTeX 文件,并且旧解析器仍然可以读取使用新版本编写的 SyncTeX 文件。

所以,从理论上讲,实现你的想法是可能的,但找到一个实际做到这一点的人可能NP困难

答案2

首先,synctex 通常是怎样工作的?基本上,在编辑代码时,正向同步是通过调用

synctex view -i line:column:[page_hint:]input

它根据输入文件中的行和列进行操作,并尝试在输出中找到位置。因此,至少前向同步可以按照您想要的方式进行。

对于向后同步,查看器调用

synctex edit -o page:x:y:file -x editor-command

它代表页码、鼠标事件的 x 和 y 坐标以及文件名。在编辑器命令中,您实际上可以使用%{column}它将列传递给编辑器。但请注意,列支持相当脆弱。

根据手册页框和记录(current、kern、glue、math)有列支持,但这是可选的。因此,基本上引擎允许将列输出到 synctex 文件。但实际上,您会注意到链接部分仅由标签(框或记录的内部表示/id)和行号组成,因此您必须为此添加引擎支持。

这也是为什么您的环境不会提供任何帮助的原因,因为基本上 TeX 的“解释器”,引擎并不知道这一点。这就是您必须努力的方向,请记住,有些编辑器可能也不支持列输入。

答案3

参照是否可以重新定义空白命令?

\documentclass{article}
\newcommand{\AND}{\par}
\obeyspaces\obeylines
  \begingroup\lccode`\~=`\ \lowercase{\endgroup\let~}\AND
  \begingroup\lccode`\~=`\^^M\lowercase{\endgroup\let~}\AND
\begin{document}
Blah blah blah. This is a sentence blah! Blah Blah!

\bigskip

Line1:
Blah blah blah. This is a sentence blah! Blah Blah!
Line2:
\end{document}

enter image description here

相关内容