/*
* Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights resvered.
*/
package commonmark4cj.commonmark
/**
* An interface to decide how links/images are handled.
* <p>
* Implementations need to be registered with a parser via {@link org.commonmark.parser.Parser.Builder#linkProcessor}.
* Then, when inline parsing is run, each parsed link/image is passed to the processor. This includes links like these:
* <p>
* <pre><code>
* [text](destination)
* [text]
* [text][]
* [text][label]
* </code></pre>
* And images:
* <pre><code>
* 
* ![text]
* ![text][]
* ![text][label]
* </code></pre>
* See {@link LinkInfo} for accessing various parts of the parsed link/image.
* <p>
* The processor can then inspect the link/image and decide what to do with it by returning the appropriate
* {@link LinkResult}. If it returns {@link LinkResult#none()}, the next registered processor is tried. If none of them
* apply, the link is handled as it normally would.
*/
public interface LinkProcessor {
/**
* @param linkInfo information about the parsed link/image
* @param scanner the scanner at the current position after the parsed link/image
* @param context context for inline parsing
* @return what to do with the link/image, e.g. do nothing (try the next processor), wrap the text in a node, or
* replace the link/image with a node
*/
func process(linkInfo: LinkInfo, scanner: Scanner, context: InlineParserContext): ?LinkResult
}
public class CoreLinkProcessor <: LinkProcessor {
// @Override
@Frozen
public func process(linkInfo: LinkInfo, scanner: Scanner, context: InlineParserContext): ?LinkResult {
if (let Some(dest) <- linkInfo.destination()) {
// Inline link
return _process(linkInfo, scanner, dest, linkInfo.title())
}
var label = linkInfo.label()
var ref = if (let Some(label) <- label && !label.isEmpty()) {
label
} else {
linkInfo.text()
}
var def: ?LinkReferenceDefinition = context.getDefinition("LinkReferenceDefinition", ref)
if (let Some(def) <- def) {
// Reference link
return _process(linkInfo, scanner, def.getDestination(), def.getTitle())
}
return LinkResult.none()
}
private static func _process(linkInfo: LinkInfo, scanner: Scanner, destination: String, title: ?String): LinkResult {
if (linkInfo.marker()?.getLiteral() == "!") {
return LinkResult.wrapTextIn(Image(destination, title), scanner.position()).includeMarker()
}
return LinkResult.wrapTextIn(Link(destination, title), scanner.position())
}
}