inDesign 脚本 - 从 "typesetting script" TextFrame 剪切并粘贴到空 TextFrame

inDesign Scripting - Cut from "typesetting script" TextFrame and paste on empty TextFrame

我需要一个 Adob​​e 脚本来执行此操作:

我一直在做这个排版工作,我遇到了这个 Typesetterer for Photoshop, went on a journey to find a similar script/application for inDesign and I found this this solution, tried it and worked, boosting my productivity by at least 2x. Tried this split one 但是调整大小和移动所有生成的 TextFrames 需要更长的时间。但它对我开发最终代码非常有用。

这种方法的主要问题是它要求排版脚本在 .txt 文件中,这破坏了所有 BoldItalic 来自原始脚本。

main();

function main() { // Main() just to keep it organized
  try {
    var myMeasuringUnit = app.scriptPreferences.measurementUnit;
    app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;
  } catch (exception) {
    alert(exception.description);
    exit();
  }

  var myTextFrameSelection = app.activeDocument.selection;
  cutAndPaste(myTextFrameSelection);

  try {
    app.scriptPreferences.measurementUnit = myMeasuringUnit;
  } catch (exception) {}
}

function cutAndPaste(myTextFrameSelection) {
  for (elementsInSelection = 0; elementsInSelection < myTextFrameSelection.length; elementsInSelection++) {
    if (myTextFrameSelection[elementsInSelection].constructor.name == "TextFrame") {
      var myParagraphs = myTextFrameSelection[elementsInSelection].texts[0].paragraphs;
      var isCopied = true;
      for (var i = 0; i < myParagraphs.length; i++) {
        try {
          myParagraphs[i].insertionPoints.itemByRange(0, -2).select();
          app.cut();
          isCopied = true;
        } catch (exception) {
          isCopied = false;
        }
        if (isCopied) {
          /*
          Attempt at adding a way to select another TextFrame and app.paste() the previously app.cut() line in it

          var doc = app.activeDocument.selection[0];
          doc.addEventListener('afterSelectionChanged', selectionChanged);

          function selectionChanged() {
              if (doc.selection[0] instanceof TextFrame && doc.selection[0].contents == '' && doc.selection[1] == null) {
                  if (doc.selection[0] instanceof TextFrame) {
                  doc.selection[0].contents = app.paste();
              }
          }
          */
          app.paste(); // This just pastes it in the same folder
        }
      }
    }
  }
} // For now, what it does it "cut paragraph from the TextFrame but also paste in the same TextFrame"

到目前为止,它只是从 TextFrame 中逐段剪切,然后粘贴到同一个 TextFrame 上。它接近于做我需要的事情,但我似乎无法在主循环中找到 select 新框架的方法。我评论了我正在努力工作的可能解决方案。

也许我也使用了错误的 cut/paste 功能?也许修改第二个 link 解决方案以接受 .docx 更容易?

RisingFog's solution and Eugeny Budantsev solition 之间的重要区别在于与用户的交互。以前的脚本显示对话框 window 并保持 运行ning 直到您关闭 window。稍后 运行 仅一次,无法继续跟踪用户操作。

所以如果你想保留你的脚本 运行ning(并做一些对用户操作的反应)你需要显示一些 window 即使 window 将是空的。像这样:

#targetengine session

var dialog = new Window("palette", undefined, undefined);
    dialog.preferredSize.width = 200;
    dialog.preferredSize.height = 50;
    dialog.text = "Select next frame";
    dialog.onClose = function() {
        doc.removeEventListener('afterSelectionChanged', selectionChanged);
    }

dialog.show();

var doc = app.activeDocument;
doc.addEventListener('afterSelectionChanged', selectionChanged);

function selectionChanged() {

    // here is the code that will run wenever you change selection

    if (doc.selection[0] instanceof TextFrame
        && doc.selection[0].contents == ''
        && doc.selection[1] == null) {
        alert('Next empty text frame is selected!')
    }
}

当然你可以用一些文字或按钮填充window。

更新

下面是如何从 selected 非空文本框(假设它是文本脚本)中剪切第一段并将该段落自动粘贴到下一个 selected 空框的示例:

#targetengine session

var dialog = new Window("palette", undefined, undefined);
    dialog.preferredSize.width = 300;
    dialog.preferredSize.height = 50;
    dialog.text = "Please, select next frame";
    dialog.onClose = function() {
        doc.removeEventListener('afterSelectionChanged', selectionChanged);
    }

    dialog.add("statictext", undefined, "Last cutted text:");

var msg = dialog.add("edittext");
    msg.text = "";
    msg.characters = 40

dialog.show();

var doc = app.activeDocument;
doc.addEventListener('afterSelectionChanged', selectionChanged);

function selectionChanged() {

    var sel = doc.selection[0];

    if (sel instanceof InsertionPoint) sel = sel.parent.textContainers[0];

    if (sel instanceof TextFrame || sel instanceof Story) {

        if (sel.contents != '') {
            app.select(sel.paragraphs[0], SelectionOptions.REPLACE_WITH);
            msg.text = sel.paragraphs[0].contents;
            app.cut();
            app.selection = null;
        }
        else {
            sel.texts.everyItem().select();
            app.paste();
            app.selection = null;

            // remove '\r' at the very end of text in the frame
            app.findGrepPreferences.findWhat ="\r$";
            app.changeGrepPreferences.changeTo = "";
            sel.changeGrep();

        }
    }
}

更新 2

这是相同的脚本。唯一不同的是,您不再需要单击文本脚本框架。在 运行 脚本之前,您需要 select 文本框,然后每次单击任何空文本框时,脚本都会自动从该框架中剪切第一段。

#targetengine session

var dialog = new Window("palette", undefined, undefined);
dialog.preferredSize.width = 300;
dialog.preferredSize.height = 50;
dialog.text = "Please, select next frame";
dialog.onClose = function() {doc.removeEventListener('afterSelectionChanged', selectionChanged)}

dialog.add("statictext", undefined, "Last copied text:");

var msg = dialog.add("edittext");
msg.text = "";
msg.characters = 40;

// --- here is the Pause button
var pause = false;
var pause_btn = dialog.add("button", [10,10,300,30], "Pause");
pause_btn.onClick = function() {
    pause = !pause;
    // if (pause) msg.text = "[PAUSED] " + msg.text; // it can be done better, but it works, too
    // if (!pause) msg.text = msg.text.replace(/^\[PAUSED\] /, "");
    pause_btn.text = pause ? "Resume" : "Pause"; // this is way better
};
// ---

var doc = app.activeDocument;
var master_frame = app.selection[0]; // <-- the Text Script frame

if (master_frame instanceof TextFrame || master_frame instanceof Story) {
    dialog.show();
    app.selection = null;
    doc.addEventListener('afterSelectionChanged', selectionChanged);
} else {
    alert("Please, select a frame with text before run the script!");
    exit();
}

function selectionChanged() {

    if (pause) return; // <-- here you check the state of the button

    var sel = doc.selection[0];

    if (sel instanceof InsertionPoint) sel = sel.parent.textContainers[0];
    if (sel instanceof TextFrame || sel instanceof Story) {

        if (sel.contents == '' && master_frame.contents != '') {

            app.select(master_frame.paragraphs[0], SelectionOptions.REPLACE_WITH);
            msg.text = master_frame.paragraphs[0].contents;
            app.cut();
            app.selection = null;
            sel.texts.everyItem().select();
            app.paste();
            app.selection = null;

            // remove '\r' at the end
            app.findGrepPreferences.findWhat ="\r$";
            app.changeGrepPreferences.changeTo = "";
            sel.changeGrep();

        }

        if (master_frame.contents == '') alert ("No text to paste anymore!")
    }
}

我已将 'Pause' 按钮添加到 window。