Skip to content

Commit 68783b2

Browse files
committed
Improve documentation formatting (#778)
* Move Documentation sanitize to a rule * Improve formatting
1 parent 0ba5d6e commit 68783b2

File tree

628 files changed

+7661
-875
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

628 files changed

+7661
-875
lines changed

kt/api-generator/src/main/kotlin/godot/codegen/generation/rule/FileRule.kt

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ package godot.codegen.generation.rule
33
import com.squareup.kotlinpoet.AnnotationSpec
44
import com.squareup.kotlinpoet.ClassName
55
import godot.codegen.generation.Context
6+
import godot.codegen.generation.task.ApiTask
67
import godot.codegen.generation.task.EnrichedClassTask
78
import godot.codegen.generation.task.EnrichedEnumTask
89
import godot.codegen.generation.task.FileTask
910
import godot.codegen.models.enriched.EnrichedClass
1011
import godot.codegen.models.enriched.EnrichedEnum
12+
import godot.common.extensions.convertToCamelCase
1113
import godot.tools.common.constants.GENERATED_COMMENT
1214

1315
class FileRule : GodotApiRule<FileTask>() {
@@ -71,3 +73,133 @@ class StaticRule : GodotApiRule<FileTask>() {
7173
}
7274
}
7375
}
76+
77+
private const val constantTitle = "constant"
78+
79+
class DocumentationRule : GodotApiRule<ApiTask>() {
80+
data class TypeBlock(val regex: Regex) {
81+
constructor(name: String) :
82+
this(Regex("""\[($name\s)(\S+)(])"""))
83+
}
84+
85+
private val typeToSanitize = arrayOf(
86+
TypeBlock("member"),
87+
TypeBlock("method"),
88+
TypeBlock("enum"),
89+
TypeBlock(constantTitle),
90+
TypeBlock("param")
91+
)
92+
93+
data class TagBlock(val output: String, val regex: Regex) {
94+
constructor(input: String, output: String) :
95+
this(
96+
output,
97+
Regex("""(\[$input])((?:(?!\[/$input]|\[$input]).)*)(\[/$input])""")
98+
)
99+
}
100+
101+
private val tagsToSanitize = arrayOf(
102+
TagBlock("code", "`"),
103+
TagBlock("i", "*"),
104+
TagBlock("b", "**")
105+
)
106+
107+
data class CodeBlock(val input: String, val named: Boolean)
108+
109+
private val languages = arrayOf(
110+
CodeBlock("gdscript", true),
111+
CodeBlock("csharp", true),
112+
CodeBlock("codeblock", false),
113+
)
114+
private val codeBlockRegex = Regex("""```[\s\S]*?```""")
115+
private val doubleSkipRegex = Regex("(?<!\n)\n(?!\n)")
116+
117+
override fun apply(fileTask: ApiTask, context: Context) {
118+
val enumValues = context
119+
.enumRepository
120+
.getGlobalEnums()
121+
.flatMap { it.values }
122+
123+
val classes = context.classRepository.listTypes()
124+
val members = classes.flatMap { it.methods + it.properties + it.constants + it.signals }
125+
val innerEnumValue = classes.flatMap { it.enums }.flatMap { it.values }
126+
127+
val allDocumented = enumValues + classes + members + innerEnumValue
128+
129+
allDocumented.forEach {
130+
it.description = sanitize(it.description)
131+
}
132+
}
133+
134+
private fun sanitize(documentation: String?): String {
135+
if (documentation.isNullOrEmpty()) {
136+
return ""
137+
}
138+
139+
var unicodeString = documentation
140+
.replace("/*", "&#47;*")
141+
.replace("%", "&#37;")
142+
.replace("*/", "*&#92;")
143+
.replace(System.lineSeparator(), "\n")
144+
145+
for ((regex) in typeToSanitize) {
146+
var matchResult = unicodeString.let { regex.find(it) }
147+
while (matchResult != null) {
148+
val titleRange = matchResult.groups[1]!!.range
149+
val contentRange = matchResult.groups[2]!!.range
150+
val content = with(unicodeString.substring(contentRange)) {
151+
if (unicodeString.substring(titleRange).startsWith(constantTitle)) {
152+
return@with this
153+
}
154+
convertToCamelCase()
155+
}
156+
unicodeString = unicodeString
157+
.replaceRange(contentRange, content)
158+
.removeRange(titleRange)
159+
matchResult = unicodeString.let { regex.find(it) }
160+
}
161+
}
162+
163+
for ((output, regex) in tagsToSanitize) {
164+
var matchResult = unicodeString.let { regex.find(it) }
165+
while (matchResult != null) {
166+
val endTagRange = matchResult.groups[3]!!.range
167+
val beginTagRange = matchResult.groups[1]!!.range
168+
unicodeString = unicodeString
169+
.replaceRange(endTagRange, output)
170+
.replaceRange(beginTagRange, output)
171+
matchResult = unicodeString.let { regex.find(it) }
172+
}
173+
}
174+
175+
unicodeString = unicodeString
176+
.replace("[codeblocks]", "")
177+
.replace("[/codeblocks]", "")
178+
179+
for ((language, named) in languages) {
180+
unicodeString = unicodeString
181+
.replace("[$language]", "```${if (named) "$language\n//$language" else ""}")
182+
.replace("[/$language]", "```")
183+
}
184+
185+
// Split the document into parts outside the code blocks
186+
val parts = codeBlockRegex.split(unicodeString)
187+
// Find all code blocks to reinsert later
188+
val codeBlocks = codeBlockRegex.findAll(unicodeString).map { it.value }.iterator()
189+
val sanitized = StringBuilder()
190+
parts.forEachIndexed { index, part ->
191+
// Replace single newlines with double newlines in non-code parts.
192+
// This regex finds newline characters that are not already doubled.
193+
sanitized.append(
194+
part.replace(doubleSkipRegex, "\n\n")
195+
)
196+
// If there's a corresponding code block, reinsert it unchanged.
197+
if (codeBlocks.hasNext()) {
198+
sanitized.append(codeBlocks.next())
199+
}
200+
}
201+
unicodeString = sanitized.toString()
202+
203+
return unicodeString
204+
}
205+
}

kt/api-generator/src/main/kotlin/godot/codegen/generation/rule/PropertyRule.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,9 @@ class CoreTypeHelperRule : GodotApiRule<EnrichedClassTask>() {
165165
|""".trimMargin()
166166
).apply {
167167
val kDoc = buildString {
168-
val propertyKdoc =
169-
property.sanitizedDocumentation
170-
if (propertyKdoc != null) {
171-
appendLine(propertyKdoc.replace("/*", "&#47;*"))
168+
val propertyKdoc = property.description
169+
if (propertyKdoc != null && propertyKdoc.isNotBlank()) {
170+
appendLine(propertyKdoc)
172171
appendLine()
173172
}
174173

kt/api-generator/src/main/kotlin/godot/codegen/models/EnumValue.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ import godot.codegen.traits.IDocumented
77
data class EnumValue @JsonCreator constructor(
88
@JsonProperty("name") val name: String,
99
@JsonProperty("value") val value: Long,
10-
@JsonProperty("description") override val description: String? = null
11-
) : IDocumented
10+
@JsonProperty("description") val description: String? = null
11+
)

kt/api-generator/src/main/kotlin/godot/codegen/models/Member.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import godot.codegen.traits.TypedTrait
66

77
data class Member @JsonCreator constructor(
88
@JsonProperty("name") val name: String,
9-
@JsonProperty("type") override val type: String,
9+
@JsonProperty("type") val type: String,
1010
@JsonProperty("description") val description: String?,
1111
@JsonProperty("brief_description") val briefDescription: String?
12-
) : TypedTrait
12+
)

kt/api-generator/src/main/kotlin/godot/codegen/models/Property.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ import com.fasterxml.jackson.annotation.JsonProperty
55
import godot.codegen.traits.TypedTrait
66

77
data class Property @JsonCreator constructor(
8-
@JsonProperty("type") override val type: String,
8+
@JsonProperty("type") val type: String,
99
@JsonProperty("name") val name: String,
1010
@JsonProperty("setter") val setter: String?,
1111
@JsonProperty("getter") val getter: String,
1212
@JsonProperty("index") val index: Int?,
1313
@JsonProperty("description") val description: String?,
1414
@JsonProperty("brief_description") val briefDescription: String?
15-
) : TypedTrait
15+
)

kt/api-generator/src/main/kotlin/godot/codegen/models/ReturnValue.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ import com.fasterxml.jackson.annotation.JsonProperty
55
import godot.codegen.traits.CastableTrait
66

77
data class ReturnValue @JsonCreator constructor(
8-
@JsonProperty("type") override val type: String,
9-
@JsonProperty("meta") override val meta: String?,
10-
) : CastableTrait
8+
@JsonProperty("type") val type: String,
9+
@JsonProperty("meta") val meta: String?,
10+
)

kt/api-generator/src/main/kotlin/godot/codegen/models/Singleton.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ import godot.codegen.traits.TypedTrait
66

77
data class Singleton @JsonCreator constructor(
88
@JsonProperty("name") val name: String,
9-
@JsonProperty("type") override val type: String
10-
) : TypedTrait
9+
@JsonProperty("type") val type: String
10+
)

kt/api-generator/src/main/kotlin/godot/codegen/models/enriched/EnrichedClass.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class EnrichedClass(model: Class) : TypedTrait, IDocumented {
2222
val properties = model.properties?.toEnriched() ?: listOf()
2323
val methods = model.methods?.toEnriched() ?: listOf()
2424

25-
override val description = model.description
25+
override var description = model.description
2626
val additionalImports = mutableSetOf<AdditionalImport>()
2727

2828
fun makeSingleton() {

kt/api-generator/src/main/kotlin/godot/codegen/models/enriched/EnrichedConstant.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class EnrichedConstant(model: Constant) : TypedTrait, IDocumented {
99
override val type = model.type?.sanitizeApiType() ?: "int"
1010
val name = model.name
1111
val value = model.value
12-
override val description = model.description
12+
override var description = model.description
1313
}
1414

1515
fun List<Constant>.toEnriched() = map { EnrichedConstant(it) }

kt/api-generator/src/main/kotlin/godot/codegen/models/enriched/EnrichedEnum.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class EnrichedEnum(model: Enum, val outerClass: String?) : TypedTrait {
3131
}
3232
}
3333

34-
class EnrichedEnumValue(valueName: String, ownerName: String, val value: Long, override val description: String?) : IDocumented {
34+
class EnrichedEnumValue(valueName: String, ownerName: String, val value: Long, override var description: String?) : IDocumented {
3535
val name = run {
3636
val uppercaseName = ownerName.toUpperSnakeCase()
3737
val prefixRemoved = valueName

0 commit comments

Comments
 (0)