From 6dc3ffd38dd7ded1fb59d6bc8797ec29de97df2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20F=C3=B6rster?= Date: Wed, 2 Jan 2019 21:32:16 +0100 Subject: [PATCH] Format BibTeX strings and preambles --- .../kotlin/texlab/BibtexFormatterSettings.kt | 11 ---- .../kotlin/texlab/TextDocumentServiceImpl.kt | 11 +++- .../{ => formatting}/BibtexFormatter.kt | 61 +++++++++++++------ .../formatting/BibtexFormatterSettings.kt | 14 +++++ .../kotlin/texlab/formatting/BibtexStyle.kt | 7 +++ .../kotlin/texlab/formatting/NamingStyle.kt | 31 ++++++++++ 6 files changed, 104 insertions(+), 31 deletions(-) delete mode 100644 src/main/kotlin/texlab/BibtexFormatterSettings.kt rename src/main/kotlin/texlab/{ => formatting}/BibtexFormatter.kt (57%) create mode 100644 src/main/kotlin/texlab/formatting/BibtexFormatterSettings.kt create mode 100644 src/main/kotlin/texlab/formatting/BibtexStyle.kt create mode 100644 src/main/kotlin/texlab/formatting/NamingStyle.kt diff --git a/src/main/kotlin/texlab/BibtexFormatterSettings.kt b/src/main/kotlin/texlab/BibtexFormatterSettings.kt deleted file mode 100644 index 9a069ce8..00000000 --- a/src/main/kotlin/texlab/BibtexFormatterSettings.kt +++ /dev/null @@ -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" - } -} diff --git a/src/main/kotlin/texlab/TextDocumentServiceImpl.kt b/src/main/kotlin/texlab/TextDocumentServiceImpl.kt index 0241b782..c9b76102 100644 --- a/src/main/kotlin/texlab/TextDocumentServiceImpl.kt +++ b/src/main/kotlin/texlab/TextDocumentServiceImpl.kt @@ -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() - for (entry in document.tree.root.children.filterIsInstance()) { + for (entry in document.tree.root.children.filterIsInstance()) { edits.add(TextEdit(entry.range, formatter.format(entry))) } return CompletableFuture.completedFuture(edits) diff --git a/src/main/kotlin/texlab/BibtexFormatter.kt b/src/main/kotlin/texlab/formatting/BibtexFormatter.kt similarity index 57% rename from src/main/kotlin/texlab/BibtexFormatter.kt rename to src/main/kotlin/texlab/formatting/BibtexFormatter.kt index 20cfc623..8733cfdc 100644 --- a/src/main/kotlin/texlab/BibtexFormatter.kt +++ b/src/main/kotlin/texlab/formatting/BibtexFormatter.kt @@ -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 { + private fun getAllTokens(content: BibtexContentSyntax): List { val tokens = mutableListOf() fun visit(node: BibtexContentSyntax) { when (node) { diff --git a/src/main/kotlin/texlab/formatting/BibtexFormatterSettings.kt b/src/main/kotlin/texlab/formatting/BibtexFormatterSettings.kt new file mode 100644 index 00000000..8a58dd63 --- /dev/null +++ b/src/main/kotlin/texlab/formatting/BibtexFormatterSettings.kt @@ -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" + } +} + diff --git a/src/main/kotlin/texlab/formatting/BibtexStyle.kt b/src/main/kotlin/texlab/formatting/BibtexStyle.kt new file mode 100644 index 00000000..90397821 --- /dev/null +++ b/src/main/kotlin/texlab/formatting/BibtexStyle.kt @@ -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) diff --git a/src/main/kotlin/texlab/formatting/NamingStyle.kt b/src/main/kotlin/texlab/formatting/NamingStyle.kt new file mode 100644 index 00000000..b3515eec --- /dev/null +++ b/src/main/kotlin/texlab/formatting/NamingStyle.kt @@ -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) + } +}