From 0b60828e2546ad642a95b628ece5ad261447f3de Mon Sep 17 00:00:00 2001 From: "xiarui.xr" Date: Fri, 27 Oct 2023 15:52:36 +0800 Subject: [PATCH] enhance: doc gen: display attributes in table Signed-off-by: xiarui.xr --- pkg/tools/gen/gendoc.go | 9 +- pkg/tools/gen/genopenapi.go | 15 +- pkg/tools/gen/templates/doc/schemaDoc.gotmpl | 9 +- pkg/tools/gen/testdata/doc/k8s/md/main.md | 19 +-- pkg/tools/gen/testdata/doc/pkg/md/main.md | 142 ++++-------------- .../gen/testdata/doc/reimport/md/main.md | 21 ++- 6 files changed, 67 insertions(+), 148 deletions(-) diff --git a/pkg/tools/gen/gendoc.go b/pkg/tools/gen/gendoc.go index a4bd7e90..dd36fda0 100644 --- a/pkg/tools/gen/gendoc.go +++ b/pkg/tools/gen/gendoc.go @@ -174,8 +174,8 @@ func funcMap() template.FuncMap { } return false }, - "kclType": func(tpe KclOpenAPIType) string { - return tpe.GetKclTypeName(false, true) + "kclType": func(tpe KclOpenAPIType, escapeHtml bool) string { + return tpe.GetKclTypeName(false, true, escapeHtml) }, "fullTypeName": func(tpe KclOpenAPIType) string { if tpe.KclExtensions.XKclModelType.Import.Package != "" { @@ -186,8 +186,11 @@ func funcMap() template.FuncMap { "escapeHtml": func(original string, escapeHtml bool) string { // escape html symbols if needed if escapeHtml { - return htmlTmpl.HTMLEscapeString(original) + original = htmlTmpl.HTMLEscapeString(original) } + original = strings.Replace(original, "|", "\\|", -1) + original = strings.Replace(original, "\n", "
", -1) + original = strings.Replace(original, """, "\"", -1) return original }, "arr": func(els ...any) []any { diff --git a/pkg/tools/gen/genopenapi.go b/pkg/tools/gen/genopenapi.go index 28389633..fed55d6e 100644 --- a/pkg/tools/gen/genopenapi.go +++ b/pkg/tools/gen/genopenapi.go @@ -2,6 +2,7 @@ package gen import ( "fmt" + htmlTmpl "html/template" kpm "kcl-lang.io/kpm/pkg/api" "os" @@ -175,7 +176,7 @@ type XKclDecorators struct { } // GetKclTypeName get the string representation of a KclOpenAPIType -func (tpe *KclOpenAPIType) GetKclTypeName(omitAny bool, addLink bool) string { +func (tpe *KclOpenAPIType) GetKclTypeName(omitAny bool, addLink bool, escapeHtml bool) string { if tpe.Ref != "" { schemaId := Ref2SchemaId(tpe.Ref) schemaName := schemaId[strings.LastIndex(schemaId, ".")+1:] @@ -219,22 +220,26 @@ func (tpe *KclOpenAPIType) GetKclTypeName(omitAny bool, addLink bool) string { } return typBool case Array: - return fmt.Sprintf("[%s]", tpe.Items.GetKclTypeName(true, addLink)) + return fmt.Sprintf("[%s]", tpe.Items.GetKclTypeName(true, addLink, escapeHtml)) case Object: if tpe.AdditionalProperties != nil { // dict type if tpe.KclExtensions.XKclDictKeyType.isAnyType() && tpe.AdditionalProperties.isAnyType() { return "{}" } - return fmt.Sprintf("{%s:%s}", tpe.KclExtensions.XKclDictKeyType.GetKclTypeName(true, addLink), tpe.AdditionalProperties.GetKclTypeName(true, addLink)) + return fmt.Sprintf("{%s:%s}", tpe.KclExtensions.XKclDictKeyType.GetKclTypeName(true, addLink, escapeHtml), tpe.AdditionalProperties.GetKclTypeName(true, addLink, escapeHtml)) } if tpe.KclExtensions != nil && len(tpe.KclExtensions.XKclUnionTypes) > 0 { // union type tpes := make([]string, len(tpe.KclExtensions.XKclUnionTypes)) for i, unionType := range tpe.KclExtensions.XKclUnionTypes { - tpes[i] = unionType.GetKclTypeName(true, addLink) + tpes[i] = unionType.GetKclTypeName(true, addLink, escapeHtml) + } + if escapeHtml { + return strings.Join(tpes, htmlTmpl.HTMLEscapeString(" \\| ")) + } else { + return strings.Join(tpes, " | ") } - return strings.Join(tpes, " | ") } if tpe.isAnyType() { if omitAny { diff --git a/pkg/tools/gen/templates/doc/schemaDoc.gotmpl b/pkg/tools/gen/templates/doc/schemaDoc.gotmpl index fdafce11..5ee0d49f 100644 --- a/pkg/tools/gen/templates/doc/schemaDoc.gotmpl +++ b/pkg/tools/gen/templates/doc/schemaDoc.gotmpl @@ -8,12 +8,9 @@ {{end}} #### Attributes -{{range $name, $property := $Data.Properties}}**{{$name}}**{{if containsString $Data.Required $name }} *required*{{end}}{{if $property.ReadOnly}} *readOnly*{{end}} - -{{kclType $property}}{{if ne $property.Description ""}} - -{{escapeHtml $property.Description $EscapeHtml}}{{end}} - +| name | type | description | default value | +| --- | --- | --- | --- | +{{range $name, $property := $Data.Properties}}|**{{$name}}**{{if containsString $Data.Required $name }} `required`{{end}}{{if $property.ReadOnly}} `readOnly`{{end}}|{{kclType $property $EscapeHtml}}|{{if ne $property.Description ""}}{{escapeHtml $property.Description $EscapeHtml}}{{end}}|{{$property.Default}}| {{end}}{{if ne (len $Data.Examples) 0}}#### Examples {{range $name, $example := $Data.Examples}}{{if $example.Summary}}**$example.Summary** diff --git a/pkg/tools/gen/testdata/doc/k8s/md/main.md b/pkg/tools/gen/testdata/doc/k8s/md/main.md index f91ebd99..1d8848b3 100644 --- a/pkg/tools/gen/testdata/doc/k8s/md/main.md +++ b/pkg/tools/gen/testdata/doc/k8s/md/main.md @@ -13,20 +13,15 @@ #### Attributes -**metadata** *required* - -str - -**podSpec** *required* - -any - +| name | type | description | default value | +| --- | --- | --- | --- | +|**metadata** `required`|str||| +|**podSpec** `required`|any||| ### PodSpec #### Attributes -**image** *required* - -str - +| name | type | description | default value | +| --- | --- | --- | --- | +|**image** `required`|str||| diff --git a/pkg/tools/gen/testdata/doc/pkg/md/main.md b/pkg/tools/gen/testdata/doc/pkg/md/main.md index e0638d94..e4b98f12 100644 --- a/pkg/tools/gen/testdata/doc/pkg/md/main.md +++ b/pkg/tools/gen/testdata/doc/pkg/md/main.md @@ -17,110 +17,37 @@ Container is the common user interface for long-running services. #### Attributes -**name** *required* - -str - -The name of the long-running container. - +| name | type | description | default value | +| --- | --- | --- | --- | +|**name** `required`|str|The name of the long-running container.|| ### Server Server is the common user interface for long-running services adopting the best practice of Kubernetes. #### Attributes -**age** *required* - -int - -**antiSelf** *required* - -bool - -**backendWorkload** *required* - -[Deployment](#deployment) - -**containers** *required* - -[[Container](#container)] - -**dictAny** *required* - -{str:} - -**height** *required* - -float - -**labels** - -{str:str} - -A Server-level attribute. -The labels of the long-running service. Contains <key>:<value> pairs. -See also: kusion_models/core/v1/metadata.k. - -**listAny** *required* - -[] - -**litBool** *required* *readOnly* - -True - -**litFloat** *required* *readOnly* - -1.11 - -**litInt** *required* *readOnly* - -123 - -**litStr** *required* *readOnly* - -"abc" - -**mainContainer** *required* - -[Container](#container) - -**name** *required* - -str - -A Server-level attribute. -The name of the long-running service. -See also: kusion_models/core/v1/metadata.k. - -**numMultiplier** *required* - -units.NumberMultiplier - -**others** *required* - -any - -**port** *required* - -int | str - -**union** *required* - -"abc" | 123 | True | 1.11 | [Container](#container) | units.NumberMultiplier | 1M - -**union2** *required* - -"abc" | "def" - -**workloadType** *required* - -str - -Use this attribute to specify which kind of long-running service you want. -Valid values: Deployment, CafeDeployment. -See also: kusion_models/core/v1/workload_metadata.k. - +| name | type | description | default value | +| --- | --- | --- | --- | +|**age** `required`|int||| +|**antiSelf** `required`|bool||| +|**backendWorkload** `required`|[Deployment](#deployment)||| +|**containers** `required`|[[Container](#container)]||| +|**dictAny** `required`|{str:}||| +|**height** `required`|float||| +|**labels**|{str:str}|A Server-level attribute.
The labels of the long-running service. Contains <key>:<value> pairs.
See also: kusion_models/core/v1/metadata.k.|| +|**listAny** `required`|[]||| +|**litBool** `required` `readOnly`|True||True| +|**litFloat** `required` `readOnly`|1.11||1.11| +|**litInt** `required` `readOnly`|123||123| +|**litStr** `required` `readOnly`|"abc"||"abc"| +|**mainContainer** `required`|[Container](#container)||| +|**name** `required`|str|A Server-level attribute.
The name of the long-running service.
See also: kusion_models/core/v1/metadata.k.|| +|**numMultiplier** `required`|units.NumberMultiplier||1M| +|**others** `required`|any||| +|**port** `required`|int \| str||| +|**union** `required`|"abc" \| 123 \| True \| 1.11 \| [Container](#container) \| units.NumberMultiplier \| 1M||| +|**union2** `required`|"abc" \| "def"||"abc"| +|**workloadType** `required`|str|Use this attribute to specify which kind of long-running service you want.
Valid values: Deployment, CafeDeployment.
See also: kusion_models/core/v1/workload_metadata.k.|"Deployment"| #### Examples ``` @@ -133,20 +60,15 @@ myCustomApp = AppConfiguration { #### Attributes -**metadata** *required* - -str - -**podSpec** *required* - -[PodSpec](#podspec) - +| name | type | description | default value | +| --- | --- | --- | --- | +|**metadata** `required`|str||| +|**podSpec** `required`|[PodSpec](#podspec)||| ### PodSpec #### Attributes -**image** *required* - -str - +| name | type | description | default value | +| --- | --- | --- | --- | +|**image** `required`|str||| diff --git a/pkg/tools/gen/testdata/doc/reimport/md/main.md b/pkg/tools/gen/testdata/doc/reimport/md/main.md index 24936263..0fb25f71 100644 --- a/pkg/tools/gen/testdata/doc/reimport/md/main.md +++ b/pkg/tools/gen/testdata/doc/reimport/md/main.md @@ -13,24 +13,21 @@ #### Attributes -**attr** *required* - -[Deployment](#deployment) - +| name | type | description | default value | +| --- | --- | --- | --- | +|**attr** `required`|[Deployment](#deployment)||| ### B #### Attributes -**attr** *required* - -[Deployment](#deployment) - +| name | type | description | default value | +| --- | --- | --- | --- | +|**attr** `required`|[Deployment](#deployment)||| ### Deployment #### Attributes -**metadata** *required* - -str - +| name | type | description | default value | +| --- | --- | --- | --- | +|**metadata** `required`|str|||