-
Notifications
You must be signed in to change notification settings - Fork 197
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support titles for links and images #42
base: master
Are you sure you want to change the base?
Changes from 4 commits
ac551ff
ebce0cd
a041d96
a0914fa
402e0b3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -9,6 +9,7 @@ internal struct Link: Fragment { | |||||
|
||||||
var target: Target | ||||||
var text: FormattedText | ||||||
var title: Substring? | ||||||
|
||||||
static func read(using reader: inout Reader) throws -> Link { | ||||||
try reader.read("[") | ||||||
|
@@ -19,20 +20,35 @@ internal struct Link: Fragment { | |||||
|
||||||
if reader.currentCharacter == "(" { | ||||||
reader.advanceIndex() | ||||||
let url = try reader.read(until: ")") | ||||||
return Link(target: .url(url), text: text) | ||||||
let url = try reader.readCharacters(matching: \.isLegalInURL) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
This helps fix the new failure of CommonMark tests 483 and 563: If both title and destination are missing, then this line encounters ")" immediately and throws, which ends link parsing. So instead of throwing, we assign |
||||||
|
||||||
guard !reader.didReachEnd else { throw Reader.Error() } | ||||||
var titleText: Substring? = nil | ||||||
if reader.currentCharacter.isSameLineWhitespace { | ||||||
try reader.readWhitespaces() | ||||||
try reader.read("\"") | ||||||
titleText = try reader.read(until: "\"") | ||||||
} | ||||||
try reader.read(")") | ||||||
return Link(target: .url(url), text: text, title: titleText) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Needed since |
||||||
} else { | ||||||
try reader.read("[") | ||||||
let reference = try reader.read(until: "]") | ||||||
return Link(target: .reference(reference), text: text) | ||||||
return Link(target: .reference(reference), text: text, title: nil) | ||||||
} | ||||||
} | ||||||
|
||||||
func html(usingURLs urls: NamedURLCollection, | ||||||
modifiers: ModifierCollection) -> String { | ||||||
let url = target.url(from: urls) | ||||||
let title = text.html(usingURLs: urls, modifiers: modifiers) | ||||||
return "<a href=\"\(url)\">\(title)</a>" | ||||||
let refTitle = target.title(from: urls) | ||||||
let linkText = text.html(usingURLs: urls, modifiers: modifiers) | ||||||
let finalTitle = refTitle ?? title | ||||||
var titleAttribute: String = "" | ||||||
if let finalTitle = finalTitle { | ||||||
titleAttribute = " title=\"\(finalTitle)\"" | ||||||
} | ||||||
return "<a href=\"\(url)\"\(titleAttribute)>\(linkText)</a>" | ||||||
} | ||||||
|
||||||
func plainText() -> String { | ||||||
|
@@ -53,7 +69,16 @@ extension Link.Target { | |||||
case .url(let url): | ||||||
return url | ||||||
case .reference(let name): | ||||||
return urls.url(named: name) ?? name | ||||||
return urls.url(named: name)?.url ?? name | ||||||
} | ||||||
} | ||||||
|
||||||
func title(from urls: NamedURLCollection) -> Substring? { | ||||||
switch self { | ||||||
case .url: | ||||||
return nil | ||||||
case .reference(let name): | ||||||
return urls.url(named: name)?.title | ||||||
} | ||||||
} | ||||||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -7,14 +7,29 @@ | |||||||||||||||
internal struct URLDeclaration: Readable { | ||||||||||||||||
var name: String | ||||||||||||||||
var url: URL | ||||||||||||||||
var title: Substring? | ||||||||||||||||
|
||||||||||||||||
static func read(using reader: inout Reader) throws -> Self { | ||||||||||||||||
try reader.read("[") | ||||||||||||||||
let name = try reader.read(until: "]") | ||||||||||||||||
try reader.read(":") | ||||||||||||||||
try reader.readWhitespaces() | ||||||||||||||||
let url = reader.readUntilEndOfLine() | ||||||||||||||||
|
||||||||||||||||
return URLDeclaration(name: name.lowercased(), url: url) | ||||||||||||||||
var titleText: Substring? = nil | ||||||||||||||||
let url = try reader.readCharacters(matching: \.isSameLineNonWhitespace) | ||||||||||||||||
|
||||||||||||||||
if !reader.didReachEnd { | ||||||||||||||||
if reader.currentCharacter.isNewline { | ||||||||||||||||
reader.advanceIndex() | ||||||||||||||||
} | ||||||||||||||||
if reader.currentCharacter.isSameLineWhitespace { | ||||||||||||||||
try reader.readWhitespaces() | ||||||||||||||||
} | ||||||||||||||||
if let delimeter = TitleDelimeter(rawValue: reader.currentCharacter) { | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
We capture the index at the start of the title parsing, in case there is an otherwise valid title followed by non-whitespace. If that happens, we rewind the reader to the beginning of what would have been the title, and set |
||||||||||||||||
reader.advanceIndex() | ||||||||||||||||
titleText = try reader.read(until: delimeter.closing) | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
This helps fix the new failure of CommonMark test 179: |
||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
return URLDeclaration(name: name.lowercased(), url: url, title: titleText) | ||||||||||||||||
} | ||||||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This helps fix the new failure of CommonMark test 487:
"The destination cannot contain line breaks" (spec)