TeXstudio编辑器下“编辑宏”(Script Macros)问题

发布于 2025-12-28 22:09:27

本人使用TeXstudio编辑器。因latex编译的PDF文件目录有显示问题,需编译前修改.toc文件。但每次编译前都要修改文件太繁琐,想通过宏(Script Macros)命令解决。主要步骤:

  1. 打开D:\RSWW\Gita Tex目录下的Gita.toc文件;
  2. 删除文件中全部有字符串\selectlanguage *{sanskrit}\selectlanguage *[script=Devanagari,numerals=Devanagari]{sanskrit}的行;
  3. 保存Gita.toc文件。

曾尝试通过AI生成脚本,但执行总通不过。请教达人脚本宏实现的方法,谢谢!

image.png

// 宏:清理指定目录的 Bhagavad-Gita.toc 文件
// 描述:删除包含 selectlanguage 命令的行,解决 PDF 目录显示问题

function cleanBhagavadGitaTOC() {
    // 指定 .toc 文件的完整路径
    var tocFilePath = "D:/如是我闻/Bhagavad-Gita Tex/Bhagavad-Gita.toc";
    
    // 检查 .toc 文件是否存在
    if (!QFile.exists(tocFilePath)) {
        app.message("未找到 .toc 文件: " + tocFilePath, "错误");
        return;
    }
    
    // 读取 .toc 文件内容
    var file = new QFile(tocFilePath);
    if (!file.open(QIODevice.ReadOnly | QIODevice.Text)) {
        app.message("无法打开 .toc 文件", "错误");
        return;
    }
    
    // 读取文件内容并分割为行
    var stream = new QTextStream(file);
    stream.setCodec("UTF-8");
    var lines = [];
    var deletedCount = 0;
    var lineNumber = 0;
    
    // 读取所有行,过滤掉不需要的行
    while (!stream.atEnd()) {
        var line = stream.readLine();
        lineNumber++;
        
        // 检查是否包含要删除的字符串
        if (line.includes("\\selectlanguage *{sanskrit}") || 
            line.includes("\\selectlanguage *[script=Devanagari,numerals=Devanagari]{sanskrit}")) {
            deletedCount++;
            // 可选:在控制台输出删除的行号
            console.log("删除第 " + lineNumber + " 行: " + line.substring(0, 50) + "...");
        } else {
            lines.push(line);
        }
    }
    
    file.close();
    
    // 如果有行被删除,则保存文件
    if (deletedCount > 0) {
        if (!file.open(QIODevice.WriteOnly | QIODevice.Text | QIODevice.Truncate)) {
            app.message("无法写入 .toc 文件", "错误");
            return;
        }
        
        var outStream = new QTextStream(file);
        outStream.setCodec("UTF-8");
        
        // 写入保留的行
        for (var i = 0; i < lines.length; i++) {
            outStream << lines[i];
            if (i < lines.length - 1) {
                outStream << "\n";
            }
        }
        
        file.close();
        app.message("已删除 " + deletedCount + " 行", "信息");
    } else {
        app.message("未找到需要删除的行", "信息");
    }
}

// 运行函数
cleanBhagavadGitaTOC();

查看更多

关注者
0
被浏览
64
1 个回答
Sagittarius Rover
Sagittarius Rover 16小时前
这家伙很懒,什么也没写!
本人使用TeXstudio编辑器。因latex编译的PDF文件目录有显示问题,需编译前修改.toc文件

为什么不从根源出发,直接修复.tex文件的问题。

但每次编译前都要修改文件太繁琐,想通过宏(Script Macros)命令解决。

从你的描述来看,这个问题和「对任意一个文本文件进行该操作」无异,只是这个文件恰好是「.toc」,因此可以认为这个问题和LaTeX其实不太相关。

曾尝试通过AI生成脚本,但执行总通不过。

你并未提供别人可以复现的所有必要信息。

你最好举例说明.toc文件的具体情况,具体要如何匹配「删除文件中全部有字符串\selectlanguage *{sanskrit}\selectlanguage *[script=Devanagari,numerals=Devanagari]{sanskrit}的行;」。例如这里\selectlanguage其后是否总是有空格,是否除了这两种情况还可能有其他的情况,这都可能影响脚本的写法。

最好补充给一个.toc修改前的范例和预期的脚本处理结果。否则别人不容易复现和测试。


Edited:

要注意阅读文档:

应该先明确这个「编辑宏」的功能支持哪些语法....「QFile未定义显然是因为TeXStudio的脚本功能不支持这个"类"...」

我稍微vibe了一下,下面这个脚本似乎可行:

function cleanToc() {
    var texFile = app.getCurrentFileName();
    if (!texFile) {
        alert("没有打开任何文件。");
        return;
    }

    var tocFile = texFile.replace(/\.[^.]+$/, "") + ".toc";

    var content = readFile(tocFile);
    if (content === undefined || content === null) {
        alert("无法读取 " + tocFile);
        return;
    }

    var lines = content.split(/\r?\n/);
    var result = [];
    var deleted = 0;

    // 匹配所有 \selectlanguage *{sanskrit} 以及带可选参数的形式
    var re = /^\s*\\selectlanguage\s*\*(?:\[[^\]]*\])?\{sanskrit\}/i;

    for (var i = 0; i < lines.length; i++) {
        var line = lines[i];

        if (re.test(line.trim())) {
            deleted++;
            continue;
        }

        result.push(line);
    }

    writeFile(tocFile, result.join("\n"));

    alert("清理完成:删除 " + deleted + " 行。\n文件:" + tocFile);
}

cleanToc();

但是你没有提供别人可以复现的条件...我无法测试...

Before

image.png

Run

image.png

After

image.png

其中

    // 匹配所有 \selectlanguage *{sanskrit} 以及带可选参数的形式
    var re = /^\s*\\selectlanguage\s*\*(?:\[[^\]]*\])?\{sanskrit\}/i;

为匹配的正则表达式,可能要按需修改

另外,为什么不从源头入手,「目录有问题」具体是哪里有问题?上述工作流非常不顺畅,而且路径也是写死的...

总的来说这个需求并不太合理....

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览