/*
* Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights resvered.
*/
package commonmark4cj.commonmark
/**
* Attempts to parse an HTML entity or numeric character reference.
*/
public class EntityInlineParser <: InlineContentParser {
private static let hex: AsciiMatcher = AsciiMatcher
.builder()
.range(b'0', b'9')
.range(b'A', b'F')
.range(b'a', b'f')
.build()
private static let dec: AsciiMatcher = AsciiMatcher.builder().range(b'0', b'9').build()
private static let entityStart: AsciiMatcher = AsciiMatcher.builder().range(b'A', b'Z').range(b'a', b'z').build()
private static let entityContinue: AsciiMatcher = entityStart.newBuilder().range(b'0', b'9').build()
// @Override
public func tryParse(inlineParserState: InlineParserState): ParsedInline {
let scanner: Scanner = inlineParserState.getScanner()
let start: SourcePosition = scanner.position()
// Skip `&`
scanner.next()
let c = scanner.peek()
if (c == b'#') {
// Numeric
scanner.next()
if (scanner.next(b'x') || scanner.next(b'X')) { /*cjlint-ignore !G.EXP.03 */
let digits: Int = scanner.matches(hex)
if (1 <= digits && digits <= 6 && scanner.next(b';')) { /*cjlint-ignore !G.EXP.03 */
return entity(scanner, start)
}
} else {
let digits: Int = scanner.matches(dec)
if (1 <= digits && digits <= 7 && scanner.next(b';')) { /*cjlint-ignore !G.EXP.03 */
return entity(scanner, start)
}
}
} else if (entityStart.matches(c)) {
scanner.matches(entityContinue)
if (scanner.next(b';')) {
return entity(scanner, start)
}
}
return ParsedInline.none()
}
private func entity(scanner: Scanner, start: SourcePosition): ParsedInline {
let text: String = scanner.getSource(start, scanner.position()).getContent()
return ParsedInline.of(Text(Html5Entities.entityToString(text)), scanner.position())
}
}
public class EntityInlineParserFactory <: InlineContentParserFactory {
// @Override
@Frozen
public func getTriggerCharacters(): HashSet<Rune> {
return HashSet(r'&')
}
// @Override
@Frozen
public func create(): InlineContentParser {
return EntityInlineParser()
}
}