HTML 中, sup 緊接 bdo dir rtl 時為何會排到 bdo 左邊去?

時間 2021-05-30 19:50:07

1樓:梁海

截圖中的奇怪順序和 、 元素一點關係都沒有,純粹是因為 。你那數字「123」不管是放在 裡還是 裡還是不用任何標籤,只要在同一段落內和前面那些強制 RTL 的文字相鄰就會受影響。

元素的功能是覆蓋掉 Unicode 字元預設的書寫方向。當你使用 ,其內部字元的書寫方向就被強制設定成了 RTL,不再遵循 Unicode 的判斷演算法。這段 RTL 文字後面跟著的空格和數字(weak type)也和這段 RTL 文字一起從右向左排,所以就跑到它左邊去了。

數字內部的字元順序不會顛倒(因為在阿拉伯語、希伯來語等 RTL 書寫系統中,數字都是 LTR 的)。

「abc X 123 def」這段文字,如果我把其中的「X」換成乙個阿拉伯字母「 」就會有問題中這種情況,如果把數字改成字母就不會:abc X 123 def

abc 123 def

abc GHI def數字和拉丁字母的書寫方向性質不同,數字(weak type)會受相鄰 RTL 文字的影響,而拉丁字母(strong type)不會。具體演算法詳見下文。

至於解決方案,因為不知道你到底為什麼要用 ,所以也不知道該怎麼處理你的情況。

W3C 有一篇文件題為〈Authoring HTML: Handling Right-to-left Scripts〉[0-1],詳細介紹了在 HTML 中應當如何處理 bidi 文字。這篇文章比較淺顯,也比較實用,推薦所有需要處理 bidi 文字的 HTML 開發者閱讀。

〈7.2 Weak/neutral characters at the edge of a directional run〉這一節 [0-2] 舉的例子和問題類似,基本處理方法就是給位置出錯的 weak type 文字加上明確的 dir 屬性(注意,不是加 ,是在 這樣普通的元素上加 dir)。

以下簡介 Unicode Bidirectional Algorithm 的相關知識,主要都來自〈Unicode Standard Annex #9〉[1-1],恐怕沒什麼人會感興趣,但我還是順便整理出來吧:

元素的功能詳見文件 [1-2],其中這句話很明確:If the element's dir attribute is in the ltr, then for the purposes of the bidirectional algorithm, the user agent must act as if there was a U+202E RIGHT-TO-LEFT OVERRIDE character at the start of the element, and a U+202C POP DIRECTIONAL FORMATTING at the end of the element.[1-1] Unicode Standard Annex #9:

HTML 文件中提到了兩個字元:U+202E RIGHT-TO-LEFT OVERRIDE 簡稱 RLO [2-1]

(當然,另有 U+202D LEFT-TO-RIGHT OVERRIDE 簡稱 LRO)

U+202C POP DIRECTIONAL FORMATTING 簡稱 PDF [2-2]

LRO 和 RLO 是 Unicode 的兩個「explicit embedding code」之一,它們會把文字流中自己後面的所有字元都強制設定為 RTL,直到 PDF 這個「terminating explicit directional code」來中止。

所以 的作用就是強制其內部的書寫方向為 RTL,不管那些文字預設是什麼方向(比如,拉丁字母預設是 LTR,阿拉伯字母預設是 RTL)。

Unicode Bidirectional Algorithm(UBA)很強大的一點就是:它不簡簡單單是把字元分成 LTR 和 RTL,而是把字元分成很多種 bidirectional character type,然後根據不同 type 的不同性質以及各種不同的書寫方向巢狀情況來決定當前字元到底該用什麼方向。於是 [3-1]:

拉丁字母都是 L 這一 type 的,而希伯來字母是 R,阿拉伯字母是 AL,這三個 type 都屬於 strong type,它們直接決定自己的書寫方向,除非被 explicit embedding code 這類事情影響;

歐洲數字(UBA 文件中用「European number」這個說法來把 123… 和阿拉伯世界用的數字 … 分開)屬於 weak type 中的 EN,它的書寫方向和上下文有關;

而空格屬於 neutral(中性)的 WS 一類,完全依賴上下文來確定自己的書寫方向。

UBA 對文字流做一系列處理來得出每乙個字元所處的 embedding level。偶數 level 表示 LTR,奇數 level 表示 RTL。[4-1]

如果我有一段英文,其中有一段阿拉伯文,阿拉伯文中又有一段英文——那麼最外層英文的 level 為 0,阿拉伯文的 level 為 1,內層英文的 level 為 2。這就是 embedding。每次反轉書寫方向都巢狀一層。

乙個段落的初始 level 為 0(不過如果一開頭就是 R 或 AL 字元那麼這個段落的 level 就是 1)。

上文說的「LRO 會把文字流中自己後面的所有字元都強制設定為 RTL」實際上是把後面的字元都設定為 R 這個 strong type(書寫方向為 RTL),並且使 embedding level 增大到下乙個奇數。[4-2]

我們構造乙個例子:ab cd 12 ef處理 RLO–PDF 之後,這段文字的 bidirectional character type 和 embedding level 就成了:[L-L-WS]-[R-R]-[WS-EN-EN-WS-L-L]

[0-0-0-[1-1]-0-0-0-0-0-0]處於同一 level 的連續字元分入乙個 run,於是我們有了「L-L-WS / 0-0-0」(ab )、「R-R / 1-1」(cd)和「WS-EN-EN-WS-L-L / 0-0-0-0-0-0」( 12 ef)這三個 run。問題的關鍵在於「 12 ef」(WS-EN-EN-WS-L-L / 0-0-0-0-0-0)這個 run 會怎麼處理,這裡面的 WS 和 EN(乙個 neutral 和乙個 weak type)是變數。

「1-1」和「0-0-0-0-0-0」相鄰,於是「0-0-0-0-0-0」這個 run 的 sor(start-of-level-run)由 level 較高的 run 決定,為 R。(這一步判斷的依據詳見文件 [5-1])

「WS-EN-EN-WS-L-L」的第乙個字元 WS(空格)左邊是等價為 R 的 sor,右邊是等價為 R 的 EN,所以 WS 變成 R。(這一步變化的依據詳見文件 [5-2])

這個 R 類空格落在當前 level 為 0 的區域了,level 要加 1;兩個 EN 也落在當前 level 為 0 的區域了,level 要加 2。(這一步變化的依據詳見文件 [5-3])

加上其他字元的判斷,embedding level 序列變成了:ab cd 12 ef

[0-0-0-[1-1-1-[2-2]]-0-0-0]每一次 embedding level 增大都會多翻轉一下字串行 [6-1],所以原來的「ab cd 12 ef」變成了:ab 12 dc ef* * *

題主自己搞不清問題本質就試圖草率總結,然後還自我感覺良好地阻止別人把問題理清(「細節越多越侷限,禁止更改!」),這是很糟糕的提問方式。

感謝 @Tutu-Lux 細心的測試。

* * *

答案 #1023

為何東晉南朝時江東人物名字中多帶 之 字?除此以外還有哪些當時名字不避諱的字?

越石賦扶風 陳寅恪在文裡猜測和道教有關係,然而這個解釋其實是有商榷的餘地的,在這裡再補充幾點猜測。魏斌認為 東漢人名呈現出明顯的分層,上層人名是單名,底層人名單名 雙名並存。這種情況亦存在於南方的巴蜀 吳越地區。在這種背景下觀察,長沙走馬樓吳簡整齊的單名引人矚目。楚秦至西漢前期,楚地編戶民同樣單名 ...

為何部分字型中 f 與 i 相連時 i 的點會被 吞 ?

合字 連字 ligature 連字 Ligature 那些事兒 Vivaldi 這是利用OpenType特性製作的合字。我們都知道,很多字型特別是很多經典款襯線體,其字母f的鉤比較寬,而字母i擁有比較高的x height,再加上圓點的存在,f和i排在一起的時候就會撞在一起,不僅看起來不夠乾淨,而且會...

《知否》中顧廷煜和顧廷燁宗祠託付後事時,為何不承認顧二在軍中的奮鬥?

文 竹英 顧廷煜,是寧遠侯府的嫡長子,是顧廷燁的哥哥,是後來的寧遠侯府。他的生母大秦氏,生下他沒多久就去世了,他從小體弱多病,是個病秧子。在原著中對顧廷煜的外貌有這樣一段描述 顧廷煜雖病得奄奄一息,枯槁瘦弱得只剩下一把骨頭了,眉眼卻與秦太夫人很是相似,且更為秀美精緻。就連盛明蘭第一次見到顧廷燁也感到...