gpt4 book ai didi

google-apps-script - Google (Docs) Apps 脚本 - 无法检查光标是否在命名范围内

转载 作者:行者123 更新时间:2023-12-05 05:10:10 25 4
gpt4 key购买 nike

我正在向文档中插入文本,每次插入的文本都被添加到一个命名范围内,这样我就可以使用 getNamedRanges(NAME) 查找它们。和 getNamedRangesById(ID) .

现在我需要检查当前光标位置是否在命名范围内,我还没有弄清楚如何。

这篇文章是相似的: How to determine the named range from position in Google Docs through Google Apps Script

但是当光标在命名范围上时 cursor.getElement()返回 Text对象,而不是命名范围。

如何确定光标当前是否位于命名范围内?

最佳答案

  • 您想确认当前光标位置是否在 Google Document 的命名范围内。
  • 您想使用 Google Apps 脚本实现这一目标。

解决方法:

在此解决方法中,我通过比较 namedRange 和光标位置的段落索引来检查光标位置是否包含在 namedRange 中。

流程:

脚本的流程如下。

  1. 检索命名范围段落的索引。
    • 在这个示例脚本中,根据您的问题,使用了 namedRange ID。
    • 在这种情况下,可能会有多个段落,包括表格、列表等。因此检索了 namedRange 中的所有索引。
  2. 检索光标所在段落的索引。
  3. 检索所选范围的段落索引。
    • 此示例脚本还检查所选范围是否在命名范围内。因为当文本被选中时,cursor 变为 null
  4. 如果光标或选定范围停留在命名范围内,myFunction() 返回 true
    • 如果光标或选定范围不在命名范围内,myFunction() 返回 false
    • 您也可以在日志中确认。

示例脚本:

在你使用这个脚本之前,请设置namedRange ID。

function myFunction() {
var nameRangeId = "###"; // Please set namedRange ID here.

var getIndex = function(doc, e) {
while (e.getParent().getType() != DocumentApp.ElementType.BODY_SECTION) e = e.getParent();
return doc.getBody().getChildIndex(e);
};
var doc = DocumentApp.getActiveDocument();

// For namedRange
var namedRange = doc.getNamedRangeById(nameRangeId);
if (namedRange) {
var indexOfNamedRange = namedRange.getRange().getRangeElements().map(function(e) {return getIndex(doc, e.getElement())});
} else {
throw new Error("No namedRange.");
}

var name = namedRange.getName();

// For cursor
var cursor = doc.getCursor();
if (cursor) {
var indexOfCursor = getIndex(doc, cursor.getElement());
if (~indexOfNamedRange.indexOf(indexOfCursor)) {
Logger.log("Inside of %s", name);
return true;
}
Logger.log("Outside of %s", name);
return false;
}

// For select
var select = doc.getSelection();
if (select) {
var indexOfSelect = select.getRangeElements().map(function(e) {return getIndex(doc, e.getElement())});
if (indexOfSelect.some(function(e) {return ~indexOfNamedRange.indexOf(e)})) {
Logger.log("Inside of %s", name);
return true;
}
Logger.log("Outside of %s", name);
return false;
}

throw new Error("No cursor and select.");
}

注意事项:

  • 在此脚本中,当在 Document 上选择文本时,无法检索光标位置。所以我添加了检查所选范围的功能。如果不想勾选选中范围,请去掉//For select脚本。
  • 在此脚本中,即使所选范围内只有一个索引包含在namedRange 中,也会返回true。关于这一点,请根据您的情况进行修改。
  • 在当前阶段,此脚本不假设页眉和页 footer 分。

引用资料:

添加:

我了解到,从这种情况来看,OP已将命名范围设置为该段落。当我为此提出示例脚本时,我认为我正确理解了 OP 的目标。但是,来自 gaspar's following comment ,

this only shows whether the cursor is in the same element as the named range, but in case of named range partial text it gives a false positive finding if the cursor is in the same element but not in the same text part

如果OP将段落的一部分设置为命名范围,并且OP要检查光标是否包含在命名范围内,示例脚本如下。

示例脚本:

function myFunction() {
var nameRangeId = "###"; // Please set namedRange ID here.

var getIndex = function (doc, e) {
while (e.getParent().getType() != DocumentApp.ElementType.BODY_SECTION) e = e.getParent();
return doc.getBody().getChildIndex(e);
};
var doc = DocumentApp.getActiveDocument();

// For namedRange
var namedRange = doc.getNamedRangeById(nameRangeId);

if (namedRange) {
var indexOfNamedRange = namedRange.getRange().getRangeElements().map(e => ({ idx: getIndex(doc, e.getElement()), start: e.getStartOffset(), end: e.getEndOffsetInclusive() }));
} else {
throw new Error("No namedRange.");
}
var name = namedRange.getName();

// For cursor
var cursor = doc.getCursor();
if (cursor) {
var indexOfCursor = getIndex(doc, cursor.getElement());
var offset = cursor.getOffset();
if (indexOfNamedRange.some(({ idx, start, end }) => idx == indexOfCursor && ((start == -1 && end == -1) || (offset > start && offset < end)))) {
Logger.log("Inside of %s", name);
return true;
}
Logger.log("Outside of %s", name);
return false;
}

// For select
var select = doc.getSelection();
if (select) {
var indexOfSelect = select.getRangeElements().map(e => ({ idx: getIndex(doc, e.getElement()), start: e.getStartOffset(), end: e.getEndOffsetInclusive() }));
if (indexOfSelect.some(e => indexOfNamedRange.some(({ idx, start, end }) => idx == e.idx && ((start == -1 && end == -1) || ((e.start > start && e.start < end) || (e.end > start && e.end < end)))))) {
Logger.log("Inside of %s", name);
return true;
}
Logger.log("Outside of %s", name);
return false;
}

throw new Error("No cursor and select.");
}
  • 当我发布答案时,Google Apps 脚本无法使用 V8 运行时。但是,现在可以使用 V8 运行时了。所以我使用 V8 运行时修改了脚本。请注意这一点。

关于google-apps-script - Google (Docs) Apps 脚本 - 无法检查光标是否在命名范围内,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56951578/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com