You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改InDesign脚本识别LaTeX格式的\footnote{}脚注?

LaTeX脚注转InDesign自动格式化脚本问题

我需要将LaTeX编写的文本在InDesign中格式化,主文本内的脚注均以\footnote{}标签包裹,示例文本如下:

This is my main text\footnote{with foonotes and sometimes with other braces inside footnotes such as\ref{section2}}, and I want to format it properly.

脚注数量多达数百个,希望通过脚本实现自动格式化,目前使用的脚本无法适配该格式,请问遗漏了什么?原脚本如下:

Application.prototype.main = function(){
  if (this.documents.length <= 0) return;
  var tg = this.selection[0] || this.activeDocument;
  if ('appliedFont' in tg) tg = tg.parent;
  if (tg.constructor == TextFrame) { tg = tg.parentStory; }
  if (!('findGrep' in tg)) return;

  /* Here it is neecessary to choose a pattern for wrapping the note, we are not parsing
  here, hence the rough technique! */
  var fnPatterns = ["(\\\\footnote\\{)([^\\}]+)(\\})"];

  var count = 0;

  for(patterCounter = 0; patterCounter < fnPatterns.length; patterCounter++){
    fnPattern = fnPatterns[patterCounter];

    var fnFinds = (function(){
      this.findGrepPreferences = this.changeGrepPreferences = null;
      this.findGrepPreferences.findWhat = fnPattern;
      var ret = tg.findGrep();
      this.findGrepPreferences = this.changeGrepPreferences = null;

      return ret;
    }).call(this);

    var fnFind, fnPrefix,fnSuffix, rg = new RegExp(fnPattern), ip, fnParent, fn, count;

    while (fnFind = fnFinds.pop()){
      fnPrefix = fnFind.contents.match(/^@[^@]+@/)[0];
      fnSuffix = fnFind.contents.match(/@[^@]+@/)[0];

      try {
        // add footnote
        fn = fnFind.footnotes.add(LocationOptions.AFTER, fnFind.insertionPoints[-1]);
        // duplicate the text
        fnFind.texts[0].characters.itemByRange(fnPrefix.length,fnFind.texts[0].characters.length-fnSuffix.length-1).duplicate(LocationOptions.AT_END, fn.texts[0]);
        // remove the original
        fnFind.characters.itemByRange(0,fnFind.characters.length-2).remove();
        ++count;
      }
      catch(_){}
    }
  }
  alert((count)? (count+" footnote(s) successfully added."): "No footnote added. Make sure you use the relevant pattern.");
}
app.doScript('app.main();', ScriptLanguage.javascript, undefined, UndoModes.entireScript, app.activeScript.displayName);

原脚本的核心问题

  1. 正则无法处理嵌套大括号
    原脚本的Grep模式(\\\\footnote\\{)([^\\}]+)(\\})中,[^\\}]+会在遇到第一个}时停止匹配,完全无法处理脚注内部嵌套的大括号(比如示例中的\ref{section2}),导致脚注内容截取不完整。

  2. 错误的前缀/后缀匹配逻辑
    脚本里的@[^@]+@匹配规则是针对用@包裹脚注的格式设计的,和\footnote{}的结构完全不兼容,这会直接触发匹配失败,脚注无法创建。

  3. 文本处理逻辑错位
    基于错误的前缀后缀匹配,后续的文本截取、复制、删除逻辑全部不适用于\footnote{}的结构,要么破坏原文本,要么无法正确提取脚注内容。


修正后的脚本

Application.prototype.main = function(){
  if (this.documents.length <= 0) return;
  var tg = this.selection[0] || this.activeDocument;
  if ('appliedFont' in tg) tg = tg.parent;
  if (tg.constructor == TextFrame) { tg = tg.parentStory; }
  if (!('findGrep' in tg)) return;

  // 适配嵌套大括号的Grep模式:完整匹配\footnote{...},支持内部嵌套{}
  var fnPatterns = ["(\\\\footnote\\{)([^}]*+(?:\\{[^}]*+\\}[^}]*)*+)(\\})"];

  var count = 0;

  for(let patterCounter = 0; patterCounter < fnPatterns.length; patterCounter++){
    const fnPattern = fnPatterns[patterCounter];

    const fnFinds = (function(){
      this.findGrepPreferences = this.changeGrepPreferences = null;
      this.findGrepPreferences.findWhat = fnPattern;
      const ret = tg.findGrep();
      this.findGrepPreferences = this.changeGrepPreferences = null;

      return ret;
    }).call(this);

    let fnFind, fn, match;
    const regex = new RegExp(fnPattern);

    while (fnFind = fnFinds.pop()){
      match = fnFind.contents.match(regex);
      if (!match || match.length < 3) continue;

      try {
        // 在匹配文本末尾添加脚注
        fn = fnFind.footnotes.add(LocationOptions.AFTER, fnFind.insertionPoints[-1]);
        // 将脚注内部内容(正则匹配组2)复制到新脚注
        fn.contents = match[2];
        // 删除原有的\footnote{...}文本
        fnFind.remove();
        ++count;
      }
      catch(err){
        // 捕获单个脚注的处理错误,避免脚本中断
        console.log(`处理脚注失败: ${err.message}`);
      }
    }
  }
  alert(count ? `${count} 个脚注已成功添加。` : "未添加任何脚注,请检查格式是否匹配。");
}
app.doScript('app.main();', ScriptLanguage.javascript, undefined, UndoModes.entireScript, app.activeScript.displayName);

关键修改说明

  • 嵌套大括号适配:使用的Grep模式能完整匹配包含多层嵌套{}的脚注内容,确保脚注内部的LaTeX命令不会中断匹配。
  • 移除无效匹配逻辑:直接通过正则捕获组提取\footnote{}内部的文本,不再依赖错误的@前缀后缀规则。
  • 简化处理流程:直接设置脚注内容并删除原标记,逻辑更清晰可靠,减少文本操作出错的概率。
  • 错误日志优化:添加错误捕获并输出日志,方便排查单个脚注的处理问题。

内容的提问来源于stack exchange,提问作者Sulli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 03:54:54