Add cross-straits definitions

This commit is contained in:
Marvin Elsen 2024-10-09 19:52:54 +02:00
parent eb3beb0dfe
commit f344c8df23
Signed by: marvinelsen
GPG Key ID: 820672408CC318C2
6 changed files with 80 additions and 34 deletions

View File

@ -0,0 +1,9 @@
package com.marvinelsen.willow.domain
import kotlinx.serialization.Serializable
@Serializable
data class CrossStraitsDefinition(
val definition: String,
val examples: List<String>,
)

View File

@ -6,5 +6,6 @@ data class DictionaryEntry(
val pinyinWithToneMarks: String, val pinyinWithToneMarks: String,
val pinyinWithToneNumbers: String, val pinyinWithToneNumbers: String,
val zhuyin: String, val zhuyin: String,
val definitions: List<List<String>> val cedictDefinitions: List<List<String>>,
val crossStraitsDefinitions: List<CrossStraitsDefinition>,
) )

View File

@ -27,8 +27,8 @@ class SqliteDictionary(private val connection: Connection) : Dictionary {
private val searchSimplifiedPreparedStatement: PreparedStatement by lazy { private val searchSimplifiedPreparedStatement: PreparedStatement by lazy {
connection.prepareStatement( connection.prepareStatement(
""" """
SELECT traditional, simplified, pinyin_with_tone_marks, pinyin_with_tone_numbers, zhuyin, cedict_definitions SELECT traditional, simplified, pinyin_with_tone_marks, pinyin_with_tone_numbers, zhuyin, cedict_definitions, cross_straits_definitions
FROM cedict FROM entry
WHERE simplified GLOB ? WHERE simplified GLOB ?
ORDER BY character_count ASC ORDER BY character_count ASC
""".trimIndent() """.trimIndent()
@ -38,8 +38,8 @@ class SqliteDictionary(private val connection: Connection) : Dictionary {
private val searchTraditionalPreparedStatement: PreparedStatement by lazy { private val searchTraditionalPreparedStatement: PreparedStatement by lazy {
connection.prepareStatement( connection.prepareStatement(
""" """
SELECT traditional, simplified, pinyin_with_tone_marks, pinyin_with_tone_numbers, zhuyin, cedict_definitions SELECT traditional, simplified, pinyin_with_tone_marks, pinyin_with_tone_numbers, zhuyin, cedict_definitions, cross_straits_definitions
FROM cedict FROM entry
WHERE traditional GLOB ? WHERE traditional GLOB ?
ORDER BY character_count ASC ORDER BY character_count ASC
""".trimIndent() """.trimIndent()
@ -49,8 +49,8 @@ class SqliteDictionary(private val connection: Connection) : Dictionary {
private val searchPinyinPreparedStatement: PreparedStatement by lazy { private val searchPinyinPreparedStatement: PreparedStatement by lazy {
connection.prepareStatement( connection.prepareStatement(
""" """
SELECT traditional, simplified, pinyin_with_tone_marks, pinyin_with_tone_numbers, zhuyin, cedict_definitions SELECT traditional, simplified, pinyin_with_tone_marks, pinyin_with_tone_numbers, zhuyin, cedict_definitions, cross_straits_definitions
FROM cedict FROM entry
WHERE searchable_pinyin GLOB ? WHERE searchable_pinyin GLOB ?
OR searchable_pinyin_with_tone_numbers GLOB ? OR searchable_pinyin_with_tone_numbers GLOB ?
ORDER BY character_count ASC ORDER BY character_count ASC
@ -60,17 +60,17 @@ class SqliteDictionary(private val connection: Connection) : Dictionary {
private val searchSegments = """ private val searchSegments = """
WITH cte(id, segment) AS (VALUES ?) WITH cte(id, segment) AS (VALUES ?)
SELECT cedict.traditional, simplified, pinyin_with_tone_marks, pinyin_with_tone_numbers, zhuyin, cedict_definitions SELECT entry.traditional, simplified, pinyin_with_tone_marks, pinyin_with_tone_numbers, zhuyin, cedict_definitions, cross_straits_definitions
FROM cedict INNER JOIN cte FROM entry INNER JOIN cte
ON cte.segment = cedict.traditional OR cte.segment = cedict.simplified ON cte.segment = entry.traditional OR cte.segment = entry.simplified
ORDER BY cte.id ORDER BY cte.id
""".trimIndent() """.trimIndent()
private val findWordsContaining: PreparedStatement by lazy { private val findWordsContaining: PreparedStatement by lazy {
connection.prepareStatement( connection.prepareStatement(
""" """
SELECT traditional, simplified, pinyin_with_tone_marks, pinyin_with_tone_numbers, zhuyin, cedict_definitions SELECT traditional, simplified, pinyin_with_tone_marks, pinyin_with_tone_numbers, zhuyin, cedict_definitions, cross_straits_definitions
FROM cedict FROM entry
WHERE traditional LIKE ? WHERE traditional LIKE ?
ORDER BY character_count ASC ORDER BY character_count ASC
""".trimIndent() """.trimIndent()
@ -79,9 +79,9 @@ class SqliteDictionary(private val connection: Connection) : Dictionary {
private val findCharacters = """ private val findCharacters = """
WITH cte(id, character) AS (VALUES ?) WITH cte(id, character) AS (VALUES ?)
SELECT traditional, simplified, pinyin_with_tone_marks, pinyin_with_tone_numbers, zhuyin, cedict_definitions SELECT traditional, simplified, pinyin_with_tone_marks, pinyin_with_tone_numbers, zhuyin, cedict_definitions, cross_straits_definitions
FROM cedict INNER JOIN cte FROM entry INNER JOIN cte
ON cte.character = cedict.traditional OR cte.character = cedict.simplified ON cte.character = entry.traditional OR cte.character = entry.simplified
ORDER BY cte.id ORDER BY cte.id
""".trimIndent() """.trimIndent()
@ -167,7 +167,8 @@ private fun ResultSet.toDictionaryEntry() = DictionaryEntry(
pinyinWithToneMarks = this.getString(3), pinyinWithToneMarks = this.getString(3),
pinyinWithToneNumbers = this.getString(4), pinyinWithToneNumbers = this.getString(4),
zhuyin = this.getString(5), zhuyin = this.getString(5),
definitions = Json.decodeFromString(this.getString(6)) cedictDefinitions = Json.decodeFromString(this.getString(6)),
crossStraitsDefinitions = Json.decodeFromString(this.getString(7)),
) )
private fun ResultSet.toListOfDictionaryEntries() = buildList { private fun ResultSet.toListOfDictionaryEntries() = buildList {

View File

@ -1,5 +1,6 @@
package com.marvinelsen.willow.ui package com.marvinelsen.willow.ui
import com.marvinelsen.willow.domain.CrossStraitsDefinition
import com.marvinelsen.willow.domain.DictionaryEntry import com.marvinelsen.willow.domain.DictionaryEntry
import javafx.beans.property.SimpleStringProperty import javafx.beans.property.SimpleStringProperty
import javafx.beans.property.StringProperty import javafx.beans.property.StringProperty
@ -12,7 +13,8 @@ data class DictionaryEntryFx(
val pinyinWithToneMarksProperty: StringProperty, val pinyinWithToneMarksProperty: StringProperty,
val pinyinWithToneNumbersProperty: StringProperty, val pinyinWithToneNumbersProperty: StringProperty,
val zhuyinProperty: StringProperty, val zhuyinProperty: StringProperty,
val definitions: ObservableList<List<String>>, val cedictDefinitions: ObservableList<List<String>>,
val crossStraitsDefinitions: ObservableList<CrossStraitsDefinition>,
) )
fun DictionaryEntry.toFx() = DictionaryEntryFx( fun DictionaryEntry.toFx() = DictionaryEntryFx(
@ -21,7 +23,8 @@ fun DictionaryEntry.toFx() = DictionaryEntryFx(
pinyinWithToneMarksProperty = SimpleStringProperty(this.pinyinWithToneMarks), pinyinWithToneMarksProperty = SimpleStringProperty(this.pinyinWithToneMarks),
pinyinWithToneNumbersProperty = SimpleStringProperty(this.pinyinWithToneNumbers), pinyinWithToneNumbersProperty = SimpleStringProperty(this.pinyinWithToneNumbers),
zhuyinProperty = SimpleStringProperty(this.zhuyin), zhuyinProperty = SimpleStringProperty(this.zhuyin),
definitions = FXCollections.observableList(this.definitions) cedictDefinitions = FXCollections.observableList(this.cedictDefinitions),
crossStraitsDefinitions = FXCollections.observableList(this.crossStraitsDefinitions)
) )
fun DictionaryEntryFx.toDomain() = DictionaryEntry( fun DictionaryEntryFx.toDomain() = DictionaryEntry(
@ -30,5 +33,6 @@ fun DictionaryEntryFx.toDomain() = DictionaryEntry(
pinyinWithToneMarks = this.pinyinWithToneMarksProperty.value, pinyinWithToneMarks = this.pinyinWithToneMarksProperty.value,
pinyinWithToneNumbers = this.pinyinWithToneNumbersProperty.value, pinyinWithToneNumbers = this.pinyinWithToneNumbersProperty.value,
zhuyin = this.zhuyinProperty.value, zhuyin = this.zhuyinProperty.value,
definitions = this.definitions.toList() cedictDefinitions = this.cedictDefinitions.toList(),
crossStraitsDefinitions = this.crossStraitsDefinitions.toList()
) )

View File

@ -110,7 +110,7 @@ internal class EntryCell(private val resources: ResourceBundle, private val conf
) )
) )
val definition = entry.definitions.joinToString(separator = " / ") { it.joinToString(separator = "; ") } val definition = entry.cedictDefinitions.joinToString(separator = " / ") { it.joinToString(separator = "; ") }
labelDefinition.text = definition labelDefinition.text = definition
contextMenu = createContextMenuForEntry(entry, resources) contextMenu = createContextMenuForEntry(entry, resources)

View File

@ -17,10 +17,12 @@ import javafx.scene.input.ContextMenuEvent
import javafx.scene.layout.FlowPane import javafx.scene.layout.FlowPane
import javafx.scene.web.WebView import javafx.scene.web.WebView
import kotlinx.html.body import kotlinx.html.body
import kotlinx.html.div
import kotlinx.html.h1 import kotlinx.html.h1
import kotlinx.html.html import kotlinx.html.html
import kotlinx.html.li import kotlinx.html.li
import kotlinx.html.ol import kotlinx.html.ol
import kotlinx.html.span
import kotlinx.html.stream.createHTML import kotlinx.html.stream.createHTML
import java.util.ResourceBundle import java.util.ResourceBundle
@ -186,17 +188,16 @@ class DetailsController(private val model: Model, private val config: Config) {
model.selectedEntry.addListener { _, _, newEntry -> model.selectedEntry.addListener { _, _, newEntry ->
if (newEntry == null) return@addListener if (newEntry == null) return@addListener
webViewDefinition.engine.loadContent(newEntry.createCedictDefinitionHtml()) webViewDefinition.engine.loadContent(
} createHTML().html {
}
private fun DictionaryEntryFx.createCedictDefinitionHtml() = createHTML().html {
body { body {
if (newEntry.cedictDefinitions.isNotEmpty()) {
div(classes = "cedict-definition") {
h1 { h1 {
+"CC-CEDICT" +"CC-CEDICT"
} }
ol { ol {
for (definition in this@createCedictDefinitionHtml.definitions) { for (definition in newEntry.cedictDefinitions) {
li { li {
+definition.joinToString(separator = "; ") +definition.joinToString(separator = "; ")
} }
@ -204,6 +205,36 @@ class DetailsController(private val model: Model, private val config: Config) {
} }
} }
} }
if (newEntry.crossStraitsDefinitions.isNotEmpty()) {
div(classes = "cross-straits-definition") {
h1 {
+"Cross-Straits"
}
ol {
newEntry.crossStraitsDefinitions.forEach { definition ->
li {
span(classes = "definition") {
+definition.definition
}
if (definition.examples.isNotEmpty()) {
span(classes = "example") {
+definition.examples.joinToString(
prefix = "如:",
separator = "",
postfix = ""
) { "$it" }
}
}
}
}
}
}
}
}
}
)
}
}
@FXML @FXML
private fun headerOnContextMenuRequested(contextMenuEvent: ContextMenuEvent) { private fun headerOnContextMenuRequested(contextMenuEvent: ContextMenuEvent) {