mirror of
https://github.com/latex-lsp/texlab.git
synced 2025-12-23 09:19:21 +00:00
Format BibTeX strings and preambles
This commit is contained in:
parent
d2abb963b3
commit
6dc3ffd38d
6 changed files with 104 additions and 31 deletions
|
|
@ -1,11 +0,0 @@
|
|||
package texlab
|
||||
|
||||
import java.util.*
|
||||
|
||||
data class BibtexFormatterSettings(val insertSpaces: Boolean, val tabSize: Int, val lineLength: Int) {
|
||||
val indent: String = if (insertSpaces) {
|
||||
Collections.nCopies(tabSize, " ").joinToString("")
|
||||
} else {
|
||||
"\t"
|
||||
}
|
||||
}
|
||||
|
|
@ -13,6 +13,10 @@ import texlab.completion.latex.data.LatexComponentDatabaseListener
|
|||
import texlab.completion.latex.data.LatexResolver
|
||||
import texlab.definition.*
|
||||
import texlab.folding.*
|
||||
import texlab.formatting.BibtexFormatter
|
||||
import texlab.formatting.BibtexFormatterSettings
|
||||
import texlab.formatting.BibtexStyle
|
||||
import texlab.formatting.NamingStyle
|
||||
import texlab.link.AggregateLinkProvider
|
||||
import texlab.link.LatexIncludeLinkProvider
|
||||
import texlab.link.LinkProvider
|
||||
|
|
@ -21,7 +25,7 @@ import texlab.metadata.CtanPackageMetadataProvider
|
|||
import texlab.metadata.PackageMetadataProvider
|
||||
import texlab.rename.*
|
||||
import texlab.symbol.*
|
||||
import texlab.syntax.bibtex.BibtexEntrySyntax
|
||||
import texlab.syntax.bibtex.BibtexDeclarationSyntax
|
||||
import java.io.File
|
||||
import java.net.URI
|
||||
import java.nio.file.Paths
|
||||
|
|
@ -254,10 +258,11 @@ class TextDocumentServiceImpl(private val workspace: Workspace) : TextDocumentSe
|
|||
.firstOrNull { it.uri == uri }
|
||||
?: return CompletableFuture.completedFuture(null)
|
||||
|
||||
val settings = BibtexFormatterSettings(params.options.isInsertSpaces, params.options.tabSize, 120)
|
||||
val style = BibtexStyle(NamingStyle.LOWER_CASE, NamingStyle.LOWER_CASE, 120)
|
||||
val settings = BibtexFormatterSettings(params.options.isInsertSpaces, params.options.tabSize, style)
|
||||
val formatter = BibtexFormatter(settings)
|
||||
val edits = mutableListOf<TextEdit>()
|
||||
for (entry in document.tree.root.children.filterIsInstance<BibtexEntrySyntax>()) {
|
||||
for (entry in document.tree.root.children.filterIsInstance<BibtexDeclarationSyntax>()) {
|
||||
edits.add(TextEdit(entry.range, formatter.format(entry)))
|
||||
}
|
||||
return CompletableFuture.completedFuture(edits)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,37 @@
|
|||
package texlab
|
||||
package texlab.formatting
|
||||
|
||||
import texlab.syntax.bibtex.*
|
||||
|
||||
class BibtexFormatter(private val settings: BibtexFormatterSettings) {
|
||||
fun format(declaration: BibtexDeclarationSyntax): String {
|
||||
return when (declaration) {
|
||||
is BibtexPreambleSyntax ->
|
||||
format(declaration)
|
||||
is BibtexStringSyntax ->
|
||||
format(declaration)
|
||||
is BibtexEntrySyntax ->
|
||||
format(declaration)
|
||||
}
|
||||
}
|
||||
|
||||
fun format(preamble: BibtexPreambleSyntax): String = buildString {
|
||||
append(settings.style.types.formatType(preamble.type.text))
|
||||
append("{")
|
||||
append(format(preamble.content ?: return@buildString, length))
|
||||
append("}")
|
||||
}
|
||||
|
||||
fun format(string: BibtexStringSyntax): String = buildString {
|
||||
append(settings.style.types.formatType(string.type.text))
|
||||
append("{")
|
||||
append(string.name?.text)
|
||||
append(" = ")
|
||||
append(format(string.value ?: return@buildString, length))
|
||||
append("}")
|
||||
}
|
||||
|
||||
fun format(entry: BibtexEntrySyntax): String = buildString {
|
||||
append(entry.type.text.toLowerCase())
|
||||
append(settings.style.types.formatType(entry.type.text))
|
||||
append("{")
|
||||
append(entry.name?.text ?: return@buildString)
|
||||
appendln(",")
|
||||
|
|
@ -12,16 +39,20 @@ class BibtexFormatter(private val settings: BibtexFormatterSettings) {
|
|||
append("}")
|
||||
}
|
||||
|
||||
private fun format(field: BibtexFieldSyntax): String = buildString {
|
||||
fun format(field: BibtexFieldSyntax): String = buildString {
|
||||
append(settings.indent)
|
||||
append(field.name.text.toLowerCase())
|
||||
append(settings.style.fields.format(field.name.text))
|
||||
append(" = ")
|
||||
val startLength = settings.tabSize + field.name.text.length + 3
|
||||
val align = settings.tabSize + field.name.text.length + 3
|
||||
append(format(field.content ?: return@buildString, align))
|
||||
appendln(",")
|
||||
}
|
||||
|
||||
val tokens = descendants(field.content ?: return@buildString)
|
||||
fun format(content: BibtexContentSyntax, align: Int): String = buildString {
|
||||
val tokens = getAllTokens(content)
|
||||
append(tokens[0].text)
|
||||
|
||||
var length = startLength + tokens[0].length
|
||||
var length = align + tokens[0].length
|
||||
for (i in 1 until tokens.size) {
|
||||
val previous = tokens[i - 1]
|
||||
val current = tokens[i]
|
||||
|
|
@ -33,13 +64,13 @@ class BibtexFormatter(private val settings: BibtexFormatterSettings) {
|
|||
0
|
||||
}
|
||||
|
||||
if (length + current.length + spaceLength > settings.lineLength) {
|
||||
if (length + current.length + spaceLength > settings.style.lineLength) {
|
||||
appendln()
|
||||
append(settings.indent)
|
||||
for (j in 0 until startLength - settings.tabSize + 1) {
|
||||
for (j in 0 until align - settings.tabSize + 1) {
|
||||
append(" ")
|
||||
}
|
||||
length = startLength
|
||||
length = align
|
||||
} else if (insertSpace) {
|
||||
append(" ")
|
||||
length++
|
||||
|
|
@ -47,18 +78,14 @@ class BibtexFormatter(private val settings: BibtexFormatterSettings) {
|
|||
append(current.text)
|
||||
length += current.length
|
||||
}
|
||||
appendln(",")
|
||||
}
|
||||
|
||||
private fun shouldInsertSpace(previous: BibtexToken, current: BibtexToken): Boolean {
|
||||
if (previous.line != current.line) {
|
||||
return true
|
||||
}
|
||||
|
||||
return previous.end.character < current.start.character
|
||||
return previous.line != current.line ||
|
||||
previous.end.character < current.start.character
|
||||
}
|
||||
|
||||
private fun descendants(content: BibtexContentSyntax): List<BibtexToken> {
|
||||
private fun getAllTokens(content: BibtexContentSyntax): List<BibtexToken> {
|
||||
val tokens = mutableListOf<BibtexToken>()
|
||||
fun visit(node: BibtexContentSyntax) {
|
||||
when (node) {
|
||||
14
src/main/kotlin/texlab/formatting/BibtexFormatterSettings.kt
Normal file
14
src/main/kotlin/texlab/formatting/BibtexFormatterSettings.kt
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
package texlab.formatting
|
||||
|
||||
import java.util.*
|
||||
|
||||
data class BibtexFormatterSettings(val insertSpaces: Boolean,
|
||||
val tabSize: Int,
|
||||
val style: BibtexStyle) {
|
||||
val indent: String = if (insertSpaces) {
|
||||
Collections.nCopies(tabSize, " ").joinToString("")
|
||||
} else {
|
||||
"\t"
|
||||
}
|
||||
}
|
||||
|
||||
7
src/main/kotlin/texlab/formatting/BibtexStyle.kt
Normal file
7
src/main/kotlin/texlab/formatting/BibtexStyle.kt
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
package texlab.formatting
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
data class BibtexStyle(@SerializedName("types") val types: NamingStyle,
|
||||
@SerializedName("fields") val fields: NamingStyle,
|
||||
@SerializedName("lineLength") val lineLength: Int)
|
||||
31
src/main/kotlin/texlab/formatting/NamingStyle.kt
Normal file
31
src/main/kotlin/texlab/formatting/NamingStyle.kt
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
package texlab.formatting
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
enum class NamingStyle {
|
||||
@SerializedName("upper-case")
|
||||
UPPER_CASE,
|
||||
|
||||
@SerializedName("lower-case")
|
||||
LOWER_CASE,
|
||||
|
||||
@SerializedName("title-case")
|
||||
TITLE_CASE;
|
||||
|
||||
fun format(identifier: String): String {
|
||||
if (name == "") {
|
||||
return ""
|
||||
}
|
||||
|
||||
return when (this) {
|
||||
UPPER_CASE -> identifier.toUpperCase()
|
||||
LOWER_CASE -> identifier.toLowerCase()
|
||||
TITLE_CASE -> identifier[0].toUpperCase() + identifier.toLowerCase().substring(1)
|
||||
}
|
||||
}
|
||||
|
||||
fun formatType(type: String): String {
|
||||
val name = type.substring(1)
|
||||
return "@" + format(name)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue