Add templating script #11
45
README.md
45
README.md
@ -226,3 +226,48 @@ the current time. The device is configurable via a simple TornadoFX-based contro
|
||||
You can run a demo by executing `application/run` Gradle task.
|
||||
|
||||
The graphs are displayed using [plotly.kt](https://github.com/mipt-npm/plotly.kt) library.
|
||||
|
||||
## Templates
|
||||
|
||||
**This feature required `kotlin` to be installed in your system. [Read more](https://kotlinlang.org/docs/command-line.html#install-the-compiler)**
|
||||
|
||||
**You may run gradle task `generateKTStemplates` instead of raw launch, but it will work slowly. Sample `./gradlew generateKTStemplates`**
|
||||
|
||||
This project supports generating of files from `.ktstemplate.` files. Current docs:
|
||||
|
||||
### Using
|
||||
|
||||
* Create file contains `.ktstemplate` in its name
|
||||
* Write variables **before** the first `H*` (starting with `#`) section
|
||||
* Launch `kotlin ${thisscriptname}` with required args
|
||||
|
||||
#### File sample
|
||||
|
||||
```markdown
|
||||
first = hello
|
||||
second = world
|
||||
|
||||
# Sample
|
||||
|
||||
This is sample of $first $second
|
||||
```
|
||||
|
||||
Will have next result:
|
||||
|
||||
```markdown
|
||||
# Sample
|
||||
|
||||
This is sample of hello world
|
||||
```
|
||||
|
||||
### Launch
|
||||
|
||||
This script accept next args:
|
||||
|
||||
`[...paths] [--plain] [--recursive]`
|
||||
|
||||
Where:
|
||||
|
||||
* `...paths` - Paths to the files-templates or folders with files-templates
|
||||
* `--plain` - will look only into the folders from `paths`
|
||||
* `--recursive` - (default) will look into the folders from `paths` and recursively in subfolders
|
||||
|
@ -23,3 +23,11 @@ ksciencePublish {
|
||||
}
|
||||
|
||||
readme.readmeTemplate = file("docs/templates/README-TEMPLATE.md")
|
||||
|
||||
task("generateKTStemplates") {
|
||||
doLast {
|
||||
exec {
|
||||
commandLine("kotlin", "ktstemplate_generator.kts")
|
||||
}
|
||||
}
|
||||
}
|
25
controls-constructor/README.ktstemplate.md
Normal file
25
controls-constructor/README.ktstemplate.md
Normal file
@ -0,0 +1,25 @@
|
||||
package_group=space.kscience
|
||||
package_name=controls-constructor
|
||||
maven_url=https://maven.sciprog.center
|
||||
|
||||
# Module controls-constructor
|
||||
|
||||
A low-code constructor for composite devices simulation
|
||||
|
||||
## Usage
|
||||
|
||||
## Artifact:
|
||||
|
||||
The Maven coordinates of this project are `$package_group:$package_name:0.3.0`.
|
||||
|
||||
**Gradle Kotlin DSL:**
|
||||
```kotlin
|
||||
repositories {
|
||||
maven("https://repo.kotlin.link")
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("$package_group:$package_name:0.3.0")
|
||||
}
|
||||
```
|
151
ktstemplate_generator.kts
Normal file
151
ktstemplate_generator.kts
Normal file
@ -0,0 +1,151 @@
|
||||
/**
|
||||
* # Generating files from templates script
|
||||
*
|
||||
* ## Using
|
||||
*
|
||||
* * Create file contains `.ktstemplate` in its name
|
||||
* * Write variables **before** the first H* (starting with `#`) section
|
||||
* * Launch `kotlin ${thisscriptname}` with required args
|
||||
*
|
||||
* ### File sample
|
||||
*
|
||||
* ```markdown
|
||||
* first = hello
|
||||
* second = world
|
||||
*
|
||||
* # Sample
|
||||
*
|
||||
* This is sample of $first $second
|
||||
* ```
|
||||
*
|
||||
* Will have next result:
|
||||
*
|
||||
* ```markdown
|
||||
* # Sample
|
||||
*
|
||||
* This is sample of hello world
|
||||
* ```
|
||||
*
|
||||
* ## Launch
|
||||
*
|
||||
* This script accept next args:
|
||||
*
|
||||
* `[...paths] [--plain] [--recursive]`
|
||||
*
|
||||
* Where:
|
||||
*
|
||||
* * `...paths` - Paths to the files-templates or folders with files-templates
|
||||
* * `--plain` - will look only into the folders from `paths`
|
||||
* * `--recursive` - (default) will look into the folders from `paths` and recursively in subfolders
|
||||
*/
|
||||
import kotlin.collections.LinkedHashSet
|
||||
import java.io.File
|
||||
|
||||
val templateEnding = Regex("\\.ktstemplate(\\.[^\\.]*)*$")
|
||||
val templateOnlyEnding = Regex("\\.ktstemplate")
|
||||
val singleArgumentRegex = Regex("^[\\w\\d]+$")
|
||||
val splitterRegex = Regex("[ ]*=[ ]*")
|
||||
|
||||
sealed interface Mode {
|
||||
fun filesList(folder: File): Sequence<File>
|
||||
|
||||
data object Recursive : Mode {
|
||||
override fun filesList(folder: File): Sequence<File> {
|
||||
return sequence {
|
||||
val folders = mutableListOf<File>()
|
||||
folders.add(folder)
|
||||
while (folders.isNotEmpty()) {
|
||||
val currentFolder = folders.removeAt(0)
|
||||
currentFolder.listFiles().toList().forEach {
|
||||
when {
|
||||
it.isFile -> yield(it)
|
||||
it.isDirectory -> folders.add(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data object Plain : Mode {
|
||||
override fun filesList(folder: File): Sequence<File> {
|
||||
return sequence {
|
||||
folder.listFiles().forEach {
|
||||
yield(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var mode: Mode = Mode.Recursive
|
||||
|
||||
val folders = args.mapNotNull {
|
||||
if (it.startsWith("-")) { // assume some arg
|
||||
when (it) {
|
||||
"--plain" -> mode = Mode.Plain
|
||||
"--recursive" -> mode = Mode.Recursive
|
||||
"--help" -> {
|
||||
println("[...pathnames] [--recursive] [--plain]")
|
||||
println("...pathnames - Pass any count of folder or files paths")
|
||||
println("--recursive - (default) Use recursive visiting of folders for each path in pathnames")
|
||||
println("--plain - (default) Use plain (non-recursive) visiting of folders for each path in pathnames")
|
||||
}
|
||||
}
|
||||
null
|
||||
} else {
|
||||
File(it)
|
||||
}
|
||||
}.ifEmpty {
|
||||
listOf(File("./"))
|
||||
}
|
||||
|
||||
fun String.replaceVariables(variables: Map<String, String>): String {
|
||||
var currentLine = this
|
||||
variables.forEach { (k, v) ->
|
||||
currentLine = currentLine.replace("\${${k}}", v)
|
||||
if (k.matches(singleArgumentRegex)) {
|
||||
currentLine = currentLine.replace("\$${k}", v)
|
||||
}
|
||||
}
|
||||
return currentLine
|
||||
}
|
||||
|
||||
fun generateFromTemplate(folder: File, file: File) {
|
||||
val targetFile = File(folder, file.name.replace(templateOnlyEnding, ""))
|
||||
|
||||
val variables = mutableMapOf<String, String>()
|
||||
var writeVariables = true
|
||||
var text = ""
|
||||
|
||||
file.readLines().forEach { line ->
|
||||
when {
|
||||
writeVariables && line.startsWith("#") -> {
|
||||
writeVariables = false
|
||||
}
|
||||
writeVariables -> {
|
||||
val splitted = line.split(splitterRegex)
|
||||
if (splitted.size > 1) {
|
||||
val k = splitted[0]
|
||||
val v = splitted[1].replaceVariables(variables)
|
||||
variables[k] = v
|
||||
}
|
||||
return@forEach
|
||||
}
|
||||
}
|
||||
text += line.let {
|
||||
line.replaceVariables(variables) + "\n"
|
||||
}
|
||||
}
|
||||
targetFile.writeText(text)
|
||||
println("${targetFile.absolutePath} has been recreated")
|
||||
}
|
||||
|
||||
if (args.none { it == "--help" }) {
|
||||
folders.forEach { folder ->
|
||||
mode.filesList(folder).forEach { file ->
|
||||
if (file.name.contains(templateEnding)) {
|
||||
generateFromTemplate(file.parentFile, file)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user