Skip to content

Commit f609b1f

Browse files
authored
feat(project-creator): add keywords metadata (#253)
This PR introduces document keywords (introduced in #252) into the project creator wizard (`quarkdown create --keywords a,b,c`).
2 parents c06bdac + e00a9c3 commit f609b1f

File tree

6 files changed

+62
-1
lines changed

6 files changed

+62
-1
lines changed

quarkdown-cli/src/main/kotlin/com/quarkdown/cli/creator/command/CreateProjectCommand.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,16 @@ class CreateProjectCommand : CliktCommand("create") {
6666
private val description: String by option("--description", help = "Document description")
6767
.prompt("Document description (optional)")
6868

69+
private val keywordsRaw: String? by option("--keywords", help = "Document keywords (comma-separated)")
70+
71+
private val keywords: List<String> by lazy {
72+
keywordsRaw
73+
?.split(",")
74+
?.filter { it.isNotBlank() }
75+
?.map { it.trim() }
76+
?: emptyList()
77+
}
78+
6979
private fun findLocale(language: String): Locale? = LocaleLoader.SYSTEM.find(language)
7080

7181
private val languageRaw: String? by option("--lang", help = "Document language")
@@ -93,6 +103,7 @@ class CreateProjectCommand : CliktCommand("create") {
93103
name = name?.takeUnless { it.isBlank() } ?: directory.name,
94104
description = description.takeUnless { it.isBlank() },
95105
authors = authors.toMutableList(),
106+
keywords = keywords,
96107
type = type,
97108
locale = language,
98109
theme = DocumentTheme(colorTheme, layoutTheme),

quarkdown-cli/src/main/kotlin/com/quarkdown/cli/creator/template/DefaultProjectCreatorTemplateProcessorFactory.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ class DefaultProjectCreatorTemplateProcessorFactory(
2222
TemplateProcessor.fromResourceName(TEMPLATE).apply {
2323
optionalValue(NAME, info.name)
2424
optionalValue(DESCRIPTION, info.description)
25+
conditional(KEYWORDS, info.keywords.isNotEmpty())
26+
iterable(KEYWORDS, info.keywords)
2527
conditional(AUTHORS, info.authors.isNotEmpty())
2628
iterable(AUTHORS, info.authors.map { it.name })
2729
optionalValue(TYPE, info.type.quarkdownName)

quarkdown-cli/src/main/kotlin/com/quarkdown/cli/creator/template/ProjectCreatorTemplatePlaceholders.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package com.quarkdown.cli.creator.template
66
object ProjectCreatorTemplatePlaceholders {
77
const val NAME = "NAME"
88
const val DESCRIPTION = "DESCRIPTION"
9+
const val KEYWORDS = "KEYWORDS"
910
const val AUTHORS = "AUTHORS"
1011
const val TYPE = "TYPE"
1112
const val LANGUAGE = "LANG"

quarkdown-cli/src/main/resources/creator/main.qd.template

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66
.theme[[if:COLORTHEME]] {[[COLORTHEME]]}[[endif:COLORTHEME]][[if:LAYOUTTHEME]] layout:{[[LAYOUTTHEME]]}[[endif:LAYOUTTHEME]]
77
[[endif:THEME]]
88

9+
[[if:KEYWORDS]]
10+
.dockeywords
11+
[[for:KEYWORDS]]
12+
- [[KEYWORDS]]
13+
[[endfor:KEYWORDS]]
14+
[[endif:KEYWORDS]]
15+
916
[[if:AUTHORS]]
1017
.docauthors
1118
[[for:AUTHORS]]

quarkdown-cli/src/test/kotlin/com/quarkdown/cli/ProjectCreatorCommandTest.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,15 @@ class ProjectCreatorCommandTest : TempDirectory() {
2525
* @param fixedMainFileName whether to use a fixed main file name
2626
* @param directory directory to create the project in
2727
* @param includeDescription whether to include the description argument
28+
* @param includeKeywords whether to include the keywords argument
2829
* @return content of the main file
2930
*/
3031
private fun test(
3132
additionalArgs: Array<String> = emptyArray(),
3233
fixedMainFileName: Boolean = true,
3334
directory: File = super.directory,
3435
includeDescription: Boolean = true,
36+
includeKeywords: Boolean = true,
3537
): String {
3638
// resolve(".") tests the canonical path instead of the actual one.
3739
command.test(
@@ -51,6 +53,7 @@ class ProjectCreatorCommandTest : TempDirectory() {
5153
"--layout-theme",
5254
"latex",
5355
*additionalArgs,
56+
*if (includeKeywords) arrayOf("--keywords", "testing,slides, quarkdown") else emptyArray(),
5457
*if (fixedMainFileName) arrayOf("--main-file", "main") else emptyArray(),
5558
)
5659
assertTrue(directory.exists())
@@ -64,6 +67,9 @@ class ProjectCreatorCommandTest : TempDirectory() {
6467
if (includeDescription) {
6568
assertTrue(".docdescription {A test document for slides}" in main)
6669
}
70+
if (includeKeywords) {
71+
assertTrue(".dockeywords\n - testing\n - slides\n - quarkdown" in main)
72+
}
6773
assertTrue("- Aaa" in main)
6874
assertTrue("- Bbb" in main)
6975
assertTrue("- Ccc" in main)
@@ -104,4 +110,10 @@ class ProjectCreatorCommandTest : TempDirectory() {
104110
val main = test(includeDescription = false)
105111
assertTrue(".docdescription" !in main)
106112
}
113+
114+
@Test
115+
fun `no keywords`() {
116+
val main = test(includeKeywords = false)
117+
assertTrue(".dockeywords" !in main)
118+
}
107119
}

quarkdown-cli/src/test/kotlin/com/quarkdown/cli/ProjectCreatorTest.kt

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,28 @@ class ProjectCreatorTest {
7070
assertEquals(".docname {Test}\n.docdescription {A test document}\n.doctype {plain}", resources.first().textContent)
7171
}
7272

73+
@Test
74+
fun `only keywords`() {
75+
val creator = projectCreator(DocumentInfo(keywords = listOf("kotlin", "testing")))
76+
val resources = creator.createResources()
77+
assertEquals(1, resources.size)
78+
assertEquals(
79+
".doctype {plain}\n\n.dockeywords\n - kotlin\n - testing",
80+
resources.first().textContent,
81+
)
82+
}
83+
84+
@Test
85+
fun `name and keywords`() {
86+
val creator = projectCreator(DocumentInfo(name = "Test", keywords = listOf("kotlin", "documentation")))
87+
val resources = creator.createResources()
88+
assertEquals(1, resources.size)
89+
assertEquals(
90+
".docname {Test}\n.doctype {plain}\n\n.dockeywords\n - kotlin\n - documentation",
91+
resources.first().textContent,
92+
)
93+
}
94+
7395
private val singleAuthor: MutableList<DocumentAuthor>
7496
get() = mutableListOf(DocumentAuthor("Giorgio"))
7597

@@ -186,12 +208,13 @@ class ProjectCreatorTest {
186208
}
187209

188210
@Test
189-
fun `name, description, locale, theme and author`() {
211+
fun `name, description, keywords, locale, theme and author`() {
190212
val creator =
191213
projectCreator(
192214
DocumentInfo(
193215
name = "Comprehensive Test",
194216
description = "A comprehensive test document",
217+
keywords = listOf("test", "kotlin", "quarkdown"),
195218
locale = LocaleLoader.SYSTEM.find("en")!!,
196219
theme = DocumentTheme(color = "dark", layout = "minimal"),
197220
authors = singleAuthor,
@@ -207,6 +230,11 @@ class ProjectCreatorTest {
207230
.doclang {English}
208231
.theme {dark} layout:{minimal}
209232
233+
.dockeywords
234+
- test
235+
- kotlin
236+
- quarkdown
237+
210238
.docauthors
211239
- Giorgio
212240
""".trimIndent(),

0 commit comments

Comments
 (0)