如何使用 html <ruby> 标签在 Swift 4 中用于日文字符

How to Use html <ruby> tags in Swift 4 for Japanese Characters

我需要为 Swift 中的日语字符使用 html 标签。

我一直在使用以下字符串扩展:

extension String{
func convertHtml() -> NSAttributedString{
    guard let data = data(using: .utf8) else { return NSAttributedString() }
    do{
        return try NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil)
    }catch{
        return NSAttributedString()
    }
}

然后使用 textView 进行如下测试:

textView.attributedText = "<!DOCTYPE html><html><body>これは<ruby>日<rt>に</rt>本<rt>ほん</rt>語<rt>ご</rt></ruby>です。</body></html>".convertHtml()

实际应该是这样的:

これは<ruby>日<rt>に</rt>本<rt>ほん</rt>語<rt>ご</rt></ruby>です。

但它最终看起来像这样。它没有正确排列,每次使用 ruby 标签后都会出现奇怪的换行符。

有没有我做错了什么,以及解决这个问题的方法?

谢谢!

日语文字的整行应该用<ruby>标签括起来。这是因为 <ruby> 元素设置了自己的内联上下文,但它的 sub-elements 例如 <rb><rt><rp><rtc>还设置了自己的上下文,例如 'block',只有当整行包含在 <ruby> 元素中时才真正有意义。

<!DOCTYPE html>
<html>
    <head>
        <!-- In case you'd like to try opening this page in desktop Safari! -->
        <meta charset="UTF-8">
    </head>
    <body>
        <ruby>
            <rb>これ</rb><rt></rt>
            <rb>は</rb><rt></rt>
            <rb>日</rb><rt>に</rt>
            <rb>本</rb><rt>ほん</rt>
            <rb>語</rb><rt>ご</rt>
            <rb>です</rb><rt></rt>
            <rb>。</rb><rt></rt>
        </ruby>
        <span>But this <em>isn't</em> Japanese.</span>
    </body>
</html>

我发现最好明确说明 每个 <ruby> sub-element,并且每个 <rb> (ruby 基础文本)与相应的 <rt>(ruby 转录)。当然,它看起来更冗余,更不干净,但它更语义化,您可以确定它在所有浏览器中看起来都一样。

显示 HTML 有效的编辑

下面,我提供了它工作的屏幕截图。这是我调用它的方式:

let webView: WKWebView = WKWebView(frame: self.view.frame, configuration: WKWebViewConfiguration())

webView.loadHTMLString(
    "<!DOCTYPE html><html><head><!-- In case you'd like to try opening this page in desktop Safari! --><meta charset=\"UTF-8\"></head><body><ruby><rb>これ</rb><rt></rt><rb>は</rb><rt></rt><rb>日</rb><rt>に</rt><rb>本</rb><rt>ほん</rt><rb>語</rb><rt>ご</rt><rb>です</rb><rt></rt><rb>。</rb><rt></rt></ruby><span>But this <em>isn't</em> Japanese.</span></body></html>",
    baseURL: nil
)

如果你copy-paste那个as-is,你还有运气吗?

题外话

似乎 UITextView 将所有 ruby 节点解释为具有块上下文。因此,我认为 UITextView/NSAttributedString 没有完全实现 HTML5 规范,或者它有错误,或者还有一些进一步的配置需要完成。无论哪种方式,正确显示此 ruby 文本的最简单方法是使用真正的 WKWebView (尽管我知道这有其自身的权衡,例如缺乏 text-to-speech 支持,并且时间明显增加用于渲染)。

这是我使用的一种简单方法。

<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
fg:before {
 content: attr(t);
 display: block;
    font-size: 50%;
    text-align: start;
 line-height: 1.5;
}

fg {
 display: inline-block;
 text-indent: 0px;
 line-height: normal;
    -webkit-text-emphasis: none;
 text-align: center;
 line-height: 1;
}
</style>
</head>
<body>
<fg t="わたし">私</fg>はケンです。<br><br>
</body>
</html>

看看这是否可行。它在我测试过的所有浏览器中都适用。