5

我正在尝试使用 inDesign JSX 脚本将以下数据插入到文档中:

data = [{heading:"Heading 1", content: ["Some content"]},
 {heading:"Heading 2", content: ["Some other content with", "Multiple paragraphs"]}]

数据必须放置在单个 TextFrame 中,但标题和内容的样式不同。

我可以看到添加文本的唯一方法是一次性通过textFrame.contents变量:

allContent = "";
headingParagraphs = []; // keep track of which paragraphs are headings
paragraph = 0;
for (var i = 0; i < data.length; i++) {
  allContent += data.heading + "\r"; // Use a newline to split the paragraph
  headingParagraphs.push(paragraph);
  paragraph++;
  for (var j = 0; j < data.content.length; j++) {
    allContent += data.content[j] + "\r"; // Use a newline to split the paragraph
    paragraph++;
  }
}
textFrame.contents = allContent; // all data is in, but all text is styled the same

然后,一旦数据进入,我会迭代段落并为标题添加一些样式:

for (var i = 0; i < textFrame.paragraphs.count(); i++) {
  if (headingParagraphs.indexOf(i) != -1) { // this is a heading paragraph
    textFrame.paragraphs[i].pointSize = 20;
  }
}

这适用于适合一页的小型数据集,但一旦内容大于框架,则paragraphs仅返回可见段落。如果我继续使用新的 textFrame,段落会被拆分,并且headingParagraphs[]数组不再排列。

理想情况下,我想在附加下一个内容之前附加到内容并设置样式 - 但 API 文档不太清楚你如何做到这一点(如果有的话)

// Pseudo code:
for all sections:
  append the heading to the frame, split to next page if needed
  style all the *new* paragraphs as headings
  for all section contents
    append the content to the frame, split to next page if needed
    style any *new* paragraphs as normal content

有没有办法使用附加功能或其他方式在添加内容后将标题分配到正确的位置来实现这一点?也许内容中的特殊字符来定义样式?

4

1 回答 1

6

您的较长文本会变得混乱,因为目前您正在单个文本框架内工作。一旦文本用完这一框架,您就不能再将它们称为这一框架的“拥有”段落。改为使用parentStory,因为它指向整个故事,在一个文本框架内或跨越多个文本框架。如果文本出现溢出,它也会继续工作。

因此,如果您有一个名为 的起始框架textFrame,请设置一个新变量并使用它来添加文本storytextFrame.parentStory

至于向这个框架(/故事)添加文本:确实,没有快速的方法来添加格式化文本。设置contents仅适用于具有相同格式的长条带。我使用的一种方法是将 INX 格式的文本写入临时文件并导入。短片段的速度很慢,但是可以在 Javascript 本身中非常有效地创建更大的故事(最多数百页),然后将其导入 ID 是.. 嗯,它并不,但比尝试“手动”完成要快.

另一种方法是一次添加一个段落的内容。诀窍是设置格式并将文本添加到story.insertionPoints[-1]. 这以一种特别方便的符号表示,指的是故事的最后一个文本插入点。您可以将插入点视为“文本光标”;您可以对其“应用”格式,然后添加的任何文本也将具有此格式。

您的代码片段经过重新设计,一次添加一项data

for (var i = 0; i < data.length; i++)
{
    story.insertionPoints[-1].pointSize = 20;
    story.insertionPoints[-1].contents = data[i].heading + "\r"; // Use a newline to split the paragraph
    story.insertionPoints[-1].pointSize = 10;
    for (var j = 0; j < data[i].content.length; j++)
    {
        story.insertionPoints[-1].contents = data[i].content[j] + "\r"; // Use a newline to split the paragraph
    }
}

需要注意的一件事是,您不能暂时覆盖pointSize此处。如果将其设置为更大的尺寸,则还必须再次将其设置回原始尺寸(我的代码段中的“10”)。

我可以说服您考虑使用段落样式吗?使用段落样式,你会有类似的东西

hdrStyle = app.activeDocument.paragraphStyles.item("Header");
textStyle = app.activeDocument.paragraphStyles.item("Text");

for (var i = 0; i < data.length; i++)
{
    story.insertionPoints[-1].contents = data[i].heading + "\r"; // Use a newline to split the paragraph
    story.insertionPoints[-2].appliedParagraphStyle = hdrStyle;
    for (var j = 0; j < data[i].content.length; j++)
    {
        story.insertionPoints[-1].contents = data[i].content[j] + "\r"; // Use a newline to split the paragraph
        story.insertionPoints[-2].appliedParagraphStyle = textStyle;
    }
}

请注意,这里值得反转插入内容和应用格式。这样任何以前的“临时”格式都会被清除;以这种方式应用段落样式会覆盖任何和所有本地覆盖。由于您必须将样式应用于一段(您刚刚插入的硬返回之前的那个),您将insertionPoints[-2]在此处使用。

与本地格式相比,使用样式的优点数不胜数。您可以使用单个命令应用您想要的所有格式,安全地删除所有本地覆盖的格式,如果您对它不满意,可以全局更改格式的任何部分,而不必使用稍微不同的设置重新运行脚本。

于 2014-06-02T08:47:34.153 回答