現在我們已經知道,Swift的帶屬性字串(AttributedString)可以用來「標示」(markup)一篇文章,例如將其中一部分文字(子字串)作為標題、某些標示為內文、某些以斜體表示...等等。被標示過的文字可稱為 “rich text”(富文字 — 有豐富屬性的文字),例如微軟公司的 Word 軟體編輯出來的文件,副檔名可用 .RTF — 代表 Rich Text Format。
不止文書處理軟體,一般的網頁文字內容其實也都有編排過,其文字背後都有「標示」,而且還有專門的「標示語言」來做網頁編排的工作,這個「標示語言」稱為 HTML(HyperText Markup Language, 超文本標示語言),如果檔案副檔名為 .htm 或 .html,就是用 HTML 編排過的文件。
微軟的 .RTF 格式是該公司專有的標示格式,HTML 則是全球資訊網(WWW)的官方標準,除此之外,網路上還流行一種「民間版」的標示語言,稱為 “Markdown”(常用副檔名為 .md),在程式設計圈內非常普遍,例如最大的開放原始碼網站 GitHub,文件幾乎都用 Markdown 格式撰寫。
HTML 與 Markdown 文件格式都非常簡單,簡單到可直接用文字編輯軟體來手工編排,兩者標示方式相當接近,還可透過軟體互相轉換。部分的常見標示範例如下表:
- | HTML | Markdown |
---|---|---|
標題(heading) | <h1>文件標題</h1> | |
<h2>次標題</h2> | ||
<h3>小標題</h3> | # 文件標題 |
| 斜體(italic) | <i>斜體文字</i> | 斜體文字 |
| 粗體(bold) | <b>粗體文字</b> | 粗體文字 |
| 刪除線(strikethrought) | <s>贅字應刪除</s> | 贅字應刪除 |
| 加連結(anchor/hyperlink) | <a href=”網址”>連結文字</a> | 連結文字 |
| 加圖片(image) | <img src=”網址”, alt=”圖說文字”> | |
從上表可以看出,HTML 用一對「角括號」來標示文字;而Markdown則習慣用標點符號 — 這顯然符合程式設計師的喜好。
AttributedString 物件能夠讀入Markdown格式的文件,不過很可惜,目前並非所有Markdown格式都支援,包括標題、底線、圖片等常用標示都暫時不支援,或許未來新版才會加入(還可能支援HTML或RTF等格式),如果發展成熟,用AttributedString物件就能開發出一套文書編輯軟體。
在以下範例4-2c中,用Markdown語法將字串中的地名標示為粗體、「泰耶魯」加上維基百科連結、還有一小句用刪除線測試。
這是我們第一次用「多行字串」,過去我們都是用一對雙引號來包含字串值(String literal),如果字串值很大(跨很多行),可以前後用「連續3個雙引號」來包含字串值,請參考以下範例。
// 4-2c Markdown 標示語言
// Revised by Heman, 2022/03/22
import PlaygroundSupport
import SwiftUI
let 雪山輯 = """
雪溶後 花香流過**司介欄溪**的森林
沿著長長的狹谷 成團的白雲壅著
獵人結伴攀向**司馬達克**去
採菇者領著赤足的婦女
在高寒的**賽蘭酒** 起一叢篝火
修好所有的籬 結新的筏
起得早早的小姑娘 在水邊洗日頭
少年的[泰耶魯](<https://zh.wikipedia.org/wiki/%E6%B3%B0%E9%9B%85%E6%97%8F>)唱出冬藏的歌
而卻不見了 ~~那著人議論的~~
那浪子麻沁
"""
var 帶屬性字串 = try AttributedString(markdown: 雪山輯, options: AttributedString.MarkdownParsingOptions(interpretedSyntax: .inlineOnlyPreservingWhitespace))
let 圖片網址 = "<https://storage.googleapis.com/opinion-cms-cwg-tw/article/201905/article-5cd90f7b737c2.jpg>"
struct 現代詩選: View {
let 動畫效果 = Animation.linear(duration: 12)
@State var 位移: CGFloat = 500
var body: some View {
ZStack {
AsyncImage(url: URL(string: 圖片網址)) { 狀態 in
if let 背景圖片 = 狀態.image {
背景圖片.opacity(0.25)
} else if 狀態.error != nil {
Image(systemName: "xmark.icloud.fill")
.scaleEffect(2)
.foregroundColor(.red)
} else {
ProgressView()
}
}
Text(帶屬性字串)
.font(.system(.title))
.offset(x: 0, y: 位移)
.animation(動畫效果, value: 位移)
.onAppear {
位移 = 0
}
}
}
}
PlaygroundPage.current.setLiveView(現代詩選())
從範例可以看出,Markdown的標示符號直接寫在字串裡面,是資料的一部分,而不像AttributedString的屬性必須寫程式碼才能設定。這樣的好處之一,就是Markdown文件可以由編輯人員另外處理,再透過網路或檔案輸入到Swift程式裡面,程式設計師就不用管文件編排的事情。
要用AttributedString讀入Markdown格式的文字內容,就只需增加一個 markdown 參數: