feat: urlに対応
This commit is contained in:
parent
a14906e729
commit
21087e0244
|
@ -6,7 +6,7 @@ class Lexer {
|
||||||
fun lex(input: String): List<Token> {
|
fun lex(input: String): List<Token> {
|
||||||
val tokens = mutableListOf<Token>()
|
val tokens = mutableListOf<Token>()
|
||||||
val lines = PeekableStringIterator(input.lines())
|
val lines = PeekableStringIterator(input.lines())
|
||||||
while (lines.hasNext()) {
|
line@ while (lines.hasNext()) {
|
||||||
|
|
||||||
if (lines.peekOrNull() == "") {
|
if (lines.peekOrNull() == "") {
|
||||||
blankLine(lines, tokens)
|
blankLine(lines, tokens)
|
||||||
|
@ -14,7 +14,7 @@ class Lexer {
|
||||||
val line = lines.next()
|
val line = lines.next()
|
||||||
|
|
||||||
val iterator = PeekableCharIterator(line.toCharArray())
|
val iterator = PeekableCharIterator(line.toCharArray())
|
||||||
while (iterator.hasNext()) {
|
char@ while (iterator.hasNext()) {
|
||||||
when (val next = iterator.next()) {
|
when (val next = iterator.next()) {
|
||||||
'#', '#' -> header(iterator, tokens)
|
'#', '#' -> header(iterator, tokens)
|
||||||
'>', '>' -> quote(iterator, tokens)
|
'>', '>' -> quote(iterator, tokens)
|
||||||
|
@ -37,22 +37,62 @@ class Lexer {
|
||||||
tokens.add(SquareBracketEnd)
|
tokens.add(SquareBracketEnd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
'(', '(' -> {
|
||||||
|
tokens.add(ParenthesesStart)
|
||||||
|
}
|
||||||
|
|
||||||
|
')', ')' -> {
|
||||||
|
tokens.add(ParenthesesEnd)
|
||||||
|
}
|
||||||
|
|
||||||
' ', ' ' -> {
|
' ', ' ' -> {
|
||||||
tokens.add(Whitespace(skipWhitespace(iterator) + 1, next)) //nextの分1足す
|
tokens.add(Whitespace(skipWhitespace(iterator) + 1, next)) //nextの分1足す
|
||||||
}
|
}
|
||||||
|
|
||||||
|
'h' -> {
|
||||||
|
//todo httpにも対応
|
||||||
|
val charIterator = "ttps://".iterator()
|
||||||
|
val urlBuilder = StringBuilder()
|
||||||
|
urlBuilder.append(next)
|
||||||
|
while (charIterator.hasNext() && iterator.hasNext()) {
|
||||||
|
val nextC = charIterator.next()
|
||||||
|
val nextC2 = iterator.next()
|
||||||
|
urlBuilder.append(nextC2)
|
||||||
|
if (nextC != nextC2) {
|
||||||
|
tokens.add(Text(urlBuilder.toString()))
|
||||||
|
continue@char
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (urlBuilder.length == 1) {
|
||||||
|
tokens.add(Text(urlBuilder.toString())) //hだけのときはURLじゃないのでテキストとして追加
|
||||||
|
} else {
|
||||||
|
while (iterator.hasNext() && iterator.peekOrNull()?.isWhitespace() != true) {
|
||||||
|
urlBuilder.append(iterator.next())
|
||||||
|
}
|
||||||
|
tokens.add(Url(urlBuilder.toString()))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
tokens.add(Text(next + collect(iterator)))
|
val lastToken = tokens.lastOrNull()
|
||||||
tokens.add(Break(1))
|
if (lastToken is Text) {
|
||||||
|
lastToken.text += next.toString()
|
||||||
|
} else {
|
||||||
|
tokens.add(Text(next.toString()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tokens.add(Break(1))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
println(tokens)
|
||||||
val lastToken = tokens.lastOrNull()
|
val lastToken = tokens.lastOrNull()
|
||||||
if (lastToken is Break) {
|
if (lastToken is Break) {
|
||||||
if (lastToken.count == 1) {
|
if (lastToken.count == 1) {
|
||||||
|
@ -151,7 +191,6 @@ class Lexer {
|
||||||
tokens.add(Quote(count))
|
tokens.add(Quote(count))
|
||||||
skipWhitespace(iterator)
|
skipWhitespace(iterator)
|
||||||
tokens.add(Text(collect(iterator)))
|
tokens.add(Text(collect(iterator)))
|
||||||
tokens.add(Break(1))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun header(
|
private fun header(
|
||||||
|
@ -166,7 +205,6 @@ class Lexer {
|
||||||
tokens.add(Header(count))
|
tokens.add(Header(count))
|
||||||
skipWhitespace(iterator)
|
skipWhitespace(iterator)
|
||||||
tokens.add(Text(collect(iterator)))
|
tokens.add(Text(collect(iterator)))
|
||||||
tokens.add(Break(1))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun skipWhitespace(iterator: PeekableCharIterator): Int {
|
fun skipWhitespace(iterator: PeekableCharIterator): Int {
|
||||||
|
|
|
@ -19,4 +19,7 @@ data object DiscList : List(ListType.DISC)
|
||||||
data class DecimalList(val number: Char) : List(ListType.DECIMAL)
|
data class DecimalList(val number: Char) : List(ListType.DECIMAL)
|
||||||
data class CheckBox(val checked: Boolean) : Token()
|
data class CheckBox(val checked: Boolean) : Token()
|
||||||
data object SquareBracketStart : Token()
|
data object SquareBracketStart : Token()
|
||||||
data object SquareBracketEnd : Token()
|
data object SquareBracketEnd : Token()
|
||||||
|
data object ParenthesesStart : Token()
|
||||||
|
data object ParenthesesEnd : Token()
|
||||||
|
data class Url(var url: String) : Token()
|
|
@ -57,7 +57,7 @@ class LexerTest {
|
||||||
|
|
||||||
println(actual)
|
println(actual)
|
||||||
|
|
||||||
assertContentEquals(listOf(Text("abcd"), Break(1), Text("efgh")), actual)
|
assertContentEquals(listOf(Text("abcd"), Break(1), Text("efg"), Text("h")), actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -68,7 +68,7 @@ class LexerTest {
|
||||||
|
|
||||||
println(actual)
|
println(actual)
|
||||||
|
|
||||||
assertContentEquals(listOf(Text("abcd"), Break(2), Text("efgh")), actual)
|
assertContentEquals(listOf(Text("abcd"), Break(2), Text("efg"), Text("h")), actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -223,7 +223,7 @@ class LexerTest {
|
||||||
|
|
||||||
println(actual)
|
println(actual)
|
||||||
|
|
||||||
assertContentEquals(listOf(Text("---"), Text("aiueo")), actual)
|
assertContentEquals(listOf(Text("---aiueo")), actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -256,7 +256,7 @@ class LexerTest {
|
||||||
|
|
||||||
println(actual)
|
println(actual)
|
||||||
|
|
||||||
assertContentEquals(listOf(DiscList, Text("[x"), Text("a a")), actual)
|
assertContentEquals(listOf(DiscList, Text("[xa"), Whitespace(1, ' '), Text("a")), actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -278,7 +278,7 @@ class LexerTest {
|
||||||
|
|
||||||
println(actual)
|
println(actual)
|
||||||
|
|
||||||
assertContentEquals(listOf(Text("-"), Text("aiueo")), actual)
|
assertContentEquals(listOf(Text("-aiueo")), actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -408,4 +408,79 @@ class LexerTest {
|
||||||
actual
|
actual
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun url() {
|
||||||
|
val lexer = Lexer()
|
||||||
|
|
||||||
|
val actual = lexer.lex("https://example.com")
|
||||||
|
|
||||||
|
println(actual)
|
||||||
|
|
||||||
|
assertContentEquals(listOf(Url("https://example.com")), actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun url2() {
|
||||||
|
val lexer = Lexer()
|
||||||
|
|
||||||
|
val actual =
|
||||||
|
lexer.lex("https://ja.wikipedia.org/wiki/%E3%83%A4%E3%83%B3%E3%83%90%E3%83%AB%E3%82%AF%E3%82%A4%E3%83%8A#%E6%8E%A1%E9%A4%8C")
|
||||||
|
|
||||||
|
println(actual)
|
||||||
|
|
||||||
|
assertContentEquals(
|
||||||
|
listOf(Url("https://ja.wikipedia.org/wiki/%E3%83%A4%E3%83%B3%E3%83%90%E3%83%AB%E3%82%AF%E3%82%A4%E3%83%8A#%E6%8E%A1%E9%A4%8C")),
|
||||||
|
actual
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun 文中にurl() {
|
||||||
|
val lexer = Lexer()
|
||||||
|
|
||||||
|
val actual = lexer.lex("こんにちは~ https://example.com\nあいうえお")
|
||||||
|
|
||||||
|
println(actual)
|
||||||
|
|
||||||
|
assertContentEquals(
|
||||||
|
listOf(
|
||||||
|
Text("こんにちは~"),
|
||||||
|
Whitespace(1, ' '),
|
||||||
|
Url("https://example.com"),
|
||||||
|
Break(1),
|
||||||
|
Text("あいうえお")
|
||||||
|
), actual
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun urlかと思ったら違った() {
|
||||||
|
val lexer = Lexer()
|
||||||
|
|
||||||
|
val actual = lexer.lex("httppppp")
|
||||||
|
|
||||||
|
println(actual)
|
||||||
|
|
||||||
|
assertContentEquals(
|
||||||
|
listOf(
|
||||||
|
Text("httppppp")
|
||||||
|
), actual
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun urlかと思ったら違った2() {
|
||||||
|
val lexer = Lexer()
|
||||||
|
|
||||||
|
val actual = lexer.lex("ha")
|
||||||
|
|
||||||
|
println(actual)
|
||||||
|
|
||||||
|
assertContentEquals(
|
||||||
|
listOf(
|
||||||
|
Text("ha")
|
||||||
|
), actual
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue