mirror of https://github.com/pulumi/pulumi.git
129 lines
4.2 KiB
Go
129 lines
4.2 KiB
Go
// Copyright 2016-2020, Pulumi Corporation.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package docs
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
|
|
)
|
|
|
|
const (
|
|
beginCodeBlock = "<!--Start PulumiCodeChooser -->"
|
|
endCodeBlock = "<!--End PulumiCodeChooser -->"
|
|
)
|
|
|
|
type codeLocation struct {
|
|
open int
|
|
close int
|
|
}
|
|
|
|
func getCodeSection(doc string) []codeLocation {
|
|
var fences []codeLocation
|
|
|
|
startIndex := 0
|
|
for {
|
|
open := strings.Index(doc[startIndex:], beginCodeBlock)
|
|
if open == -1 {
|
|
break
|
|
}
|
|
var fence codeLocation
|
|
fence.open = startIndex + open
|
|
startIndex += open + len(beginCodeBlock)
|
|
closing := strings.Index(doc[startIndex:], endCodeBlock)
|
|
|
|
contract.Assertf(closing != -1, "this should never happen: "+
|
|
"there should be equal amounts of opening and closing code block markers")
|
|
|
|
fence.close = startIndex + closing
|
|
|
|
startIndex += closing + len(endCodeBlock)
|
|
fences = append(fences, fence)
|
|
}
|
|
return fences
|
|
}
|
|
|
|
func markupBlock(block, supportedSnippetLanguages string) string {
|
|
languages := []struct{ tag, choosable string }{
|
|
{"typescript", "<div>\n<pulumi-choosable type=\"language\" values=\"javascript,typescript\">\n\n"},
|
|
{"python", "<div>\n<pulumi-choosable type=\"language\" values=\"python\">\n\n"},
|
|
{"go", "<div>\n<pulumi-choosable type=\"language\" values=\"go\">\n\n"},
|
|
{"csharp", "<div>\n<pulumi-choosable type=\"language\" values=\"csharp\">\n\n"},
|
|
{"java", "<div>\n<pulumi-choosable type=\"language\" values=\"java\">\n\n"},
|
|
{"yaml", "<div>\n<pulumi-choosable type=\"language\" values=\"yaml\">\n\n"},
|
|
}
|
|
const (
|
|
//nolint:lll
|
|
chooserStartFmt = "<div>\n<pulumi-chooser type=\"language\" options=\"%s\"></pulumi-chooser>\n</div>\n"
|
|
choosableEnd = "</pulumi-choosable>\n</div>\n"
|
|
)
|
|
|
|
var markedUpBlock strings.Builder
|
|
// first, append the start chooser
|
|
markedUpBlock.WriteString(fmt.Sprintf(chooserStartFmt, supportedSnippetLanguages))
|
|
|
|
for _, lang := range languages {
|
|
// Add language specific open choosable
|
|
markedUpBlock.WriteString(lang.choosable)
|
|
// find our language - because we have no guarantee of order from our input, we need to find
|
|
// both code fences and then append the content in the order that docsgen expects.
|
|
start := strings.Index(block, "```"+lang.tag)
|
|
if start == -1 {
|
|
markedUpBlock.WriteString("```\n")
|
|
markedUpBlock.WriteString(defaultMissingExampleSnippetPlaceholder)
|
|
markedUpBlock.WriteString("\n```\n")
|
|
} else {
|
|
// find end index - this is the next code fence.
|
|
endLangBlock := start + len("```"+lang.tag) + strings.Index(block[start+len("```"+lang.tag):], "```")
|
|
// append code to block, and include code fences
|
|
markedUpBlock.WriteString(block[start : endLangBlock+len("```")])
|
|
markedUpBlock.WriteRune('\n')
|
|
}
|
|
// add closing choosable
|
|
markedUpBlock.WriteString(choosableEnd)
|
|
}
|
|
return markedUpBlock.String()
|
|
}
|
|
|
|
func (dctx *docGenContext) processDescription(description, supportedSnippetLanguages string) docInfo {
|
|
importDetails := ""
|
|
parts := strings.Split(description, "\n\n## Import")
|
|
if len(parts) > 1 {
|
|
importDetails = parts[1]
|
|
description = parts[0]
|
|
}
|
|
|
|
codeBlocks := getCodeSection(description)
|
|
|
|
startIndex := 0
|
|
var markedUpDescription string
|
|
for _, block := range codeBlocks {
|
|
// append text
|
|
markedUpDescription += description[startIndex:block.open]
|
|
codeBlock := description[block.open:block.close]
|
|
// append marked up block
|
|
markedUpDescription += markupBlock(codeBlock, supportedSnippetLanguages)
|
|
startIndex = block.close + len(endCodeBlock)
|
|
}
|
|
// append remainder of description, if any
|
|
markedUpDescription += description[startIndex:]
|
|
|
|
return docInfo{
|
|
description: markedUpDescription,
|
|
importDetails: importDetails,
|
|
}
|
|
}
|