先読みに対応してコードブロック後の装飾に対応
This commit is contained in:
parent
b61a40ea32
commit
3ad0cd6f92
|
@ -64,18 +64,13 @@ class Lexer {
|
||||||
if (iterator.peekOrNull() == '[') {
|
if (iterator.peekOrNull() == '[') {
|
||||||
tokens.add(Exclamation)
|
tokens.add(Exclamation)
|
||||||
} else {
|
} else {
|
||||||
tokens.add(Text("!"))
|
addText(tokens, "!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
val lastToken = tokens.lastOrNull()
|
addText(tokens, next.toString())
|
||||||
if (lastToken is Text) {
|
|
||||||
lastToken.text += next.toString()
|
|
||||||
} else {
|
|
||||||
tokens.add(Text(next.toString()))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!inline && tokens.lastOrNull() !is Whitespace) { //行頭が空白の場合は一旦無視する
|
if (!inline && tokens.lastOrNull() !is Whitespace) { //行頭が空白の場合は一旦無視する
|
||||||
|
@ -105,13 +100,22 @@ class Lexer {
|
||||||
return tokens
|
return tokens
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun addText(tokens: MutableList<Token>, next: String) {
|
||||||
|
val lastToken = tokens.lastOrNull()
|
||||||
|
if (lastToken is Text) {
|
||||||
|
lastToken.text += next
|
||||||
|
} else {
|
||||||
|
tokens.add(Text(next))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun codeblock(
|
private fun codeblock(
|
||||||
iterator: PeekableCharIterator,
|
iterator: PeekableCharIterator,
|
||||||
next: Char,
|
next: Char,
|
||||||
tokens: MutableList<Token>,
|
tokens: MutableList<Token>,
|
||||||
inCode: Boolean,
|
inCode: Boolean,
|
||||||
codeBuffer: StringBuilder,
|
codeBuffer: StringBuilder,
|
||||||
inline: Boolean
|
inline: Boolean,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
var inCode1 = inCode
|
var inCode1 = inCode
|
||||||
if (iterator.peekOrNull() == next && !inline) { //行頭かつ次の文字が`
|
if (iterator.peekOrNull() == next && !inline) { //行頭かつ次の文字が`
|
||||||
|
@ -157,20 +161,16 @@ class Lexer {
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
val codeBuilder = StringBuilder()
|
val peekString = peekString(next, iterator)
|
||||||
while (iterator.hasNext() && iterator.peekOrNull() != next) {
|
if (peekString != null && peekString.isEmpty()) {
|
||||||
codeBuilder.append(iterator.next())
|
addText(tokens, "$next$next")
|
||||||
}
|
iterator.next()
|
||||||
if (iterator.hasNext() && iterator.next() == next) { //インラインコードブロックかと思ったら違った
|
} else if (peekString != null) {
|
||||||
if (codeBuilder.isEmpty()) {
|
tokens.add(InlineCodeBlock(peekString))
|
||||||
tokens.add(Text("$next$next"))
|
iterator.skip(peekString.length + 1)
|
||||||
} else {
|
|
||||||
tokens.add(InlineCodeBlock(codeBuilder.toString()))
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
tokens.add(Text(codeBuilder.insert(0, next).toString()))
|
addText(tokens, next.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return inCode1
|
return inCode1
|
||||||
}
|
}
|
||||||
|
@ -345,6 +345,19 @@ class Lexer {
|
||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun peekString(char: Char, iterator: PeekableCharIterator): String? {
|
||||||
|
var counter = 0
|
||||||
|
val stringBuilder = StringBuilder()
|
||||||
|
while (iterator.peekOrNull(counter) != null && iterator.peekOrNull(counter) != char) {
|
||||||
|
stringBuilder.append(iterator.peekOrNull(counter))
|
||||||
|
counter++
|
||||||
|
}
|
||||||
|
if (iterator.peekOrNull(counter) == null) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return stringBuilder.toString()
|
||||||
|
}
|
||||||
|
|
||||||
fun collect(iterator: PeekableCharIterator): String {
|
fun collect(iterator: PeekableCharIterator): String {
|
||||||
val char = mutableListOf<Char>()
|
val char = mutableListOf<Char>()
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
|
|
|
@ -15,6 +15,12 @@ class PeekableCharIterator(private val charArray: CharArray) : Iterator<Char> {
|
||||||
fun peekOrNull(): Char? = charArray.getOrNull(index)
|
fun peekOrNull(): Char? = charArray.getOrNull(index)
|
||||||
|
|
||||||
fun current(): Int = index
|
fun current(): Int = index
|
||||||
|
|
||||||
|
fun peekOrNull(offset: Int): Char? = charArray.getOrNull(index + offset)
|
||||||
|
|
||||||
|
fun skip(count: Int = 0) {
|
||||||
|
index += count
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PeekableStringIterator(private val list: List<String>) : Iterator<String> {
|
class PeekableStringIterator(private val list: List<String>) : Iterator<String> {
|
||||||
|
|
|
@ -756,7 +756,7 @@ class LexerTest {
|
||||||
|
|
||||||
assertContentEquals(
|
assertContentEquals(
|
||||||
listOf(
|
listOf(
|
||||||
Text("```"), Text("`aiueo")
|
Text("````aiueo")
|
||||||
), actual
|
), actual
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -816,7 +816,12 @@ class LexerTest {
|
||||||
|
|
||||||
assertContentEquals(
|
assertContentEquals(
|
||||||
listOf(
|
listOf(
|
||||||
Text("aiueo"), Whitespace(1, ' '), Text("```abcd")
|
Text("aiueo"),
|
||||||
|
Whitespace(1, ' '),
|
||||||
|
Text("```abcd"),
|
||||||
|
Asterisk(1, '*'),
|
||||||
|
Text("a"),
|
||||||
|
Asterisk(1, '*')
|
||||||
), actual
|
), actual
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue