谷歌表格应用程序脚本-自定义功能,以查找RichText(粗体/斜体)位置



我目前正在进行一个项目,该项目使用Google Sheets来跟踪/维护一些文本翻译(实际上是一些元数据,然后是原始文本和翻译的2列(。

最后的应用程序有一些换行约束和可变宽度字体,所以我在应用程序脚本中创建了一个自定义函数来应用换行符,以便于可视化它的外观。

function preview(text)
{
if(text.startsWith('=')) // Copy of something else, so we don't care
return text;
text = text.trimEnd();
text = text.replace("<4A>", "nn"); // For the sake of the preview, just treat <4A> as a new box
text = text.replace(/<&[a-zA-Z0-9]+>/g,"────────"); // Assume the longest length (8 * 8)
text = text.replace(/<*.>/g,""); // Get rid of exit codes
text = text.replace(/<S.+?>/g,""); // Get rid of special effects

var output = "";
var boxes = text.split("nn"); // Double newline is a forced new text box
for (var i = 0; i < boxes.length; i++)
{ // For each intentional text box
var box = boxes[i];
box = box.replace("<4E>","n"); // Will technically forcibly always draw on the second line

var lines = box.split('n');
var newboxFlag = false; // Flag to indicate if we draw a new line or new box
for (var j = 0; j < lines.length; j++)
{ // For each intentional line in this box
words = lines[j].split(' ');
var word = "";    
var currentLineLen = 0;
for(var k = 0; k < words.length; k++)
{
word += words[k];

var wordWidth = 0;
for (var l = 0; l < word.length; l++)
{
var char = word.charAt(l);
wordWidth += getCharacterWidth(char);
}
if(wordWidth + currentLineLen > 0x89)
{ // This word won't fit on this line, so it goes to a new line

// Strip the first space, and just assume we don't have a string longer than 136 characters
word = word.substr(1);
wordWidth -= getCharacterWidth(' ');

// Add a new line and flip the newboxFlag
output += 'n';
if(newboxFlag) output += 'n';
newboxFlag ^= 1;
currentLineLen = 0;
}

currentLineLen += wordWidth
output += word;
word = " ";
}

if (j != lines.length - 1)
{
output += 'n';  // line length is reset at the top
if(newboxFlag) output += 'n';
newboxFlag ^= 1;
}
}
if(i != boxes.length - 1) output += 'nn'; // If we're not on the last box, add the double new line
}
return output;
}

我用=preview(<CELL>)来调用它(getCharacterWidth只是从字符<->宽度映射中提取一个整数(。

此函数适用于不包含任何粗体或斜体字符的原始文本。

问题是,粗体和斜体字符通常比普通字符占用更多的空间,在某些情况下,会导致预览的输出文本错误地省略了应该有的换行符。

例如,原始文本为:

这是斜体。这是粗体。这是粗体和斜体

=预览(文本(应该理想情况下类似于:

这是斜体

这是粗体

这是bold

和italic

但相反,它可能会变成这样:

这是斜体。

这是粗体。这个

为粗体和斜体。

由于没有考虑粗体/斜体字符的额外宽度,该函数认为它有足够的空间在行上容纳另一个单词。

如果我不能输出它也可以,但我至少需要能够识别哪些文本是粗体或斜体。在Google Sheets中,如何编写一个了解RichText的自定义函数?

感谢TheMaster的评论,我能够通过将函数更改为以下内容来创建解决方案:

function preview(startcol, startrow)
{
var str = String.fromCharCode(64 + startcol) + startrow;
var richtext = SpreadsheetApp.getActiveSpreadsheet().getRange(str).getRichTextValue();
var runs = richtext.getRuns();
...

并将我的呼叫设置为

=preview(COLUMN(<CELL>), ROW(<CELL>))

通过循环计算getTextStyle((.IsBold((或.IsIItalic((的运行,我可以计算RichText属性。

if(runs[i].getTextStyle().IsBold() && runs[i].getTextStyle().IsItalic())
{
wordWidth += getCharacterWidthBoldItalic(char);
}
else if(runs[i].getTextStyle().IsBold())
{
wordWidth += getCharacterWidthBold(char);
}
else if(runs[i].getTextStyle().IsItalic())
{
wordWidth += getCharacterWidthItalic(char);
}
else
{
wordWidth += getCharacterWidth(char);
}

最新更新