This commit is contained in:
usbharu 2024-11-13 16:39:28 +09:00
parent 6d49a4ad5e
commit 4c23bdc1ad
Signed by: usbharu
GPG Key ID: 8CB1087135660B8D
3 changed files with 75 additions and 8 deletions

View File

@ -50,6 +50,14 @@ class Lexer {
next == 'h' -> url(next, iterator, tokens) next == 'h' -> url(next, iterator, tokens)
next == '*' || next == '_' -> asterisk(iterator, next, tokens) next == '*' || next == '_' -> asterisk(iterator, next, tokens)
next == '!' -> {
if (iterator.peekOrNull() == '[') {
tokens.add(Exclamation)
} else {
tokens.add(Text("!"))
}
}
else -> { else -> {
val lastToken = tokens.lastOrNull() val lastToken = tokens.lastOrNull()
if (lastToken is Text) { if (lastToken is Text) {
@ -97,27 +105,42 @@ class Lexer {
tokens: MutableList<Token>, tokens: MutableList<Token>,
) { ) {
//todo httpにも対応 //todo httpにも対応
//todo nextでみずにpeekでみて確認してからnextする hのあとにアスタリスク等が来たときに対応できない val charIterator = PeekableCharIterator("ttps://".toCharArray())
val charIterator = "ttps://".iterator()
val urlBuilder = StringBuilder() val urlBuilder = StringBuilder()
urlBuilder.append(next) urlBuilder.append(next)
while (charIterator.hasNext() && iterator.hasNext()) { while (charIterator.hasNext() && iterator.hasNext()) {
// charIterator val nextC = charIterator.peekOrNull() ?: return
val nextC = charIterator.next() val nextC2 = iterator.peekOrNull() ?: return
val nextC2 = iterator.next()
urlBuilder.append(nextC2)
if (nextC != nextC2) { if (nextC != nextC2) {
tokens.add(Text(urlBuilder.toString())) tokens.add(Text(urlBuilder.toString()))
return return
} }
urlBuilder.append(nextC2)
charIterator.next()
iterator.next()
} }
if (urlBuilder.length == 1) { if (urlBuilder.length == 1) {
tokens.add(Text(urlBuilder.toString())) //hだけのときはURLじゃないのでテキストとして追加 tokens.add(Text(urlBuilder.toString())) //hだけのときはURLじゃないのでテキストとして追加
} else { } else {
while (iterator.hasNext() && iterator.peekOrNull()?.isWhitespace() != true) { while (iterator.hasNext() && (iterator.peekOrNull()
?.isWhitespace() != true && iterator.peekOrNull() != ')')
) {
urlBuilder.append(iterator.next()) urlBuilder.append(iterator.next())
} }
tokens.add(Url(urlBuilder.toString())) tokens.add(Url(urlBuilder.toString()))
skipWhitespace(iterator)
val doubleQuotation = iterator.peekOrNull()
if (iterator.peekOrNull() == '"' || doubleQuotation == '”') {
iterator.next()
doubleQuotation!!
val titleBuilder = StringBuilder()
while (iterator.hasNext() && iterator.peekOrNull() != doubleQuotation && iterator.peekOrNull() != ')') {
titleBuilder.append(iterator.next())
}
if (iterator.peekOrNull() == '"') {
iterator.next()
}
}
} }
} }

View File

@ -24,3 +24,5 @@ data object ParenthesesStart : Token()
data object ParenthesesEnd : Token() data object ParenthesesEnd : Token()
data class Url(var url: String) : Token() data class Url(var url: String) : Token()
data class Asterisk(var count: Int, var char: Char) : Token() data class Asterisk(var count: Int, var char: Char) : Token()
data object Exclamation : Token()
data class UrlTitle(val title: String) : Token()

View File

@ -563,6 +563,48 @@ class LexerTest {
assertContentEquals( assertContentEquals(
listOf( listOf(
Text("h"), Asterisk(1, '*'), Text("a"), Asterisk(1, '*')
), actual
)
}
@Test
fun 画像() {
val lexer = Lexer()
val actual = lexer.lex("![alt](https://example.com)")
println(actual)
assertContentEquals(
listOf(
Exclamation,
SquareBracketStart,
Text("alt"),
SquareBracketEnd,
ParenthesesStart,
Url("https://example.com"),
ParenthesesEnd
), actual
)
}
@Test
fun url3() {
val lexer = Lexer()
val actual = lexer.lex("[alt](https://example.com)")
println(actual)
assertContentEquals(
listOf(
SquareBracketStart,
Text("alt"),
SquareBracketEnd,
ParenthesesStart,
Url("https://example.com"),
ParenthesesEnd
), actual ), actual
) )
} }