iT邦幫忙

2022 iThome 鐵人賽

DAY 7
0
Software Development

譯者會消失嗎?Maybe, but not today —— 你,才是更好的翻譯師系列 第 7

嚇死寶寶了,今天差點開天窗之分句功能

  • 分享至 

  • xImage
  •  

我太小看這個分句功能了。
結果一直忙到晚上十點多,
好不容易才把程式碼初步搞定。

話說這個 html 的分句功能,
最難纏的就是各式各樣的 html 標籤。

這些標籤功能繁多,各有不同的特性。
(若以 nodeType 來區分,可參考 MDN 的文件

不過在分句的考量上,大致可分成兩大類。

  • inline 行內標籤:我喜歡叫它 span 類標籤。遇到這種標籤,可以把它當成句子裡的一部分,不用急著分句斷行。
  • block 區塊標籤:我喜歡叫它 div 類標籤。只要一遇到這種標籤,前後就要進行分句斷行。
// 行內標籤:參見 https://www.w3schools.com/html/html_blocks.asp
inline_tags = [
    'span', 'a', 'em', 'b', 'i', 'big', 'small', 
    'br', 'strong', 'sub', 'sup', 'tt', 'abbr',
    'img',
    'acronym', 'bdo',  'dfn', 'kbd', 'map', 
    'object', 'output', 'q', 'samp', 'time',
    'var', 'cite',
    'nobr',
];

// 區塊標籤:參見 https://www.w3schools.com/html/html_blocks.asp
block_tags= [
    'html', 'head', 'body',
    'section', 'nav', 'main', 'footer',
    'div', 'table', 'thead', 'tbody', 'tfoot', 
    'tr', 'ul', 'ol', 'hr', 'colgroup', 'col', 'dl',
    'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 
    'caption', 'th', 'td', 'li', 'dd', 'dt',
    'form', 'header',
    'address', 'article', 'aside', 'blockquote', 
    'canvas', 'fieldset',
    'figcaption', 'figure',
    'label',
    'button', 'input', 'select', 'textarea',
    // txt 檔案若在瀏覽器中開啟,其內容會被包在 pre 裡頭。。。
    'pre',
    // 下面是 Google Cloud Document 用到的一些特殊 tag
    'devsite-header', 'devsite-content', 'devsite-toc', 
    'devsite-footer-linkboxes', 'devsite-footer-utility',
    'devsite-language-selector', 'devsite-select',
    // 下面這些註解起來的,都會變成不明 tag,不會進行分句處理
    // 'code',
    // 'script',
    // 'video',
    // 'noscript',
];

這些 HTML 標籤還有另一個很難處理的特性,
那就是大部分標籤通常會包住另一堆標籤,
形成層層相嵌的 DOM 樹狀結構。

在進行分句時主要針對的是文字,
但 HTML 所有的標籤會形成 DOM 這樣的結構。
為了對付這種一層包著另一層的結構,
我採用了遞迴的做法。

這樣的做法也許會犧牲一點效能,
但程式碼會簡潔很多,
讀起來也比較容易理解。

為了進行分句,
我創造了一個全新的 sent 標籤。
在每一個句子的前後,
都用這個 sent 標籤包了起來。

這麼做有很多好處。
實際上不過分的說,
將來有很多很厲害的功能,
都是靠它來實現的。

所以我另外針對這個 sentTag.js,
建立了一個獨立的小專案:

git clone https://github.com/betterTrans/sentTag

這個小專案也歡迎大家一起參與,
讓 HTML 的分句功能越來越棒囉 ^_^

我們只要把這個 sentTag.js 複製到
之前 betterTranslation 目錄裡的 js 子目錄,
然後修改一下 manifest.json,
把 sentTag.js 添加到 content_scripts 的列表中:

    "content_scripts": [ {
        "matches": ["<all_urls>"],
        "js": [
            "js/sentTag.js",
            "js/content.js"
        ]
    } ]

最後在 content.js 按下 Alt+1 的程式區塊中,
添加一行程式碼:

if (e.altKey && e.key=='1') {
    // 備份原始 HTML
    body0 = document.body.innerHTML;

    // 分句
    document.body.innerHTML = addSentTag2HTML(document.body.innerHTML);

}

重新載入外掛之後,按下 Alt+1,
整個網頁就完成分句的工作了。。。

什麼?看不出來?
沒錯,雖然我們完成了分句,
添加了許多 sent 標籤,
整個網頁的外觀卻不會有任何的變動。

某種程度來說,
我們就是希望這個分句的動作,
不要影響到原本的網頁內容。

但這個分句完成的網頁,
究竟有什麼用途呢?

我們今天就先小試身手一下,
為每一個 sent 標籤加上 title 的屬性吧。

只要在剛才分句的程式碼下面,
添加一小段程式碼:

    // 添加 title 屬性
    document.querySelectorAll("sent").forEach((node)=>{
        node.title = node.textContent;
    });

是的,這樣就完成了。

程式修改完之後,別忘了重新載入外掛。

重新載入之後,你只要再次按下 ALT+1,
接著移動到網頁的任何一個句子上,
都會自動浮現出這個句子的原文了。

https://ithelp.ithome.com.tw/upload/images/20220923/201152412saYHCF86i.png

有了 sent 標籤之後,
我們就能以句子為單位,
進行各式各樣的處理了。

明天我們就來好好善用這個 sent 標籤,
看看能玩出什麼樣的花招囉。


上一篇
「生命就像酥炸球,可以讓你吃飽飽,但你的心總想要更多。」
下一篇
分句好好用!中英對照閱讀終於完善啦!
系列文
譯者會消失嗎?Maybe, but not today —— 你,才是更好的翻譯師30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言