问题描述
我目前正在使用Google表格来跟踪/维护一些文本翻译的项目(实际上是一些元数据,然后是原始文本和翻译的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>","\n\n"); // 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("\n\n"); // 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 += '\n\n'; // If we're not on the last box,add the double new line
}
return output;
}
我用=preview(<CELL>)
来称呼它(getCharacterWidth只是从字符宽度映射中提取一个整数)。
此功能适用于不包含任何粗体或斜体字符的原始文本。
问题在于,粗体和斜体字符通常比普通字符占用更多的空间,并且在某些情况下,会导致预览的输出文本错误地省略应该包含一些换行符的换行符。
例如,原始文本为:
这是斜体。这是粗体。这是 粗体和斜体 。
=预览(文本) 应该 理想情况是:
这是 italic 。
这是粗体。
这是 粗体
和斜体 。
但是相反,它可能最终像这样:
这是斜体的。
这是粗体。这个
是粗体和斜体。
由于未考虑粗体/斜体字符的额外宽度,因此该函数认为它有足够的空间来容纳行中的另一个单词。
我不能输出就可以了,但是至少我需要能够识别出什么文本是粗体或斜体。在Google表格中,我该如何编写支持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()或.IsItalic()的运行,我可以说明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);
}