From cc78abbcb570e329eb145854481acfcb1072f307 Mon Sep 17 00:00:00 2001 From: Jeff Principe Date: Sun, 2 Apr 2023 09:35:22 -0700 Subject: [PATCH] feat: add support for links in documentation (#89) --- README.md | 48 +-- cmd/gomarkdoc/README.md | 5 +- format/README.md | 328 +++++++++++++----- format/devops.go | 29 +- format/format.go | 19 +- format/formatcore/README.md | 88 +++-- format/formatcore/base.go | 25 +- format/github.go | 29 +- format/plain.go | 31 +- lang/README.md | 568 +++++++++++++++++++++++-------- lang/block.go | 61 ++-- lang/config.go | 48 +++ lang/doc.go | 7 +- lang/func.go | 16 + lang/package.go | 46 +-- lang/span.go | 137 ++++++++ lang/symbol.go | 181 ++++++++++ lang/type.go | 8 + lang/value.go | 15 + renderer.go | 5 +- templates.go | 47 ++- templates/doc.gotxt | 7 +- templates/func.gotxt | 4 +- templates/index.gotxt | 20 +- templates/text.gotxt | 11 + templates/type.gotxt | 2 +- templates/value.gotxt | 1 + testData/docs/README.md | 91 ++++- testData/docs/anotherFile.go | 19 ++ testData/docs/docs.go | 28 +- testData/embed/README.md | 9 +- testData/lang/function/README.md | 25 +- testData/nested/README.md | 3 +- testData/nested/inner/README.md | 3 +- testData/simple/README.md | 9 +- testData/tags/README.md | 6 +- testData/unexported/README.md | 12 +- testData/untagged/README.md | 3 +- 38 files changed, 1516 insertions(+), 478 deletions(-) create mode 100644 lang/span.go create mode 100644 lang/symbol.go create mode 100644 templates/text.gotxt create mode 100644 testData/docs/anotherFile.go diff --git a/README.md b/README.md index b97a9ec..7ddd8ce 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ import "github.com/princjef/gomarkdoc" ``` -Package gomarkdoc formats documentation for one or more packages as markdown for usage outside of the main https://pkg.go.dev site. It supports custom templates for tweaking representation of documentation at fine\-grained levels, exporting both exported and unexported symbols, and custom formatters for different backends. +Package gomarkdoc formats documentation for one or more packages as markdown for usage outside of the main https://pkg.go.dev[https://pkg.go.dev]() site. It supports custom templates for tweaking representation of documentation at fine\-grained levels, exporting both exported and unexported symbols, and custom formatters for different backends. ### Command Line Usage @@ -100,7 +100,7 @@ The documentation information that is output is formatted using a series of text - index: generates an index of symbols within a package, similar to what is seen for godoc.org. The index links to types, funcs, variables, and constants generated by other templates, so it may need to be overridden as well if any of those templates are changed in a material way. -- example: generates documentation for a single example for a package or one of its symbols. The example is generated alongside whichever symbol it represents, based on the standard naming conventions outlined in https://blog.golang.org/examples#TOC_4 . +- example: generates documentation for a single example for a package or one of its symbols. The example is generated alongside whichever symbol it represents, based on the standard naming conventions outlined in https://blog.golang.org/examples#TOC_4[https://blog.golang.org/examples#TOC_4](). - doc: generates the freeform documentation block for any of the above structures that can contain a documentation section. @@ -229,18 +229,19 @@ Know of another project that is using gomarkdoc? Open an issue with a descriptio ## Index -- [type Renderer](<#type-renderer>) - - [func NewRenderer(opts ...RendererOption) (*Renderer, error)](<#func-newrenderer>) - - [func (out *Renderer) Example(ex *lang.Example) (string, error)](<#func-renderer-example>) - - [func (out *Renderer) File(file *lang.File) (string, error)](<#func-renderer-file>) - - [func (out *Renderer) Func(fn *lang.Func) (string, error)](<#func-renderer-func>) - - [func (out *Renderer) Package(pkg *lang.Package) (string, error)](<#func-renderer-package>) - - [func (out *Renderer) Type(typ *lang.Type) (string, error)](<#func-renderer-type>) -- [type RendererOption](<#type-rendereroption>) - - [func WithFormat(format format.Format) RendererOption](<#func-withformat>) - - [func WithTemplateOverride(name, tmpl string) RendererOption](<#func-withtemplateoverride>) +- [type Renderer](<#Renderer>) + - [func NewRenderer(opts ...RendererOption) (*Renderer, error)](<#NewRenderer>) + - [func (out *Renderer) Example(ex *lang.Example) (string, error)](<#Renderer.Example>) + - [func (out *Renderer) File(file *lang.File) (string, error)](<#Renderer.File>) + - [func (out *Renderer) Func(fn *lang.Func) (string, error)](<#Renderer.Func>) + - [func (out *Renderer) Package(pkg *lang.Package) (string, error)](<#Renderer.Package>) + - [func (out *Renderer) Type(typ *lang.Type) (string, error)](<#Renderer.Type>) +- [type RendererOption](<#RendererOption>) + - [func WithFormat(format format.Format) RendererOption](<#WithFormat>) + - [func WithTemplateOverride(name, tmpl string) RendererOption](<#WithTemplateOverride>) + ## type [Renderer]() Renderer provides capabilities for rendering various types of documentation with the configured format and templates. @@ -251,6 +252,7 @@ type Renderer struct { } ``` + ### func [NewRenderer]() ```go @@ -259,7 +261,8 @@ func NewRenderer(opts ...RendererOption) (*Renderer, error) NewRenderer initializes a Renderer configured using the provided options. If nothing special is provided, the created renderer will use the default set of templates and the GitHubFlavoredMarkdown. -### func \(\*Renderer\) [Example]() + +### func \(\*Renderer\) [Example]() ```go func (out *Renderer) Example(ex *lang.Example) (string, error) @@ -267,7 +270,8 @@ func (out *Renderer) Example(ex *lang.Example) (string, error) Example renders an example's documentation to a string. You can change the rendering of the example by overriding the "example" template or one of the templates it references. -### func \(\*Renderer\) [File]() + +### func \(\*Renderer\) [File]() ```go func (out *Renderer) File(file *lang.File) (string, error) @@ -275,7 +279,8 @@ func (out *Renderer) File(file *lang.File) (string, error) File renders a file containing one or more packages to document to a string. You can change the rendering of the file by overriding the "file" template or one of the templates it references. -### func \(\*Renderer\) [Func]() + +### func \(\*Renderer\) [Func]() ```go func (out *Renderer) Func(fn *lang.Func) (string, error) @@ -283,7 +288,8 @@ func (out *Renderer) Func(fn *lang.Func) (string, error) Func renders a function's documentation to a string. You can change the rendering of the package by overriding the "func" template or one of the templates it references. -### func \(\*Renderer\) [Package]() + +### func \(\*Renderer\) [Package]() ```go func (out *Renderer) Package(pkg *lang.Package) (string, error) @@ -291,7 +297,8 @@ func (out *Renderer) Package(pkg *lang.Package) (string, error) Package renders a package's documentation to a string. You can change the rendering of the package by overriding the "package" template or one of the templates it references. -### func \(\*Renderer\) [Type]() + +### func \(\*Renderer\) [Type]() ```go func (out *Renderer) Type(typ *lang.Type) (string, error) @@ -299,6 +306,7 @@ func (out *Renderer) Type(typ *lang.Type) (string, error) Type renders a type's documentation to a string. You can change the rendering of the type by overriding the "type" template or one of the templates it references. + ## type [RendererOption]() RendererOption configures the renderer's behavior. @@ -307,7 +315,8 @@ RendererOption configures the renderer's behavior. type RendererOption func(renderer *Renderer) error ``` -### func [WithFormat]() + +### func [WithFormat]() ```go func WithFormat(format format.Format) RendererOption @@ -315,7 +324,8 @@ func WithFormat(format format.Format) RendererOption WithFormat changes the renderer to use the format provided instead of the default format. -### func [WithTemplateOverride]() + +### func [WithTemplateOverride]() ```go func WithTemplateOverride(name, tmpl string) RendererOption diff --git a/cmd/gomarkdoc/README.md b/cmd/gomarkdoc/README.md index 2f1914e..1f6d7dd 100644 --- a/cmd/gomarkdoc/README.md +++ b/cmd/gomarkdoc/README.md @@ -8,13 +8,14 @@ import "github.com/princjef/gomarkdoc/cmd/gomarkdoc" Package gomarkdoc provides a command line interface for writing golang documentation in markdown format. -See https://github.com/princjef/gomarkdoc for full documentation of this tool. +See https://github.com/princjef/gomarkdoc[https://github.com/princjef/gomarkdoc]() for full documentation of this tool. ## Index -- [type PackageSpec](<#type-packagespec>) +- [type PackageSpec](<#PackageSpec>) + ## type [PackageSpec]() PackageSpec defines the data available to the \-\-output option's template. Information is recomputed for each package generated. diff --git a/format/README.md b/format/README.md index 280bc13..24059a4 100755 --- a/format/README.md +++ b/format/README.md @@ -12,60 +12,71 @@ Each of the formats in this package contains the same set of formatting function ## Index -- [type AzureDevOpsMarkdown](<#type-azuredevopsmarkdown>) - - [func (f *AzureDevOpsMarkdown) Accordion(title, body string) (string, error)](<#func-azuredevopsmarkdown-accordion>) - - [func (f *AzureDevOpsMarkdown) AccordionHeader(title string) (string, error)](<#func-azuredevopsmarkdown-accordionheader>) - - [func (f *AzureDevOpsMarkdown) AccordionTerminator() (string, error)](<#func-azuredevopsmarkdown-accordionterminator>) - - [func (f *AzureDevOpsMarkdown) Bold(text string) (string, error)](<#func-azuredevopsmarkdown-bold>) - - [func (f *AzureDevOpsMarkdown) CodeBlock(language, code string) (string, error)](<#func-azuredevopsmarkdown-codeblock>) - - [func (f *AzureDevOpsMarkdown) CodeHref(loc lang.Location) (string, error)](<#func-azuredevopsmarkdown-codehref>) - - [func (f *AzureDevOpsMarkdown) Escape(text string) string](<#func-azuredevopsmarkdown-escape>) - - [func (f *AzureDevOpsMarkdown) Header(level int, text string) (string, error)](<#func-azuredevopsmarkdown-header>) - - [func (f *AzureDevOpsMarkdown) Link(text, href string) (string, error)](<#func-azuredevopsmarkdown-link>) - - [func (f *AzureDevOpsMarkdown) ListEntry(depth int, text string) (string, error)](<#func-azuredevopsmarkdown-listentry>) - - [func (f *AzureDevOpsMarkdown) LocalHref(headerText string) (string, error)](<#func-azuredevopsmarkdown-localhref>) - - [func (f *AzureDevOpsMarkdown) Paragraph(text string) (string, error)](<#func-azuredevopsmarkdown-paragraph>) - - [func (f *AzureDevOpsMarkdown) RawHeader(level int, text string) (string, error)](<#func-azuredevopsmarkdown-rawheader>) -- [type Format](<#type-format>) -- [type GitHubFlavoredMarkdown](<#type-githubflavoredmarkdown>) - - [func (f *GitHubFlavoredMarkdown) Accordion(title, body string) (string, error)](<#func-githubflavoredmarkdown-accordion>) - - [func (f *GitHubFlavoredMarkdown) AccordionHeader(title string) (string, error)](<#func-githubflavoredmarkdown-accordionheader>) - - [func (f *GitHubFlavoredMarkdown) AccordionTerminator() (string, error)](<#func-githubflavoredmarkdown-accordionterminator>) - - [func (f *GitHubFlavoredMarkdown) Bold(text string) (string, error)](<#func-githubflavoredmarkdown-bold>) - - [func (f *GitHubFlavoredMarkdown) CodeBlock(language, code string) (string, error)](<#func-githubflavoredmarkdown-codeblock>) - - [func (f *GitHubFlavoredMarkdown) CodeHref(loc lang.Location) (string, error)](<#func-githubflavoredmarkdown-codehref>) - - [func (f *GitHubFlavoredMarkdown) Escape(text string) string](<#func-githubflavoredmarkdown-escape>) - - [func (f *GitHubFlavoredMarkdown) Header(level int, text string) (string, error)](<#func-githubflavoredmarkdown-header>) - - [func (f *GitHubFlavoredMarkdown) Link(text, href string) (string, error)](<#func-githubflavoredmarkdown-link>) - - [func (f *GitHubFlavoredMarkdown) ListEntry(depth int, text string) (string, error)](<#func-githubflavoredmarkdown-listentry>) - - [func (f *GitHubFlavoredMarkdown) LocalHref(headerText string) (string, error)](<#func-githubflavoredmarkdown-localhref>) - - [func (f *GitHubFlavoredMarkdown) Paragraph(text string) (string, error)](<#func-githubflavoredmarkdown-paragraph>) - - [func (f *GitHubFlavoredMarkdown) RawHeader(level int, text string) (string, error)](<#func-githubflavoredmarkdown-rawheader>) -- [type PlainMarkdown](<#type-plainmarkdown>) - - [func (f *PlainMarkdown) Accordion(title, body string) (string, error)](<#func-plainmarkdown-accordion>) - - [func (f *PlainMarkdown) AccordionHeader(title string) (string, error)](<#func-plainmarkdown-accordionheader>) - - [func (f *PlainMarkdown) AccordionTerminator() (string, error)](<#func-plainmarkdown-accordionterminator>) - - [func (f *PlainMarkdown) Bold(text string) (string, error)](<#func-plainmarkdown-bold>) - - [func (f *PlainMarkdown) CodeBlock(language, code string) (string, error)](<#func-plainmarkdown-codeblock>) - - [func (f *PlainMarkdown) CodeHref(loc lang.Location) (string, error)](<#func-plainmarkdown-codehref>) - - [func (f *PlainMarkdown) Escape(text string) string](<#func-plainmarkdown-escape>) - - [func (f *PlainMarkdown) Header(level int, text string) (string, error)](<#func-plainmarkdown-header>) - - [func (f *PlainMarkdown) Link(text, href string) (string, error)](<#func-plainmarkdown-link>) - - [func (f *PlainMarkdown) ListEntry(depth int, text string) (string, error)](<#func-plainmarkdown-listentry>) - - [func (f *PlainMarkdown) LocalHref(headerText string) (string, error)](<#func-plainmarkdown-localhref>) - - [func (f *PlainMarkdown) Paragraph(text string) (string, error)](<#func-plainmarkdown-paragraph>) - - [func (f *PlainMarkdown) RawHeader(level int, text string) (string, error)](<#func-plainmarkdown-rawheader>) - - +- [type AzureDevOpsMarkdown](<#AzureDevOpsMarkdown>) + - [func (f *AzureDevOpsMarkdown) Accordion(title, body string) (string, error)](<#AzureDevOpsMarkdown.Accordion>) + - [func (f *AzureDevOpsMarkdown) AccordionHeader(title string) (string, error)](<#AzureDevOpsMarkdown.AccordionHeader>) + - [func (f *AzureDevOpsMarkdown) AccordionTerminator() (string, error)](<#AzureDevOpsMarkdown.AccordionTerminator>) + - [func (f *AzureDevOpsMarkdown) Anchor(anchor string) string](<#AzureDevOpsMarkdown.Anchor>) + - [func (f *AzureDevOpsMarkdown) AnchorHeader(level int, text, anchor string) (string, error)](<#AzureDevOpsMarkdown.AnchorHeader>) + - [func (f *AzureDevOpsMarkdown) Bold(text string) (string, error)](<#AzureDevOpsMarkdown.Bold>) + - [func (f *AzureDevOpsMarkdown) CodeBlock(language, code string) (string, error)](<#AzureDevOpsMarkdown.CodeBlock>) + - [func (f *AzureDevOpsMarkdown) CodeHref(loc lang.Location) (string, error)](<#AzureDevOpsMarkdown.CodeHref>) + - [func (f *AzureDevOpsMarkdown) Escape(text string) string](<#AzureDevOpsMarkdown.Escape>) + - [func (f *AzureDevOpsMarkdown) Header(level int, text string) (string, error)](<#AzureDevOpsMarkdown.Header>) + - [func (f *AzureDevOpsMarkdown) Link(text, href string) (string, error)](<#AzureDevOpsMarkdown.Link>) + - [func (f *AzureDevOpsMarkdown) ListEntry(depth int, text string) (string, error)](<#AzureDevOpsMarkdown.ListEntry>) + - [func (f *AzureDevOpsMarkdown) LocalHref(headerText string) (string, error)](<#AzureDevOpsMarkdown.LocalHref>) + - [func (f *AzureDevOpsMarkdown) RawAnchorHeader(level int, text, anchor string) (string, error)](<#AzureDevOpsMarkdown.RawAnchorHeader>) + - [func (f *AzureDevOpsMarkdown) RawHeader(level int, text string) (string, error)](<#AzureDevOpsMarkdown.RawHeader>) + - [func (f *AzureDevOpsMarkdown) RawLocalHref(anchor string) string](<#AzureDevOpsMarkdown.RawLocalHref>) +- [type Format](<#Format>) +- [type GitHubFlavoredMarkdown](<#GitHubFlavoredMarkdown>) + - [func (f *GitHubFlavoredMarkdown) Accordion(title, body string) (string, error)](<#GitHubFlavoredMarkdown.Accordion>) + - [func (f *GitHubFlavoredMarkdown) AccordionHeader(title string) (string, error)](<#GitHubFlavoredMarkdown.AccordionHeader>) + - [func (f *GitHubFlavoredMarkdown) AccordionTerminator() (string, error)](<#GitHubFlavoredMarkdown.AccordionTerminator>) + - [func (f *GitHubFlavoredMarkdown) Anchor(anchor string) string](<#GitHubFlavoredMarkdown.Anchor>) + - [func (f *GitHubFlavoredMarkdown) AnchorHeader(level int, text, anchor string) (string, error)](<#GitHubFlavoredMarkdown.AnchorHeader>) + - [func (f *GitHubFlavoredMarkdown) Bold(text string) (string, error)](<#GitHubFlavoredMarkdown.Bold>) + - [func (f *GitHubFlavoredMarkdown) CodeBlock(language, code string) (string, error)](<#GitHubFlavoredMarkdown.CodeBlock>) + - [func (f *GitHubFlavoredMarkdown) CodeHref(loc lang.Location) (string, error)](<#GitHubFlavoredMarkdown.CodeHref>) + - [func (f *GitHubFlavoredMarkdown) Escape(text string) string](<#GitHubFlavoredMarkdown.Escape>) + - [func (f *GitHubFlavoredMarkdown) Header(level int, text string) (string, error)](<#GitHubFlavoredMarkdown.Header>) + - [func (f *GitHubFlavoredMarkdown) Link(text, href string) (string, error)](<#GitHubFlavoredMarkdown.Link>) + - [func (f *GitHubFlavoredMarkdown) ListEntry(depth int, text string) (string, error)](<#GitHubFlavoredMarkdown.ListEntry>) + - [func (f *GitHubFlavoredMarkdown) LocalHref(headerText string) (string, error)](<#GitHubFlavoredMarkdown.LocalHref>) + - [func (f *GitHubFlavoredMarkdown) RawAnchorHeader(level int, text, anchor string) (string, error)](<#GitHubFlavoredMarkdown.RawAnchorHeader>) + - [func (f *GitHubFlavoredMarkdown) RawHeader(level int, text string) (string, error)](<#GitHubFlavoredMarkdown.RawHeader>) + - [func (f *GitHubFlavoredMarkdown) RawLocalHref(anchor string) string](<#GitHubFlavoredMarkdown.RawLocalHref>) +- [type PlainMarkdown](<#PlainMarkdown>) + - [func (f *PlainMarkdown) Accordion(title, body string) (string, error)](<#PlainMarkdown.Accordion>) + - [func (f *PlainMarkdown) AccordionHeader(title string) (string, error)](<#PlainMarkdown.AccordionHeader>) + - [func (f *PlainMarkdown) AccordionTerminator() (string, error)](<#PlainMarkdown.AccordionTerminator>) + - [func (f *PlainMarkdown) Anchor(anchor string) string](<#PlainMarkdown.Anchor>) + - [func (f *PlainMarkdown) AnchorHeader(level int, text, anchor string) (string, error)](<#PlainMarkdown.AnchorHeader>) + - [func (f *PlainMarkdown) Bold(text string) (string, error)](<#PlainMarkdown.Bold>) + - [func (f *PlainMarkdown) CodeBlock(language, code string) (string, error)](<#PlainMarkdown.CodeBlock>) + - [func (f *PlainMarkdown) CodeHref(loc lang.Location) (string, error)](<#PlainMarkdown.CodeHref>) + - [func (f *PlainMarkdown) Escape(text string) string](<#PlainMarkdown.Escape>) + - [func (f *PlainMarkdown) Header(level int, text string) (string, error)](<#PlainMarkdown.Header>) + - [func (f *PlainMarkdown) Link(text, href string) (string, error)](<#PlainMarkdown.Link>) + - [func (f *PlainMarkdown) ListEntry(depth int, text string) (string, error)](<#PlainMarkdown.ListEntry>) + - [func (f *PlainMarkdown) LocalHref(headerText string) (string, error)](<#PlainMarkdown.LocalHref>) + - [func (f *PlainMarkdown) RawAnchorHeader(level int, text, anchor string) (string, error)](<#PlainMarkdown.RawAnchorHeader>) + - [func (f *PlainMarkdown) RawHeader(level int, text string) (string, error)](<#PlainMarkdown.RawHeader>) + - [func (f *PlainMarkdown) RawLocalHref(anchor string) string](<#PlainMarkdown.RawLocalHref>) + + + ## type [AzureDevOpsMarkdown]() -AzureDevOpsMarkdown provides a Format which is compatible with Azure DevOps's syntax and semantics. See the Azure DevOps documentation for more details about their markdown format: https://docs.microsoft.com/en-us/azure/devops/project/wiki/markdown-guidance?view=azure-devops +AzureDevOpsMarkdown provides a Format which is compatible with Azure DevOps's syntax and semantics. See the Azure DevOps documentation for more details about their markdown format: https://docs.microsoft.com/en-us/azure/devops/project/wiki/markdown-guidance?view=azure-devops[https://docs.microsoft.com/en-us/azure/devops/project/wiki/markdown-guidance?view=azure-devops]() ```go type AzureDevOpsMarkdown struct{} ``` -### func \(\*AzureDevOpsMarkdown\) [Accordion]() + +### func \(\*AzureDevOpsMarkdown\) [Accordion]() ```go func (f *AzureDevOpsMarkdown) Accordion(title, body string) (string, error) @@ -73,7 +84,8 @@ func (f *AzureDevOpsMarkdown) Accordion(title, body string) (string, error) Accordion generates a collapsible content. The accordion's visible title while collapsed is the provided title and the expanded content is the body. -### func \(\*AzureDevOpsMarkdown\) [AccordionHeader]() + +### func \(\*AzureDevOpsMarkdown\) [AccordionHeader]() ```go func (f *AzureDevOpsMarkdown) AccordionHeader(title string) (string, error) @@ -87,7 +99,8 @@ The AccordionHeader is expected to be used in conjunction with AccordionTerminat accordion := format.AccordionHeader("Accordion Title") + "Accordion Body" + format.AccordionTerminator() ``` -### func \(\*AzureDevOpsMarkdown\) [AccordionTerminator]() + +### func \(\*AzureDevOpsMarkdown\) [AccordionTerminator]() ```go func (f *AzureDevOpsMarkdown) AccordionTerminator() (string, error) @@ -95,6 +108,25 @@ func (f *AzureDevOpsMarkdown) AccordionTerminator() (string, error) AccordionTerminator generates the code necessary to terminate an accordion after the body. It is expected to be used in conjunction with AccordionHeader\(\). See AccordionHeader for a full description. + +### func \(\*AzureDevOpsMarkdown\) [Anchor]() + +```go +func (f *AzureDevOpsMarkdown) Anchor(anchor string) string +``` + +Anchor produces an anchor for the provided link. + + +### func \(\*AzureDevOpsMarkdown\) [AnchorHeader]() + +```go +func (f *AzureDevOpsMarkdown) AnchorHeader(level int, text, anchor string) (string, error) +``` + +AnchorHeader converts the provided text and custom anchor link into a header of the provided level. The level is expected to be at least 1. + + ### func \(\*AzureDevOpsMarkdown\) [Bold]() ```go @@ -103,6 +135,7 @@ func (f *AzureDevOpsMarkdown) Bold(text string) (string, error) Bold converts the provided text to bold + ### func \(\*AzureDevOpsMarkdown\) [CodeBlock]() ```go @@ -111,7 +144,8 @@ func (f *AzureDevOpsMarkdown) CodeBlock(language, code string) (string, error) CodeBlock wraps the provided code as a code block and tags it with the provided language \(or no language if the empty string is provided\). -### func \(\*AzureDevOpsMarkdown\) [CodeHref]() + +### func \(\*AzureDevOpsMarkdown\) [CodeHref]() ```go func (f *AzureDevOpsMarkdown) CodeHref(loc lang.Location) (string, error) @@ -119,7 +153,8 @@ func (f *AzureDevOpsMarkdown) CodeHref(loc lang.Location) (string, error) CodeHref generates an href to the provided code entry. -### func \(\*AzureDevOpsMarkdown\) [Escape]() + +### func \(\*AzureDevOpsMarkdown\) [Escape]() ```go func (f *AzureDevOpsMarkdown) Escape(text string) string @@ -127,7 +162,8 @@ func (f *AzureDevOpsMarkdown) Escape(text string) string Escape escapes special markdown characters from the provided text. -### func \(\*AzureDevOpsMarkdown\) [Header]() + +### func \(\*AzureDevOpsMarkdown\) [Header]() ```go func (f *AzureDevOpsMarkdown) Header(level int, text string) (string, error) @@ -135,7 +171,8 @@ func (f *AzureDevOpsMarkdown) Header(level int, text string) (string, error) Header converts the provided text into a header of the provided level. The level is expected to be at least 1. -### func \(\*AzureDevOpsMarkdown\) [Link]() + +### func \(\*AzureDevOpsMarkdown\) [Link]() ```go func (f *AzureDevOpsMarkdown) Link(text, href string) (string, error) @@ -143,7 +180,8 @@ func (f *AzureDevOpsMarkdown) Link(text, href string) (string, error) Link generates a link with the given text and href values. -### func \(\*AzureDevOpsMarkdown\) [ListEntry]() + +### func \(\*AzureDevOpsMarkdown\) [ListEntry]() ```go func (f *AzureDevOpsMarkdown) ListEntry(depth int, text string) (string, error) @@ -151,23 +189,26 @@ func (f *AzureDevOpsMarkdown) ListEntry(depth int, text string) (string, error) ListEntry generates an unordered list entry with the provided text at the provided zero\-indexed depth. A depth of 0 is considered the topmost level of list. -### func \(\*AzureDevOpsMarkdown\) [LocalHref]() + +### func \(\*AzureDevOpsMarkdown\) [LocalHref]() ```go func (f *AzureDevOpsMarkdown) LocalHref(headerText string) (string, error) ``` -LocalHref generates an href for navigating to a header with the given headerText located within the same document as the href itself. Link generation follows the guidelines here: https://docs.microsoft.com/en-us/azure/devops/project/wiki/markdown-guidance?view=azure-devops#anchor-links +LocalHref generates an href for navigating to a header with the given headerText located within the same document as the href itself. Link generation follows the guidelines here: https://docs.microsoft.com/en-us/azure/devops/project/wiki/markdown-guidance?view=azure-devops#anchor-links[https://docs.microsoft.com/en-us/azure/devops/project/wiki/markdown-guidance?view=azure-devops#anchor-links]() -### func \(\*AzureDevOpsMarkdown\) [Paragraph]() + +### func \(\*AzureDevOpsMarkdown\) [RawAnchorHeader]() ```go -func (f *AzureDevOpsMarkdown) Paragraph(text string) (string, error) +func (f *AzureDevOpsMarkdown) RawAnchorHeader(level int, text, anchor string) (string, error) ``` -Paragraph formats a paragraph with the provided text as the contents. +RawAnchorHeader converts the provided text and custom anchor link into a header of the provided level without escaping the header text. The level is expected to be at least 1. -### func \(\*AzureDevOpsMarkdown\) [RawHeader]() + +### func \(\*AzureDevOpsMarkdown\) [RawHeader]() ```go func (f *AzureDevOpsMarkdown) RawHeader(level int, text string) (string, error) @@ -175,7 +216,17 @@ func (f *AzureDevOpsMarkdown) RawHeader(level int, text string) (string, error) RawHeader converts the provided text into a header of the provided level without escaping the header text. The level is expected to be at least 1. -## type [Format]() + +### func \(\*AzureDevOpsMarkdown\) [RawLocalHref]() + +```go +func (f *AzureDevOpsMarkdown) RawLocalHref(anchor string) string +``` + +RawLocalHref generates an href within the same document but with a direct link provided instead of text to slugify. + + +## type [Format]() Format is a generic interface for formatting documentation contents in a particular way. @@ -188,10 +239,22 @@ type Format interface { // provided language (or no language if the empty string is provided). CodeBlock(language, code string) (string, error) + // Anchor produces an anchor for the provided link. + Anchor(anchor string) string + + // AnchorHeader converts the provided text and custom anchor link into a + // header of the provided level. The level is expected to be at least 1. + AnchorHeader(level int, text, anchor string) (string, error) + // Header converts the provided text into a header of the provided level. // The level is expected to be at least 1. Header(level int, text string) (string, error) + // RawAnchorHeader converts the provided text and custom anchor link into a + // header of the provided level without escaping the header text. The level + // is expected to be at least 1. + RawAnchorHeader(level int, text, anchor string) (string, error) + // RawHeader converts the provided text into a header of the provided level // without escaping the header text. The level is expected to be at least 1. RawHeader(level int, text string) (string, error) @@ -200,6 +263,10 @@ type Format interface { // headerText located within the same document as the href itself. LocalHref(headerText string) (string, error) + // RawLocalHref generates an href within the same document but with a direct + // link provided instead of text to slugify. + RawLocalHref(anchor string) string + // Link generates a link with the given text and href values. Link(text, href string) (string, error) @@ -232,23 +299,22 @@ type Format interface { // AccordionHeader(). See AccordionHeader for a full description. AccordionTerminator() (string, error) - // Paragraph formats a paragraph with the provided text as the contents. - Paragraph(text string) (string, error) - // Escape escapes special markdown characters from the provided text. Escape(text string) string } ``` + ## type [GitHubFlavoredMarkdown]() -GitHubFlavoredMarkdown provides a Format which is compatible with GitHub Flavored Markdown's syntax and semantics. See GitHub's documentation for more details about their markdown format: https://guides.github.com/features/mastering-markdown/ +GitHubFlavoredMarkdown provides a Format which is compatible with GitHub Flavored Markdown's syntax and semantics. See GitHub's documentation for more details about their markdown format: https://guides.github.com/features/mastering-markdown/[https://guides.github.com/features/mastering-markdown/]() ```go type GitHubFlavoredMarkdown struct{} ``` -### func \(\*GitHubFlavoredMarkdown\) [Accordion]() + +### func \(\*GitHubFlavoredMarkdown\) [Accordion]() ```go func (f *GitHubFlavoredMarkdown) Accordion(title, body string) (string, error) @@ -256,7 +322,8 @@ func (f *GitHubFlavoredMarkdown) Accordion(title, body string) (string, error) Accordion generates a collapsible content. The accordion's visible title while collapsed is the provided title and the expanded content is the body. -### func \(\*GitHubFlavoredMarkdown\) [AccordionHeader]() + +### func \(\*GitHubFlavoredMarkdown\) [AccordionHeader]() ```go func (f *GitHubFlavoredMarkdown) AccordionHeader(title string) (string, error) @@ -270,7 +337,8 @@ The AccordionHeader is expected to be used in conjunction with AccordionTerminat accordion := format.AccordionHeader("Accordion Title") + "Accordion Body" + format.AccordionTerminator() ``` -### func \(\*GitHubFlavoredMarkdown\) [AccordionTerminator]() + +### func \(\*GitHubFlavoredMarkdown\) [AccordionTerminator]() ```go func (f *GitHubFlavoredMarkdown) AccordionTerminator() (string, error) @@ -278,6 +346,25 @@ func (f *GitHubFlavoredMarkdown) AccordionTerminator() (string, error) AccordionTerminator generates the code necessary to terminate an accordion after the body. It is expected to be used in conjunction with AccordionHeader\(\). See AccordionHeader for a full description. + +### func \(\*GitHubFlavoredMarkdown\) [Anchor]() + +```go +func (f *GitHubFlavoredMarkdown) Anchor(anchor string) string +``` + +Anchor produces an anchor for the provided link. + + +### func \(\*GitHubFlavoredMarkdown\) [AnchorHeader]() + +```go +func (f *GitHubFlavoredMarkdown) AnchorHeader(level int, text, anchor string) (string, error) +``` + +AnchorHeader converts the provided text and custom anchor link into a header of the provided level. The level is expected to be at least 1. + + ### func \(\*GitHubFlavoredMarkdown\) [Bold]() ```go @@ -286,6 +373,7 @@ func (f *GitHubFlavoredMarkdown) Bold(text string) (string, error) Bold converts the provided text to bold + ### func \(\*GitHubFlavoredMarkdown\) [CodeBlock]() ```go @@ -294,7 +382,8 @@ func (f *GitHubFlavoredMarkdown) CodeBlock(language, code string) (string, error CodeBlock wraps the provided code as a code block and tags it with the provided language \(or no language if the empty string is provided\). -### func \(\*GitHubFlavoredMarkdown\) [CodeHref]() + +### func \(\*GitHubFlavoredMarkdown\) [CodeHref]() ```go func (f *GitHubFlavoredMarkdown) CodeHref(loc lang.Location) (string, error) @@ -302,7 +391,8 @@ func (f *GitHubFlavoredMarkdown) CodeHref(loc lang.Location) (string, error) CodeHref generates an href to the provided code entry. -### func \(\*GitHubFlavoredMarkdown\) [Escape]() + +### func \(\*GitHubFlavoredMarkdown\) [Escape]() ```go func (f *GitHubFlavoredMarkdown) Escape(text string) string @@ -310,7 +400,8 @@ func (f *GitHubFlavoredMarkdown) Escape(text string) string Escape escapes special markdown characters from the provided text. -### func \(\*GitHubFlavoredMarkdown\) [Header]() + +### func \(\*GitHubFlavoredMarkdown\) [Header]() ```go func (f *GitHubFlavoredMarkdown) Header(level int, text string) (string, error) @@ -318,7 +409,8 @@ func (f *GitHubFlavoredMarkdown) Header(level int, text string) (string, error) Header converts the provided text into a header of the provided level. The level is expected to be at least 1. -### func \(\*GitHubFlavoredMarkdown\) [Link]() + +### func \(\*GitHubFlavoredMarkdown\) [Link]() ```go func (f *GitHubFlavoredMarkdown) Link(text, href string) (string, error) @@ -326,7 +418,8 @@ func (f *GitHubFlavoredMarkdown) Link(text, href string) (string, error) Link generates a link with the given text and href values. -### func \(\*GitHubFlavoredMarkdown\) [ListEntry]() + +### func \(\*GitHubFlavoredMarkdown\) [ListEntry]() ```go func (f *GitHubFlavoredMarkdown) ListEntry(depth int, text string) (string, error) @@ -334,7 +427,8 @@ func (f *GitHubFlavoredMarkdown) ListEntry(depth int, text string) (string, erro ListEntry generates an unordered list entry with the provided text at the provided zero\-indexed depth. A depth of 0 is considered the topmost level of list. -### func \(\*GitHubFlavoredMarkdown\) [LocalHref]() + +### func \(\*GitHubFlavoredMarkdown\) [LocalHref]() ```go func (f *GitHubFlavoredMarkdown) LocalHref(headerText string) (string, error) @@ -342,15 +436,17 @@ func (f *GitHubFlavoredMarkdown) LocalHref(headerText string) (string, error) LocalHref generates an href for navigating to a header with the given headerText located within the same document as the href itself. -### func \(\*GitHubFlavoredMarkdown\) [Paragraph]() + +### func \(\*GitHubFlavoredMarkdown\) [RawAnchorHeader]() ```go -func (f *GitHubFlavoredMarkdown) Paragraph(text string) (string, error) +func (f *GitHubFlavoredMarkdown) RawAnchorHeader(level int, text, anchor string) (string, error) ``` -Paragraph formats a paragraph with the provided text as the contents. +RawAnchorHeader converts the provided text and custom anchor link into a header of the provided level without escaping the header text. The level is expected to be at least 1. -### func \(\*GitHubFlavoredMarkdown\) [RawHeader]() + +### func \(\*GitHubFlavoredMarkdown\) [RawHeader]() ```go func (f *GitHubFlavoredMarkdown) RawHeader(level int, text string) (string, error) @@ -358,6 +454,16 @@ func (f *GitHubFlavoredMarkdown) RawHeader(level int, text string) (string, erro RawHeader converts the provided text into a header of the provided level without escaping the header text. The level is expected to be at least 1. + +### func \(\*GitHubFlavoredMarkdown\) [RawLocalHref]() + +```go +func (f *GitHubFlavoredMarkdown) RawLocalHref(anchor string) string +``` + +RawLocalHref generates an href within the same document but with a direct link provided instead of text to slugify. + + ## type [PlainMarkdown]() PlainMarkdown provides a Format which is compatible with the base Markdown format specification. @@ -366,7 +472,8 @@ PlainMarkdown provides a Format which is compatible with the base Markdown forma type PlainMarkdown struct{} ``` -### func \(\*PlainMarkdown\) [Accordion]() + +### func \(\*PlainMarkdown\) [Accordion]() ```go func (f *PlainMarkdown) Accordion(title, body string) (string, error) @@ -374,7 +481,8 @@ func (f *PlainMarkdown) Accordion(title, body string) (string, error) Accordion generates a collapsible content. Since accordions are not supported by plain markdown, this generates a level 6 header followed by a paragraph. -### func \(\*PlainMarkdown\) [AccordionHeader]() + +### func \(\*PlainMarkdown\) [AccordionHeader]() ```go func (f *PlainMarkdown) AccordionHeader(title string) (string, error) @@ -388,7 +496,8 @@ The AccordionHeader is expected to be used in conjunction with AccordionTerminat accordion := format.AccordionHeader("Accordion Title") + "Accordion Body" + format.AccordionTerminator() ``` -### func \(\*PlainMarkdown\) [AccordionTerminator]() + +### func \(\*PlainMarkdown\) [AccordionTerminator]() ```go func (f *PlainMarkdown) AccordionTerminator() (string, error) @@ -396,6 +505,25 @@ func (f *PlainMarkdown) AccordionTerminator() (string, error) AccordionTerminator generates the code necessary to terminate an accordion after the body. Since accordions are not supported in plain markdown, this completes a paragraph section. It is expected to be used in conjunction with AccordionHeader\(\). See AccordionHeader for a full description. + +### func \(\*PlainMarkdown\) [Anchor]() + +```go +func (f *PlainMarkdown) Anchor(anchor string) string +``` + +Anchor produces an anchor for the provided link. + + +### func \(\*PlainMarkdown\) [AnchorHeader]() + +```go +func (f *PlainMarkdown) AnchorHeader(level int, text, anchor string) (string, error) +``` + +AnchorHeader converts the provided text and custom anchor link into a header of the provided level. The level is expected to be at least 1. + + ### func \(\*PlainMarkdown\) [Bold]() ```go @@ -404,6 +532,7 @@ func (f *PlainMarkdown) Bold(text string) (string, error) Bold converts the provided text to bold + ### func \(\*PlainMarkdown\) [CodeBlock]() ```go @@ -412,7 +541,8 @@ func (f *PlainMarkdown) CodeBlock(language, code string) (string, error) CodeBlock wraps the provided code as a code block. The provided language is ignored as it is not supported in plain markdown. -### func \(\*PlainMarkdown\) [CodeHref]() + +### func \(\*PlainMarkdown\) [CodeHref]() ```go func (f *PlainMarkdown) CodeHref(loc lang.Location) (string, error) @@ -420,7 +550,8 @@ func (f *PlainMarkdown) CodeHref(loc lang.Location) (string, error) CodeHref always returns the empty string, as there is no defined file linking format in standard markdown. -### func \(\*PlainMarkdown\) [Escape]() + +### func \(\*PlainMarkdown\) [Escape]() ```go func (f *PlainMarkdown) Escape(text string) string @@ -428,7 +559,8 @@ func (f *PlainMarkdown) Escape(text string) string Escape escapes special markdown characters from the provided text. -### func \(\*PlainMarkdown\) [Header]() + +### func \(\*PlainMarkdown\) [Header]() ```go func (f *PlainMarkdown) Header(level int, text string) (string, error) @@ -436,7 +568,8 @@ func (f *PlainMarkdown) Header(level int, text string) (string, error) Header converts the provided text into a header of the provided level. The level is expected to be at least 1. -### func \(\*PlainMarkdown\) [Link]() + +### func \(\*PlainMarkdown\) [Link]() ```go func (f *PlainMarkdown) Link(text, href string) (string, error) @@ -444,7 +577,8 @@ func (f *PlainMarkdown) Link(text, href string) (string, error) Link generates a link with the given text and href values. -### func \(\*PlainMarkdown\) [ListEntry]() + +### func \(\*PlainMarkdown\) [ListEntry]() ```go func (f *PlainMarkdown) ListEntry(depth int, text string) (string, error) @@ -452,7 +586,8 @@ func (f *PlainMarkdown) ListEntry(depth int, text string) (string, error) ListEntry generates an unordered list entry with the provided text at the provided zero\-indexed depth. A depth of 0 is considered the topmost level of list. -### func \(\*PlainMarkdown\) [LocalHref]() + +### func \(\*PlainMarkdown\) [LocalHref]() ```go func (f *PlainMarkdown) LocalHref(headerText string) (string, error) @@ -460,15 +595,17 @@ func (f *PlainMarkdown) LocalHref(headerText string) (string, error) LocalHref always returns the empty string, as header links are not supported in plain markdown. -### func \(\*PlainMarkdown\) [Paragraph]() + +### func \(\*PlainMarkdown\) [RawAnchorHeader]() ```go -func (f *PlainMarkdown) Paragraph(text string) (string, error) +func (f *PlainMarkdown) RawAnchorHeader(level int, text, anchor string) (string, error) ``` -Paragraph formats a paragraph with the provided text as the contents. +RawAnchorHeader converts the provided text and custom anchor link into a header of the provided level without escaping the header text. The level is expected to be at least 1. -### func \(\*PlainMarkdown\) [RawHeader]() + +### func \(\*PlainMarkdown\) [RawHeader]() ```go func (f *PlainMarkdown) RawHeader(level int, text string) (string, error) @@ -476,4 +613,13 @@ func (f *PlainMarkdown) RawHeader(level int, text string) (string, error) RawHeader converts the provided text into a header of the provided level without escaping the header text. The level is expected to be at least 1. + +### func \(\*PlainMarkdown\) [RawLocalHref]() + +```go +func (f *PlainMarkdown) RawLocalHref(anchor string) string +``` + +RawLocalHref generates an href within the same document but with a direct link provided instead of text to slugify. + Generated by [gomarkdoc]() diff --git a/format/devops.go b/format/devops.go index 38d2bf7..ccb1484 100644 --- a/format/devops.go +++ b/format/devops.go @@ -28,12 +28,30 @@ func (f *AzureDevOpsMarkdown) CodeBlock(language, code string) (string, error) { return formatcore.GFMCodeBlock(language, code), nil } +// Anchor produces an anchor for the provided link. +func (f *AzureDevOpsMarkdown) Anchor(anchor string) string { + return formatcore.Anchor(anchor) +} + +// AnchorHeader converts the provided text and custom anchor link into a header +// of the provided level. The level is expected to be at least 1. +func (f *AzureDevOpsMarkdown) AnchorHeader(level int, text, anchor string) (string, error) { + return formatcore.AnchorHeader(level, formatcore.Escape(text), anchor) +} + // Header converts the provided text into a header of the provided level. The // level is expected to be at least 1. func (f *AzureDevOpsMarkdown) Header(level int, text string) (string, error) { return formatcore.Header(level, formatcore.Escape(text)) } +// RawAnchorHeader converts the provided text and custom anchor link into a +// header of the provided level without escaping the header text. The level is +// expected to be at least 1. +func (f *AzureDevOpsMarkdown) RawAnchorHeader(level int, text, anchor string) (string, error) { + return formatcore.AnchorHeader(level, text, anchor) +} + // RawHeader converts the provided text into a header of the provided level // without escaping the header text. The level is expected to be at least 1. func (f *AzureDevOpsMarkdown) RawHeader(level int, text string) (string, error) { @@ -57,6 +75,12 @@ func (f *AzureDevOpsMarkdown) LocalHref(headerText string) (string, error) { return fmt.Sprintf("#%s", result), nil } +// RawLocalHref generates an href within the same document but with a direct +// link provided instead of text to slugify. +func (f *AzureDevOpsMarkdown) RawLocalHref(anchor string) string { + return fmt.Sprintf("#%s", anchor) +} + // CodeHref generates an href to the provided code entry. func (f *AzureDevOpsMarkdown) CodeHref(loc lang.Location) (string, error) { // If there's no repo, we can't compute an href @@ -131,11 +155,6 @@ func (f *AzureDevOpsMarkdown) AccordionTerminator() (string, error) { return formatcore.GFMAccordionTerminator(), nil } -// Paragraph formats a paragraph with the provided text as the contents. -func (f *AzureDevOpsMarkdown) Paragraph(text string) (string, error) { - return formatcore.Paragraph(text), nil -} - // Escape escapes special markdown characters from the provided text. func (f *AzureDevOpsMarkdown) Escape(text string) string { return formatcore.Escape(text) diff --git a/format/format.go b/format/format.go index cfd9f49..a24e7af 100644 --- a/format/format.go +++ b/format/format.go @@ -12,10 +12,22 @@ type Format interface { // provided language (or no language if the empty string is provided). CodeBlock(language, code string) (string, error) + // Anchor produces an anchor for the provided link. + Anchor(anchor string) string + + // AnchorHeader converts the provided text and custom anchor link into a + // header of the provided level. The level is expected to be at least 1. + AnchorHeader(level int, text, anchor string) (string, error) + // Header converts the provided text into a header of the provided level. // The level is expected to be at least 1. Header(level int, text string) (string, error) + // RawAnchorHeader converts the provided text and custom anchor link into a + // header of the provided level without escaping the header text. The level + // is expected to be at least 1. + RawAnchorHeader(level int, text, anchor string) (string, error) + // RawHeader converts the provided text into a header of the provided level // without escaping the header text. The level is expected to be at least 1. RawHeader(level int, text string) (string, error) @@ -24,6 +36,10 @@ type Format interface { // headerText located within the same document as the href itself. LocalHref(headerText string) (string, error) + // RawLocalHref generates an href within the same document but with a direct + // link provided instead of text to slugify. + RawLocalHref(anchor string) string + // Link generates a link with the given text and href values. Link(text, href string) (string, error) @@ -56,9 +72,6 @@ type Format interface { // AccordionHeader(). See AccordionHeader for a full description. AccordionTerminator() (string, error) - // Paragraph formats a paragraph with the provided text as the contents. - Paragraph(text string) (string, error) - // Escape escapes special markdown characters from the provided text. Escape(text string) string } diff --git a/format/formatcore/README.md b/format/formatcore/README.md index 6b387b5..eb8277b 100755 --- a/format/formatcore/README.md +++ b/format/formatcore/README.md @@ -10,21 +10,41 @@ Package formatcore provides utilities for creating formatters like those found i ## Index -- [func Bold(text string) string](<#func-bold>) -- [func CodeBlock(code string) string](<#func-codeblock>) -- [func Escape(text string) string](<#func-escape>) -- [func GFMAccordion(title, body string) string](<#func-gfmaccordion>) -- [func GFMAccordionHeader(title string) string](<#func-gfmaccordionheader>) -- [func GFMAccordionTerminator() string](<#func-gfmaccordionterminator>) -- [func GFMCodeBlock(language, code string) string](<#func-gfmcodeblock>) -- [func Header(level int, text string) (string, error)](<#func-header>) -- [func Link(text, href string) string](<#func-link>) -- [func ListEntry(depth int, text string) string](<#func-listentry>) -- [func Paragraph(text string) string](<#func-paragraph>) -- [func PlainText(text string) string](<#func-plaintext>) - - -## func [Bold]() +- [func Anchor(anchor string) string](<#Anchor>) +- [func AnchorHeader(level int, text, anchor string) (string, error)](<#AnchorHeader>) +- [func Bold(text string) string](<#Bold>) +- [func CodeBlock(code string) string](<#CodeBlock>) +- [func Escape(text string) string](<#Escape>) +- [func GFMAccordion(title, body string) string](<#GFMAccordion>) +- [func GFMAccordionHeader(title string) string](<#GFMAccordionHeader>) +- [func GFMAccordionTerminator() string](<#GFMAccordionTerminator>) +- [func GFMCodeBlock(language, code string) string](<#GFMCodeBlock>) +- [func Header(level int, text string) (string, error)](<#Header>) +- [func Link(text, href string) string](<#Link>) +- [func ListEntry(depth int, text string) string](<#ListEntry>) +- [func PlainText(text string) string](<#PlainText>) + + + +## func [Anchor]() + +```go +func Anchor(anchor string) string +``` + +Anchor produces an anchor for the provided link. + + +## func [AnchorHeader]() + +```go +func AnchorHeader(level int, text, anchor string) (string, error) +``` + +AnchorHeader converts the provided text and custom anchor link into a header of the provided level. The level is expected to be at least 1. + + +## func [Bold]() ```go func Bold(text string) string @@ -32,7 +52,8 @@ func Bold(text string) string Bold converts the provided text to bold -## func [CodeBlock]() + +## func [CodeBlock]() ```go func CodeBlock(code string) string @@ -40,7 +61,8 @@ func CodeBlock(code string) string CodeBlock wraps the provided code as a code block. Language syntax highlighting is not supported. -## func [Escape]() + +## func [Escape]() ```go func Escape(text string) string @@ -48,7 +70,8 @@ func Escape(text string) string Escape escapes the special characters in the provided text, but leaves URLs found intact. Note that the URLs included must begin with a scheme to skip the escaping. -## func [GFMAccordion]() + +## func [GFMAccordion]() ```go func GFMAccordion(title, body string) string @@ -56,7 +79,8 @@ func GFMAccordion(title, body string) string GFMAccordion generates a collapsible content. The accordion's visible title while collapsed is the provided title and the expanded content is the body. -## func [GFMAccordionHeader]() + +## func [GFMAccordionHeader]() ```go func GFMAccordionHeader(title string) string @@ -70,7 +94,8 @@ The GFMAccordionHeader is expected to be used in conjunction with GFMAccordionTe accordion := GFMAccordionHeader("Accordion Title") + "Accordion Body" + GFMAccordionTerminator() ``` -## func [GFMAccordionTerminator]() + +## func [GFMAccordionTerminator]() ```go func GFMAccordionTerminator() string @@ -78,7 +103,8 @@ func GFMAccordionTerminator() string GFMAccordionTerminator generates the code necessary to terminate an accordion after the body. It is expected to be used in conjunction with GFMAccordionHeader\(\). See GFMAccordionHeader for a full description. -## func [GFMCodeBlock]() + +## func [GFMCodeBlock]() ```go func GFMCodeBlock(language, code string) string @@ -86,7 +112,8 @@ func GFMCodeBlock(language, code string) string GFMCodeBlock wraps the provided code as a code block and tags it with the provided language \(or no language if the empty string is provided\), using the triple backtick format from GitHub Flavored Markdown. -## func [Header]() + +## func [Header]() ```go func Header(level int, text string) (string, error) @@ -94,7 +121,8 @@ func Header(level int, text string) (string, error) Header converts the provided text into a header of the provided level. The level is expected to be at least 1. -## func [Link]() + +## func [Link]() ```go func Link(text, href string) string @@ -102,7 +130,8 @@ func Link(text, href string) string Link generates a link with the given text and href values. -## func [ListEntry]() + +## func [ListEntry]() ```go func ListEntry(depth int, text string) string @@ -110,15 +139,8 @@ func ListEntry(depth int, text string) string ListEntry generates an unordered list entry with the provided text at the provided zero\-indexed depth. A depth of 0 is considered the topmost level of list. -## func [Paragraph]() - -```go -func Paragraph(text string) string -``` - -Paragraph formats a paragraph with the provided text as the contents - -## func [PlainText]() + +## func [PlainText]() ```go func PlainText(text string) string diff --git a/format/formatcore/base.go b/format/formatcore/base.go index 70be6f0..5772cd3 100644 --- a/format/formatcore/base.go +++ b/format/formatcore/base.go @@ -3,6 +3,7 @@ package formatcore import ( "errors" "fmt" + "html" "regexp" "strings" @@ -44,6 +45,25 @@ func GFMCodeBlock(language, code string) string { return fmt.Sprintf("```%s\n%s\n```", language, strings.TrimSpace(code)) } +// Anchor produces an anchor for the provided link. +func Anchor(anchor string) string { + return fmt.Sprintf( + "", + html.EscapeString(anchor), + ) +} + +// AnchorHeader converts the provided text and custom anchor link into a header +// of the provided level. The level is expected to be at least 1. +func AnchorHeader(level int, text, anchor string) (string, error) { + header, err := Header(level, text) + if err != nil { + return "", err + } + + return fmt.Sprintf("%s\n%s", Anchor(anchor), header), nil +} + // Header converts the provided text into a header of the provided level. The // level is expected to be at least 1. func Header(level int, text string) (string, error) { @@ -120,11 +140,6 @@ func GFMAccordionTerminator() string { return "

\n" } -// Paragraph formats a paragraph with the provided text as the contents -func Paragraph(text string) string { - return Escape(text) -} - var ( specialCharacterRegex = regexp.MustCompile("([\\\\`*_{}\\[\\]()<>#+\\-!~])") urlRegex = xurls.Strict() // Require a scheme in URLs diff --git a/format/github.go b/format/github.go index b5b5af7..c630d72 100644 --- a/format/github.go +++ b/format/github.go @@ -27,12 +27,30 @@ func (f *GitHubFlavoredMarkdown) CodeBlock(language, code string) (string, error return formatcore.GFMCodeBlock(language, code), nil } +// Anchor produces an anchor for the provided link. +func (f *GitHubFlavoredMarkdown) Anchor(anchor string) string { + return formatcore.Anchor(anchor) +} + +// AnchorHeader converts the provided text and custom anchor link into a header +// of the provided level. The level is expected to be at least 1. +func (f *GitHubFlavoredMarkdown) AnchorHeader(level int, text, anchor string) (string, error) { + return formatcore.AnchorHeader(level, formatcore.Escape(text), anchor) +} + // Header converts the provided text into a header of the provided level. The // level is expected to be at least 1. func (f *GitHubFlavoredMarkdown) Header(level int, text string) (string, error) { return formatcore.Header(level, formatcore.Escape(text)) } +// RawAnchorHeader converts the provided text and custom anchor link into a +// header of the provided level without escaping the header text. The level is +// expected to be at least 1. +func (f *GitHubFlavoredMarkdown) RawAnchorHeader(level int, text, anchor string) (string, error) { + return formatcore.AnchorHeader(level, text, anchor) +} + // RawHeader converts the provided text into a header of the provided level // without escaping the header text. The level is expected to be at least 1. func (f *GitHubFlavoredMarkdown) RawHeader(level int, text string) (string, error) { @@ -56,6 +74,12 @@ func (f *GitHubFlavoredMarkdown) LocalHref(headerText string) (string, error) { return fmt.Sprintf("#%s", result), nil } +// RawLocalHref generates an href within the same document but with a direct +// link provided instead of text to slugify. +func (f *GitHubFlavoredMarkdown) RawLocalHref(anchor string) string { + return fmt.Sprintf("#%s", anchor) +} + // Link generates a link with the given text and href values. func (f *GitHubFlavoredMarkdown) Link(text, href string) (string, error) { return formatcore.Link(text, href), nil @@ -134,11 +158,6 @@ func (f *GitHubFlavoredMarkdown) AccordionTerminator() (string, error) { return formatcore.GFMAccordionTerminator(), nil } -// Paragraph formats a paragraph with the provided text as the contents. -func (f *GitHubFlavoredMarkdown) Paragraph(text string) (string, error) { - return formatcore.Paragraph(text), nil -} - // Escape escapes special markdown characters from the provided text. func (f *GitHubFlavoredMarkdown) Escape(text string) string { return formatcore.Escape(text) diff --git a/format/plain.go b/format/plain.go index c886317..7062a21 100644 --- a/format/plain.go +++ b/format/plain.go @@ -22,12 +22,30 @@ func (f *PlainMarkdown) CodeBlock(language, code string) (string, error) { return formatcore.CodeBlock(code), nil } +// Anchor produces an anchor for the provided link. +func (f *PlainMarkdown) Anchor(anchor string) string { + return formatcore.Anchor(anchor) +} + +// AnchorHeader converts the provided text and custom anchor link into a header +// of the provided level. The level is expected to be at least 1. +func (f *PlainMarkdown) AnchorHeader(level int, text, anchor string) (string, error) { + return formatcore.AnchorHeader(level, formatcore.Escape(text), anchor) +} + // Header converts the provided text into a header of the provided level. The // level is expected to be at least 1. func (f *PlainMarkdown) Header(level int, text string) (string, error) { return formatcore.Header(level, formatcore.Escape(text)) } +// RawAnchorHeader converts the provided text and custom anchor link into a +// header of the provided level without escaping the header text. The level is +// expected to be at least 1. +func (f *PlainMarkdown) RawAnchorHeader(level int, text, anchor string) (string, error) { + return formatcore.AnchorHeader(level, text, anchor) +} + // RawHeader converts the provided text into a header of the provided level // without escaping the header text. The level is expected to be at least 1. func (f *PlainMarkdown) RawHeader(level int, text string) (string, error) { @@ -40,6 +58,12 @@ func (f *PlainMarkdown) LocalHref(headerText string) (string, error) { return "", nil } +// RawLocalHref generates an href within the same document but with a direct +// link provided instead of text to slugify. +func (f *PlainMarkdown) RawLocalHref(anchor string) string { + return fmt.Sprintf("#%s", anchor) +} + // CodeHref always returns the empty string, as there is no defined file linking // format in standard markdown. func (f *PlainMarkdown) CodeHref(loc lang.Location) (string, error) { @@ -66,7 +90,7 @@ func (f *PlainMarkdown) Accordion(title, body string) (string, error) { return "", err } - return fmt.Sprintf("%s%s", h, formatcore.Paragraph(body)), nil + return fmt.Sprintf("%s%s", h, body), nil } // AccordionHeader generates the header visible when an accordion is collapsed. @@ -90,11 +114,6 @@ func (f *PlainMarkdown) AccordionTerminator() (string, error) { return "\n\n", nil } -// Paragraph formats a paragraph with the provided text as the contents. -func (f *PlainMarkdown) Paragraph(text string) (string, error) { - return formatcore.Paragraph(text), nil -} - // Escape escapes special markdown characters from the provided text. func (f *PlainMarkdown) Escape(text string) string { return formatcore.Escape(text) diff --git a/lang/README.md b/lang/README.md index e564da7..d30ced5 100644 --- a/lang/README.md +++ b/lang/README.md @@ -10,107 +10,131 @@ Package lang provides constructs for defining golang language constructs and ext ## Index -- [type Block](<#type-block>) - - [func NewBlock(cfg *Config, kind BlockKind, text string, inline bool) *Block](<#func-newblock>) - - [func NewListBlock(cfg *Config, list *List, inline bool) *Block](<#func-newlistblock>) - - [func ParseBlocks(cfg *Config, blocks []comment.Block, inline bool) []*Block](<#func-parseblocks>) - - [func (b *Block) Inline() bool](<#func-block-inline>) - - [func (b *Block) Kind() BlockKind](<#func-block-kind>) - - [func (b *Block) Level() int](<#func-block-level>) - - [func (b *Block) List() *List](<#func-block-list>) - - [func (b *Block) Text() string](<#func-block-text>) -- [type BlockKind](<#type-blockkind>) -- [type Config](<#type-config>) - - [func NewConfig(log logger.Logger, workDir string, pkgDir string, opts ...ConfigOption) (*Config, error)](<#func-newconfig>) - - [func (c *Config) Inc(step int) *Config](<#func-config-inc>) -- [type ConfigOption](<#type-configoption>) - - [func ConfigWithRepoOverrides(overrides *Repo) ConfigOption](<#func-configwithrepooverrides>) -- [type Doc](<#type-doc>) - - [func NewDoc(cfg *Config, text string) *Doc](<#func-newdoc>) - - [func (d *Doc) Blocks() []*Block](<#func-doc-blocks>) - - [func (d *Doc) Level() int](<#func-doc-level>) -- [type Example](<#type-example>) - - [func NewExample(cfg *Config, name string, doc *doc.Example) *Example](<#func-newexample>) - - [func (ex *Example) Code() (string, error)](<#func-example-code>) - - [func (ex *Example) Doc() *Doc](<#func-example-doc>) - - [func (ex *Example) HasOutput() bool](<#func-example-hasoutput>) - - [func (ex *Example) Level() int](<#func-example-level>) - - [func (ex *Example) Location() Location](<#func-example-location>) - - [func (ex *Example) Name() string](<#func-example-name>) - - [func (ex *Example) Output() string](<#func-example-output>) - - [func (ex *Example) Summary() string](<#func-example-summary>) - - [func (ex *Example) Title() string](<#func-example-title>) -- [type File](<#type-file>) - - [func NewFile(header, footer string, packages []*Package) *File](<#func-newfile>) -- [type Func](<#type-func>) - - [func NewFunc(cfg *Config, doc *doc.Func, examples []*doc.Example) *Func](<#func-newfunc>) - - [func (fn *Func) Doc() *Doc](<#func-func-doc>) - - [func (fn *Func) Examples() (examples []*Example)](<#func-func-examples>) - - [func (fn *Func) Level() int](<#func-func-level>) - - [func (fn *Func) Location() Location](<#func-func-location>) - - [func (fn *Func) Name() string](<#func-func-name>) - - [func (fn *Func) Receiver() string](<#func-func-receiver>) - - [func (fn *Func) Signature() (string, error)](<#func-func-signature>) - - [func (fn *Func) Summary() string](<#func-func-summary>) - - [func (fn *Func) Title() string](<#func-func-title>) -- [type Item](<#type-item>) - - [func NewItem(cfg *Config, docItem *comment.ListItem) *Item](<#func-newitem>) - - [func (i *Item) Blocks() []*Block](<#func-item-blocks>) - - [func (i *Item) Kind() ItemKind](<#func-item-kind>) - - [func (i *Item) Number() int](<#func-item-number>) -- [type ItemKind](<#type-itemkind>) -- [type List](<#type-list>) - - [func NewList(cfg *Config, docList *comment.List) *List](<#func-newlist>) - - [func (l *List) BlankBetween() bool](<#func-list-blankbetween>) - - [func (l *List) Items() []*Item](<#func-list-items>) -- [type Location](<#type-location>) - - [func NewLocation(cfg *Config, node ast.Node) Location](<#func-newlocation>) -- [type Package](<#type-package>) - - [func NewPackage(cfg *Config, doc *doc.Package, examples []*doc.Example) *Package](<#func-newpackage>) - - [func NewPackageFromBuild(log logger.Logger, pkg *build.Package, opts ...PackageOption) (*Package, error)](<#func-newpackagefrombuild>) - - [func (pkg *Package) Consts() (consts []*Value)](<#func-package-consts>) - - [func (pkg *Package) Dir() string](<#func-package-dir>) - - [func (pkg *Package) Dirname() string](<#func-package-dirname>) - - [func (pkg *Package) Doc() *Doc](<#func-package-doc>) - - [func (pkg *Package) Examples() (examples []*Example)](<#func-package-examples>) - - [func (pkg *Package) Funcs() (funcs []*Func)](<#func-package-funcs>) - - [func (pkg *Package) Import() string](<#func-package-import>) - - [func (pkg *Package) ImportPath() string](<#func-package-importpath>) - - [func (pkg *Package) Level() int](<#func-package-level>) - - [func (pkg *Package) Name() string](<#func-package-name>) - - [func (pkg *Package) Summary() string](<#func-package-summary>) - - [func (pkg *Package) Types() (types []*Type)](<#func-package-types>) - - [func (pkg *Package) Vars() (vars []*Value)](<#func-package-vars>) -- [type PackageOption](<#type-packageoption>) - - [func PackageWithRepositoryOverrides(repo *Repo) PackageOption](<#func-packagewithrepositoryoverrides>) - - [func PackageWithUnexportedIncluded() PackageOption](<#func-packagewithunexportedincluded>) -- [type PackageOptions](<#type-packageoptions>) -- [type Position](<#type-position>) -- [type Repo](<#type-repo>) -- [type Type](<#type-type>) - - [func NewType(cfg *Config, doc *doc.Type, examples []*doc.Example) *Type](<#func-newtype>) - - [func (typ *Type) Consts() []*Value](<#func-type-consts>) - - [func (typ *Type) Decl() (string, error)](<#func-type-decl>) - - [func (typ *Type) Doc() *Doc](<#func-type-doc>) - - [func (typ *Type) Examples() (examples []*Example)](<#func-type-examples>) - - [func (typ *Type) Funcs() []*Func](<#func-type-funcs>) - - [func (typ *Type) Level() int](<#func-type-level>) - - [func (typ *Type) Location() Location](<#func-type-location>) - - [func (typ *Type) Methods() []*Func](<#func-type-methods>) - - [func (typ *Type) Name() string](<#func-type-name>) - - [func (typ *Type) Summary() string](<#func-type-summary>) - - [func (typ *Type) Title() string](<#func-type-title>) - - [func (typ *Type) Vars() []*Value](<#func-type-vars>) -- [type Value](<#type-value>) - - [func NewValue(cfg *Config, doc *doc.Value) *Value](<#func-newvalue>) - - [func (v *Value) Decl() (string, error)](<#func-value-decl>) - - [func (v *Value) Doc() *Doc](<#func-value-doc>) - - [func (v *Value) Level() int](<#func-value-level>) - - [func (v *Value) Location() Location](<#func-value-location>) - - [func (v *Value) Summary() string](<#func-value-summary>) - - -## type [Block]() +- [func PackageSymbols(pkg *doc.Package) map[string]Symbol](<#PackageSymbols>) +- [type Block](<#Block>) + - [func NewBlock(cfg *Config, kind BlockKind, spans []*Span, inline bool) *Block](<#NewBlock>) + - [func NewListBlock(cfg *Config, list *List, inline bool) *Block](<#NewListBlock>) + - [func ParseBlocks(cfg *Config, blocks []comment.Block, inline bool) []*Block](<#ParseBlocks>) + - [func (b *Block) Inline() bool](<#Block.Inline>) + - [func (b *Block) Kind() BlockKind](<#Block.Kind>) + - [func (b *Block) Level() int](<#Block.Level>) + - [func (b *Block) List() *List](<#Block.List>) + - [func (b *Block) Spans() []*Span](<#Block.Spans>) +- [type BlockKind](<#BlockKind>) +- [type Config](<#Config>) + - [func NewConfig(log logger.Logger, workDir string, pkgDir string, opts ...ConfigOption) (*Config, error)](<#NewConfig>) + - [func (c *Config) Inc(step int) *Config](<#Config.Inc>) +- [type ConfigOption](<#ConfigOption>) + - [func ConfigWithRepoOverrides(overrides *Repo) ConfigOption](<#ConfigWithRepoOverrides>) +- [type Doc](<#Doc>) + - [func NewDoc(cfg *Config, text string) *Doc](<#NewDoc>) + - [func (d *Doc) Blocks() []*Block](<#Doc.Blocks>) + - [func (d *Doc) Level() int](<#Doc.Level>) +- [type Example](<#Example>) + - [func NewExample(cfg *Config, name string, doc *doc.Example) *Example](<#NewExample>) + - [func (ex *Example) Code() (string, error)](<#Example.Code>) + - [func (ex *Example) Doc() *Doc](<#Example.Doc>) + - [func (ex *Example) HasOutput() bool](<#Example.HasOutput>) + - [func (ex *Example) Level() int](<#Example.Level>) + - [func (ex *Example) Location() Location](<#Example.Location>) + - [func (ex *Example) Name() string](<#Example.Name>) + - [func (ex *Example) Output() string](<#Example.Output>) + - [func (ex *Example) Summary() string](<#Example.Summary>) + - [func (ex *Example) Title() string](<#Example.Title>) +- [type File](<#File>) + - [func NewFile(header, footer string, packages []*Package) *File](<#NewFile>) +- [type Func](<#Func>) + - [func NewFunc(cfg *Config, doc *doc.Func, examples []*doc.Example) *Func](<#NewFunc>) + - [func (fn *Func) Anchor() string](<#Func.Anchor>) + - [func (fn *Func) Doc() *Doc](<#Func.Doc>) + - [func (fn *Func) Examples() (examples []*Example)](<#Func.Examples>) + - [func (fn *Func) Level() int](<#Func.Level>) + - [func (fn *Func) Location() Location](<#Func.Location>) + - [func (fn *Func) Name() string](<#Func.Name>) + - [func (fn *Func) Receiver() string](<#Func.Receiver>) + - [func (fn *Func) Signature() (string, error)](<#Func.Signature>) + - [func (fn *Func) Summary() string](<#Func.Summary>) + - [func (fn *Func) Title() string](<#Func.Title>) +- [type Item](<#Item>) + - [func NewItem(cfg *Config, docItem *comment.ListItem) *Item](<#NewItem>) + - [func (i *Item) Blocks() []*Block](<#Item.Blocks>) + - [func (i *Item) Kind() ItemKind](<#Item.Kind>) + - [func (i *Item) Number() int](<#Item.Number>) +- [type ItemKind](<#ItemKind>) +- [type List](<#List>) + - [func NewList(cfg *Config, docList *comment.List) *List](<#NewList>) + - [func (l *List) BlankBetween() bool](<#List.BlankBetween>) + - [func (l *List) Items() []*Item](<#List.Items>) +- [type Location](<#Location>) + - [func NewLocation(cfg *Config, node ast.Node) Location](<#NewLocation>) +- [type Package](<#Package>) + - [func NewPackage(cfg *Config, examples []*doc.Example) *Package](<#NewPackage>) + - [func NewPackageFromBuild(log logger.Logger, pkg *build.Package, opts ...PackageOption) (*Package, error)](<#NewPackageFromBuild>) + - [func (pkg *Package) Consts() (consts []*Value)](<#Package.Consts>) + - [func (pkg *Package) Dir() string](<#Package.Dir>) + - [func (pkg *Package) Dirname() string](<#Package.Dirname>) + - [func (pkg *Package) Doc() *Doc](<#Package.Doc>) + - [func (pkg *Package) Examples() (examples []*Example)](<#Package.Examples>) + - [func (pkg *Package) Funcs() (funcs []*Func)](<#Package.Funcs>) + - [func (pkg *Package) Import() string](<#Package.Import>) + - [func (pkg *Package) ImportPath() string](<#Package.ImportPath>) + - [func (pkg *Package) Level() int](<#Package.Level>) + - [func (pkg *Package) Name() string](<#Package.Name>) + - [func (pkg *Package) Summary() string](<#Package.Summary>) + - [func (pkg *Package) Types() (types []*Type)](<#Package.Types>) + - [func (pkg *Package) Vars() (vars []*Value)](<#Package.Vars>) +- [type PackageOption](<#PackageOption>) + - [func PackageWithRepositoryOverrides(repo *Repo) PackageOption](<#PackageWithRepositoryOverrides>) + - [func PackageWithUnexportedIncluded() PackageOption](<#PackageWithUnexportedIncluded>) +- [type PackageOptions](<#PackageOptions>) +- [type Position](<#Position>) +- [type Repo](<#Repo>) +- [type Span](<#Span>) + - [func NewSpan(cfg *Config, kind SpanKind, text string, url string) *Span](<#NewSpan>) + - [func ParseSpans(cfg *Config, texts []comment.Text) []*Span](<#ParseSpans>) + - [func (s *Span) Kind() SpanKind](<#Span.Kind>) + - [func (s *Span) Text() string](<#Span.Text>) + - [func (s *Span) URL() string](<#Span.URL>) +- [type SpanKind](<#SpanKind>) +- [type Symbol](<#Symbol>) + - [func (s Symbol) Anchor() string](<#Symbol.Anchor>) +- [type SymbolKind](<#SymbolKind>) +- [type Type](<#Type>) + - [func NewType(cfg *Config, doc *doc.Type, examples []*doc.Example) *Type](<#NewType>) + - [func (typ *Type) Anchor() string](<#Type.Anchor>) + - [func (typ *Type) Consts() []*Value](<#Type.Consts>) + - [func (typ *Type) Decl() (string, error)](<#Type.Decl>) + - [func (typ *Type) Doc() *Doc](<#Type.Doc>) + - [func (typ *Type) Examples() (examples []*Example)](<#Type.Examples>) + - [func (typ *Type) Funcs() []*Func](<#Type.Funcs>) + - [func (typ *Type) Level() int](<#Type.Level>) + - [func (typ *Type) Location() Location](<#Type.Location>) + - [func (typ *Type) Methods() []*Func](<#Type.Methods>) + - [func (typ *Type) Name() string](<#Type.Name>) + - [func (typ *Type) Summary() string](<#Type.Summary>) + - [func (typ *Type) Title() string](<#Type.Title>) + - [func (typ *Type) Vars() []*Value](<#Type.Vars>) +- [type Value](<#Value>) + - [func NewValue(cfg *Config, doc *doc.Value) *Value](<#NewValue>) + - [func (v *Value) Anchor() string](<#Value.Anchor>) + - [func (v *Value) Decl() (string, error)](<#Value.Decl>) + - [func (v *Value) Doc() *Doc](<#Value.Doc>) + - [func (v *Value) Level() int](<#Value.Level>) + - [func (v *Value) Location() Location](<#Value.Location>) + - [func (v *Value) Summary() string](<#Value.Summary>) + + + +## func [PackageSymbols]() + +```go +func PackageSymbols(pkg *doc.Package) map[string]Symbol +``` + +PackageSymbols gets the list of symbols for a doc package. + + +## type [Block]() Block defines a single block element \(e.g. paragraph, code block\) in the documentation for a symbol or package. @@ -120,15 +144,17 @@ type Block struct { } ``` -### func [NewBlock]() + +### func [NewBlock]() ```go -func NewBlock(cfg *Config, kind BlockKind, text string, inline bool) *Block +func NewBlock(cfg *Config, kind BlockKind, spans []*Span, inline bool) *Block ``` -NewBlock creates a new block element of the provided kind and with the given text contents and a flag indicating whether this block is part of an inline element. +NewBlock creates a new block element of the provided kind and with the given text spans and a flag indicating whether this block is part of an inline element. -### func [NewListBlock]() + +### func [NewListBlock]() ```go func NewListBlock(cfg *Config, list *List, inline bool) *Block @@ -136,6 +162,7 @@ func NewListBlock(cfg *Config, list *List, inline bool) *Block NewListBlock creates a new list block element and with the given list definition and a flag indicating whether this block is part of an inline element. + ### func [ParseBlocks]() ```go @@ -144,6 +171,7 @@ func ParseBlocks(cfg *Config, blocks []comment.Block, inline bool) []*Block ParseBlocks produces a set of blocks from the corresponding comment blocks. It also takes a flag indicating whether the blocks are part of an inline element such as a list item. + ### func \(\*Block\) [Inline]() ```go @@ -152,7 +180,8 @@ func (b *Block) Inline() bool Inline indicates whether the block is part of an inline element, such as a list item. -### func \(\*Block\) [Kind]() + +### func \(\*Block\) [Kind]() ```go func (b *Block) Kind() BlockKind @@ -160,7 +189,8 @@ func (b *Block) Kind() BlockKind Kind provides the kind of data that this block's text should be interpreted as. -### func \(\*Block\) [Level]() + +### func \(\*Block\) [Level]() ```go func (b *Block) Level() int @@ -168,6 +198,7 @@ func (b *Block) Level() int Level provides the default level that a block of kind HeaderBlock will render at in the output. The level is not used for other block types. + ### func \(\*Block\) [List]() ```go @@ -176,15 +207,17 @@ func (b *Block) List() *List List provides the list contents for a list block. Only relevant for blocks of type ListBlock. -### func \(\*Block\) [Text]() + +### func \(\*Block\) [Spans]() ```go -func (b *Block) Text() string +func (b *Block) Spans() []*Span ``` -Text provides the raw text of the block's contents. The text is pre\-scrubbed and sanitized as determined by the block's Kind\(\), but it is not wrapped in any special constructs for rendering purposes \(such as markdown code blocks\). +Spans provides the raw text of the block's contents as a set of text spans. The text is pre\-scrubbed and sanitized as determined by the block's Kind\(\), but it is not wrapped in any special constructs for rendering purposes \(such as markdown code blocks\). -## type [BlockKind]() + +## type [BlockKind]() BlockKind identifies the type of block element represented by the corresponding Block. @@ -192,7 +225,7 @@ BlockKind identifies the type of block element represented by the corresponding type BlockKind string ``` - + ```go const ( @@ -210,22 +243,27 @@ const ( ) ``` -## type [Config]() + +## type [Config]() Config defines contextual information used to resolve documentation for a construct. ```go type Config struct { FileSet *token.FileSet + Files []*ast.File Level int Repo *Repo PkgDir string WorkDir string + Symbols map[string]Symbol + Pkg *doc.Package Log logger.Logger } ``` -### func [NewConfig]() + +### func [NewConfig]() ```go func NewConfig(log logger.Logger, workDir string, pkgDir string, opts ...ConfigOption) (*Config, error) @@ -233,7 +271,8 @@ func NewConfig(log logger.Logger, workDir string, pkgDir string, opts ...ConfigO NewConfig generates a Config for the provided package directory. It will resolve the filepath and attempt to determine the repository containing the directory. If no repository is found, the Repo field will be set to nil. An error is returned if the provided directory is invalid. -### func \(\*Config\) [Inc]() + +### func \(\*Config\) [Inc]() ```go func (c *Config) Inc(step int) *Config @@ -241,7 +280,8 @@ func (c *Config) Inc(step int) *Config Inc copies the Config and increments the level by the provided step. -## type [ConfigOption]() + +## type [ConfigOption]() ConfigOption modifies the Config generated by NewConfig. @@ -249,7 +289,8 @@ ConfigOption modifies the Config generated by NewConfig. type ConfigOption func(c *Config) error ``` -### func [ConfigWithRepoOverrides]() + +### func [ConfigWithRepoOverrides]() ```go func ConfigWithRepoOverrides(overrides *Repo) ConfigOption @@ -257,7 +298,8 @@ func ConfigWithRepoOverrides(overrides *Repo) ConfigOption ConfigWithRepoOverrides defines a set of manual overrides for the repository information to be used in place of automatic repository detection. -## type [Doc]() + +## type [Doc]() Doc provides access to the documentation comment contents for a package or symbol in a structured form. @@ -267,7 +309,8 @@ type Doc struct { } ``` -### func [NewDoc]() + +### func [NewDoc]() ```go func NewDoc(cfg *Config, text string) *Doc @@ -275,7 +318,8 @@ func NewDoc(cfg *Config, text string) *Doc NewDoc initializes a Doc struct from the provided raw documentation text and with headers rendered by default at the heading level provided. Documentation is separated into block level elements using the standard rules from golang's documentation conventions. -### func \(\*Doc\) [Blocks]() + +### func \(\*Doc\) [Blocks]() ```go func (d *Doc) Blocks() []*Block @@ -283,7 +327,8 @@ func (d *Doc) Blocks() []*Block Blocks holds the list of block elements that makes up the documentation contents. -### func \(\*Doc\) [Level]() + +### func \(\*Doc\) [Level]() ```go func (d *Doc) Level() int @@ -291,6 +336,7 @@ func (d *Doc) Level() int Level provides the default level that headers within the documentation should be rendered + ## type [Example]() Example holds a single documentation example for a package or symbol. @@ -301,6 +347,7 @@ type Example struct { } ``` + ### func [NewExample]() ```go @@ -309,6 +356,7 @@ func NewExample(cfg *Config, name string, doc *doc.Example) *Example NewExample creates a new example from the example function's name, its documentation example and the files holding code related to the example. + ### func \(\*Example\) [Code]() ```go @@ -317,6 +365,7 @@ func (ex *Example) Code() (string, error) Code provides the raw text code representation of the example's contents. + ### func \(\*Example\) [Doc]() ```go @@ -325,6 +374,7 @@ func (ex *Example) Doc() *Doc Doc provides the structured contents of the documentation comment for the example. + ### func \(\*Example\) [HasOutput]() ```go @@ -333,6 +383,7 @@ func (ex *Example) HasOutput() bool HasOutput indicates whether the example contains any example output. + ### func \(\*Example\) [Level]() ```go @@ -341,6 +392,7 @@ func (ex *Example) Level() int Level provides the default level that headers for the example should be rendered. + ### func \(\*Example\) [Location]() ```go @@ -349,6 +401,7 @@ func (ex *Example) Location() Location Location returns a representation of the node's location in a file within a repository. + ### func \(\*Example\) [Name]() ```go @@ -357,6 +410,7 @@ func (ex *Example) Name() string Name provides a pretty\-printed name for the specific example, if one was provided. + ### func \(\*Example\) [Output]() ```go @@ -365,6 +419,7 @@ func (ex *Example) Output() string Output provides the code's example output. + ### func \(\*Example\) [Summary]() ```go @@ -373,6 +428,7 @@ func (ex *Example) Summary() string Summary provides the one\-sentence summary of the example's documentation comment. + ### func \(\*Example\) [Title]() ```go @@ -381,6 +437,7 @@ func (ex *Example) Title() string Title provides a formatted string to print as the title of the example. It incorporates the example's name, if present. + ## type [File]() File holds information for rendering a single file that contains one or more packages. @@ -393,6 +450,7 @@ type File struct { } ``` + ### func [NewFile]() ```go @@ -401,6 +459,7 @@ func NewFile(header, footer string, packages []*Package) *File NewFile creates a new instance of File with the provided information. + ## type [Func]() Func holds documentation information for a single func declaration within a package or type. @@ -411,6 +470,7 @@ type Func struct { } ``` + ### func [NewFunc]() ```go @@ -419,6 +479,16 @@ func NewFunc(cfg *Config, doc *doc.Func, examples []*doc.Example) *Func NewFunc creates a new Func from the corresponding documentation construct from the standard library, the related token.FileSet for the package and the list of examples for the package. + +### func \(\*Func\) [Anchor]() + +```go +func (fn *Func) Anchor() string +``` + +Anchor produces anchor text for the func. + + ### func \(\*Func\) [Doc]() ```go @@ -427,6 +497,7 @@ func (fn *Func) Doc() *Doc Doc provides the structured contents of the documentation comment for the function. + ### func \(\*Func\) [Examples]() ```go @@ -435,6 +506,7 @@ func (fn *Func) Examples() (examples []*Example) Examples provides the list of examples from the list given on initialization that pertain to the function. + ### func \(\*Func\) [Level]() ```go @@ -443,6 +515,7 @@ func (fn *Func) Level() int Level provides the default level at which headers for the func should be rendered in the final documentation. + ### func \(\*Func\) [Location]() ```go @@ -451,6 +524,7 @@ func (fn *Func) Location() Location Location returns a representation of the node's location in a file within a repository. + ### func \(\*Func\) [Name]() ```go @@ -459,6 +533,7 @@ func (fn *Func) Name() string Name provides the name of the function. + ### func \(\*Func\) [Receiver]() ```go @@ -467,6 +542,7 @@ func (fn *Func) Receiver() string Receiver provides the type of the receiver for the function, or empty string if there is no receiver type. + ### func \(\*Func\) [Signature]() ```go @@ -475,6 +551,7 @@ func (fn *Func) Signature() (string, error) Signature provides the raw text representation of the code for the function's signature. + ### func \(\*Func\) [Summary]() ```go @@ -483,6 +560,7 @@ func (fn *Func) Summary() string Summary provides the one\-sentence summary of the function's documentation comment + ### func \(\*Func\) [Title]() ```go @@ -491,6 +569,7 @@ func (fn *Func) Title() string Title provides the formatted name of the func. It is primarily designed for generating headers. + ## type [Item]() Item defines a single item in a list in the documentation for a symbol or package. @@ -501,6 +580,7 @@ type Item struct { } ``` + ### func [NewItem]() ```go @@ -509,6 +589,7 @@ func NewItem(cfg *Config, docItem *comment.ListItem) *Item NewItem initializes a list item from the equivalent type from the comment package. + ### func \(\*Item\) [Blocks]() ```go @@ -517,6 +598,7 @@ func (i *Item) Blocks() []*Block Blocks returns the blocks of documentation in a list item. + ### func \(\*Item\) [Kind]() ```go @@ -525,6 +607,7 @@ func (i *Item) Kind() ItemKind Kind returns the kind of the list item. + ### func \(\*Item\) [Number]() ```go @@ -533,6 +616,7 @@ func (i *Item) Number() int Number returns the number of the list item. Only populated if the item is of the OrderedItem kind. + ## type [ItemKind]() ItemKind identifies the kind of item @@ -541,7 +625,7 @@ ItemKind identifies the kind of item type ItemKind string ``` - + ```go const ( @@ -553,6 +637,7 @@ const ( ) ``` + ## type [List]() List defines a list block element in the documentation for a symbol or package. @@ -563,6 +648,7 @@ type List struct { } ``` + ### func [NewList]() ```go @@ -571,6 +657,7 @@ func NewList(cfg *Config, docList *comment.List) *List NewList initializes a list from the equivalent type from the comment package. + ### func \(\*List\) [BlankBetween]() ```go @@ -579,6 +666,7 @@ func (l *List) BlankBetween() bool BlankBetween returns true if there should be a blank line between list items. + ### func \(\*List\) [Items]() ```go @@ -587,7 +675,8 @@ func (l *List) Items() []*Item Items returns the slice of items in the list. -## type [Location]() + +## type [Location]() Location holds information for identifying a position within a file and repository, if present. @@ -601,7 +690,8 @@ type Location struct { } ``` -### func [NewLocation]() + +### func [NewLocation]() ```go func NewLocation(cfg *Config, node ast.Node) Location @@ -609,6 +699,7 @@ func NewLocation(cfg *Config, node ast.Node) Location NewLocation returns a location for the provided Config and ast.Node combination. This is typically not called directly, but is made available via the Location\(\) methods of various lang constructs. + ## type [Package]() Package holds documentation information for a package and all of the symbols contained within it. @@ -619,14 +710,16 @@ type Package struct { } ``` + ### func [NewPackage]() ```go -func NewPackage(cfg *Config, doc *doc.Package, examples []*doc.Example) *Package +func NewPackage(cfg *Config, examples []*doc.Example) *Package ``` NewPackage creates a representation of a package's documentation from the raw documentation constructs provided by the standard library. This is only recommended for advanced scenarios. Most consumers will find it easier to use NewPackageFromBuild instead. + ### func [NewPackageFromBuild]() ```go @@ -635,7 +728,8 @@ func NewPackageFromBuild(log logger.Logger, pkg *build.Package, opts ...PackageO NewPackageFromBuild creates a representation of a package's documentation from the build metadata for that package. It can be configured using the provided options. -### func \(\*Package\) [Consts]() + +### func \(\*Package\) [Consts]() ```go func (pkg *Package) Consts() (consts []*Value) @@ -643,7 +737,8 @@ func (pkg *Package) Consts() (consts []*Value) Consts lists the top\-level constants provided by the package. -### func \(\*Package\) [Dir]() + +### func \(\*Package\) [Dir]() ```go func (pkg *Package) Dir() string @@ -651,7 +746,8 @@ func (pkg *Package) Dir() string Dir provides the name of the full directory in which the package is located. -### func \(\*Package\) [Dirname]() + +### func \(\*Package\) [Dirname]() ```go func (pkg *Package) Dirname() string @@ -659,7 +755,8 @@ func (pkg *Package) Dirname() string Dirname provides the name of the leaf directory in which the package is located. -### func \(\*Package\) [Doc]() + +### func \(\*Package\) [Doc]() ```go func (pkg *Package) Doc() *Doc @@ -667,7 +764,8 @@ func (pkg *Package) Doc() *Doc Doc provides the structured contents of the documentation comment for the package. -### func \(\*Package\) [Examples]() + +### func \(\*Package\) [Examples]() ```go func (pkg *Package) Examples() (examples []*Example) @@ -675,7 +773,8 @@ func (pkg *Package) Examples() (examples []*Example) Examples provides the package\-level examples that have been defined. This does not include examples that are associated with symbols contained within the package. -### func \(\*Package\) [Funcs]() + +### func \(\*Package\) [Funcs]() ```go func (pkg *Package) Funcs() (funcs []*Func) @@ -683,7 +782,8 @@ func (pkg *Package) Funcs() (funcs []*Func) Funcs lists the top\-level functions provided by the package. -### func \(\*Package\) [Import]() + +### func \(\*Package\) [Import]() ```go func (pkg *Package) Import() string @@ -691,7 +791,8 @@ func (pkg *Package) Import() string Import provides the raw text for the import declaration that is used to import code from the package. If your package's documentation is generated from a local path and does not use Go Modules, this will typically print \`import "."\`. -### func \(\*Package\) [ImportPath]() + +### func \(\*Package\) [ImportPath]() ```go func (pkg *Package) ImportPath() string @@ -699,7 +800,8 @@ func (pkg *Package) ImportPath() string ImportPath provides the identifier used for the package when installing or importing the package. If your package's documentation is generated from a local path and does not use Go Modules, this will typically print \`.\`. -### func \(\*Package\) [Level]() + +### func \(\*Package\) [Level]() ```go func (pkg *Package) Level() int @@ -707,7 +809,8 @@ func (pkg *Package) Level() int Level provides the default level that headers for the package's root documentation should be rendered. -### func \(\*Package\) [Name]() + +### func \(\*Package\) [Name]() ```go func (pkg *Package) Name() string @@ -715,7 +818,8 @@ func (pkg *Package) Name() string Name provides the name of the package as it would be seen from another package importing it. -### func \(\*Package\) [Summary]() + +### func \(\*Package\) [Summary]() ```go func (pkg *Package) Summary() string @@ -723,7 +827,8 @@ func (pkg *Package) Summary() string Summary provides the one\-sentence summary of the package's documentation comment. -### func \(\*Package\) [Types]() + +### func \(\*Package\) [Types]() ```go func (pkg *Package) Types() (types []*Type) @@ -731,7 +836,8 @@ func (pkg *Package) Types() (types []*Type) Types lists the top\-level types provided by the package. -### func \(\*Package\) [Vars]() + +### func \(\*Package\) [Vars]() ```go func (pkg *Package) Vars() (vars []*Value) @@ -739,6 +845,7 @@ func (pkg *Package) Vars() (vars []*Value) Vars lists the top\-level variables provided by the package. + ## type [PackageOption]() PackageOption configures one or more options for the package. @@ -747,7 +854,8 @@ PackageOption configures one or more options for the package. type PackageOption func(opts *PackageOptions) error ``` -### func [PackageWithRepositoryOverrides]() + +### func [PackageWithRepositoryOverrides]() ```go func PackageWithRepositoryOverrides(repo *Repo) PackageOption @@ -755,7 +863,8 @@ func PackageWithRepositoryOverrides(repo *Repo) PackageOption PackageWithRepositoryOverrides can be used along with the NewPackageFromBuild function to define manual overrides to the automatic repository detection logic. -### func [PackageWithUnexportedIncluded]() + +### func [PackageWithUnexportedIncluded]() ```go func PackageWithUnexportedIncluded() PackageOption @@ -763,6 +872,7 @@ func PackageWithUnexportedIncluded() PackageOption PackageWithUnexportedIncluded can be used along with the NewPackageFromBuild function to specify that all symbols, including unexported ones, should be included in the documentation for the package. + ## type [PackageOptions]() PackageOptions holds options related to the configuration of the package and its documentation on creation. @@ -773,7 +883,8 @@ type PackageOptions struct { } ``` -## type [Position]() + +## type [Position]() Position represents a line and column number within a file. @@ -784,7 +895,8 @@ type Position struct { } ``` -## type [Repo]() + +## type [Repo]() Repo represents information about a repository relevant to documentation generation. @@ -796,6 +908,140 @@ type Repo struct { } ``` + +## type [Span]() + +Span defines a single text span in a block for documentation of a symbol or package. + +```go +type Span struct { + // contains filtered or unexported fields +} +``` + + +### func [NewSpan]() + +```go +func NewSpan(cfg *Config, kind SpanKind, text string, url string) *Span +``` + +NewSpan creates a new span. + + +### func [ParseSpans]() + +```go +func ParseSpans(cfg *Config, texts []comment.Text) []*Span +``` + +ParseSpans turns a set of \*comment.Text entries into a slice of spans. + + +### func \(\*Span\) [Kind]() + +```go +func (s *Span) Kind() SpanKind +``` + +Kind provides the kind of data that this span represents. + + +### func \(\*Span\) [Text]() + +```go +func (s *Span) Text() string +``` + +Text provides the raw text for the span. + + +### func \(\*Span\) [URL]() + +```go +func (s *Span) URL() string +``` + +URL provides the url associated with the span, if any. + + +## type [SpanKind]() + +SpanKind identifies the type of span element represented by the corresponding Span. + +```go +type SpanKind string +``` + + + +```go +const ( + // TextSpan defines a span that represents plain text. + TextSpan SpanKind = "text" + + // RawTextSpan defines a span that represents plain text that should be + // displayed as-is. + RawTextSpan SpanKind = "rawText" + + // LinkSpan defines a span that represents a link. + LinkSpan SpanKind = "link" + + // AutolinkSpan defines a span that represents text which is itself a link. + AutolinkSpan SpanKind = "autolink" +) +``` + + +## type [Symbol]() + +Symbol provides identity information for a symbol in a package. + +```go +type Symbol struct { + // Receiver holds the receiver for a method or field. + Receiver string + // Name holds the name of the symbol itself. + Name string + // Kind identifies the category of the symbol. + Kind SymbolKind + // Parent holds the linkable parent symbol which contains this one. + Parent *Symbol +} +``` + + +### func \(Symbol\) [Anchor]() + +```go +func (s Symbol) Anchor() string +``` + +Anchor produces anchor text for the symbol. + + +## type [SymbolKind]() + +SymbolKind identifies the type of symbol. + +```go +type SymbolKind int +``` + +The list of valid symbol kinds. + +```go +const ( + TypeSymbolKind SymbolKind = iota + 1 + FuncSymbolKind + ConstSymbolKind + VarSymbolKind + MethodSymbolKind + FieldSymbolKind +) +``` + + ## type [Type]() Type holds documentation information for a type declaration. @@ -806,6 +1052,7 @@ type Type struct { } ``` + ### func [NewType]() ```go @@ -814,6 +1061,16 @@ func NewType(cfg *Config, doc *doc.Type, examples []*doc.Example) *Type NewType creates a Type from the raw documentation representation of the type, the token.FileSet for the package's files and the full list of examples from the containing package. + +### func \(\*Type\) [Anchor]() + +```go +func (typ *Type) Anchor() string +``` + +Anchor produces anchor text for the type. + + ### func \(\*Type\) [Consts]() ```go @@ -822,6 +1079,7 @@ func (typ *Type) Consts() []*Value Consts lists the const declaration blocks containing values of this type. + ### func \(\*Type\) [Decl]() ```go @@ -830,6 +1088,7 @@ func (typ *Type) Decl() (string, error) Decl provides the raw text representation of the code for the type's declaration. + ### func \(\*Type\) [Doc]() ```go @@ -838,6 +1097,7 @@ func (typ *Type) Doc() *Doc Doc provides the structured contents of the documentation comment for the type. + ### func \(\*Type\) [Examples]() ```go @@ -846,6 +1106,7 @@ func (typ *Type) Examples() (examples []*Example) Examples lists the examples pertaining to the type from the set provided on initialization. + ### func \(\*Type\) [Funcs]() ```go @@ -854,6 +1115,7 @@ func (typ *Type) Funcs() []*Func Funcs lists the funcs related to the type. This only includes functions which return an instance of the type or its pointer. + ### func \(\*Type\) [Level]() ```go @@ -862,6 +1124,7 @@ func (typ *Type) Level() int Level provides the default level that headers for the type should be rendered. + ### func \(\*Type\) [Location]() ```go @@ -870,6 +1133,7 @@ func (typ *Type) Location() Location Location returns a representation of the node's location in a file within a repository. + ### func \(\*Type\) [Methods]() ```go @@ -878,6 +1142,7 @@ func (typ *Type) Methods() []*Func Methods lists the funcs that use the type as a value or pointer receiver. + ### func \(\*Type\) [Name]() ```go @@ -886,6 +1151,7 @@ func (typ *Type) Name() string Name provides the name of the type + ### func \(\*Type\) [Summary]() ```go @@ -894,6 +1160,7 @@ func (typ *Type) Summary() string Summary provides the one\-sentence summary of the type's documentation comment. + ### func \(\*Type\) [Title]() ```go @@ -902,6 +1169,7 @@ func (typ *Type) Title() string Title provides a formatted name suitable for use in a header identifying the type. + ### func \(\*Type\) [Vars]() ```go @@ -910,6 +1178,7 @@ func (typ *Type) Vars() []*Value Vars lists the var declaration blocks containing values of this type. + ## type [Value]() Value holds documentation for a var or const declaration within a package. @@ -920,6 +1189,7 @@ type Value struct { } ``` + ### func [NewValue]() ```go @@ -928,6 +1198,16 @@ func NewValue(cfg *Config, doc *doc.Value) *Value NewValue creates a new Value from the raw const or var documentation and the token.FileSet of files for the containing package. + +### func \(\*Value\) [Anchor]() + +```go +func (v *Value) Anchor() string +``` + +Anchor produces anchor text for the value. + + ### func \(\*Value\) [Decl]() ```go @@ -936,6 +1216,7 @@ func (v *Value) Decl() (string, error) Decl provides the raw text representation of the code for declaring the const or var. + ### func \(\*Value\) [Doc]() ```go @@ -944,6 +1225,7 @@ func (v *Value) Doc() *Doc Doc provides the structured contents of the documentation comment for the example. + ### func \(\*Value\) [Level]() ```go @@ -952,6 +1234,7 @@ func (v *Value) Level() int Level provides the default level that headers for the value should be rendered. + ### func \(\*Value\) [Location]() ```go @@ -960,6 +1243,7 @@ func (v *Value) Location() Location Location returns a representation of the node's location in a file within a repository. + ### func \(\*Value\) [Summary]() ```go diff --git a/lang/block.go b/lang/block.go index c256d48..4ce4c73 100644 --- a/lang/block.go +++ b/lang/block.go @@ -2,7 +2,6 @@ package lang import ( "go/doc/comment" - "regexp" "strings" ) @@ -12,7 +11,7 @@ type ( Block struct { cfg *Config kind BlockKind - text string + spans []*Span list *List inline bool } @@ -37,17 +36,17 @@ const ( ) // NewBlock creates a new block element of the provided kind and with the given -// text contents and a flag indicating whether this block is part of an inline +// text spans and a flag indicating whether this block is part of an inline // element. -func NewBlock(cfg *Config, kind BlockKind, text string, inline bool) *Block { - return &Block{cfg, kind, text, nil, inline} +func NewBlock(cfg *Config, kind BlockKind, spans []*Span, inline bool) *Block { + return &Block{cfg, kind, spans, nil, inline} } // NewListBlock creates a new list block element and with the given list // definition and a flag indicating whether this block is part of an inline // element. func NewListBlock(cfg *Config, list *List, inline bool) *Block { - return &Block{cfg, ListBlock, "", list, inline} + return &Block{cfg, ListBlock, nil, list, inline} } // Level provides the default level that a block of kind HeaderBlock will render @@ -62,11 +61,12 @@ func (b *Block) Kind() BlockKind { return b.kind } -// Text provides the raw text of the block's contents. The text is pre-scrubbed -// and sanitized as determined by the block's Kind(), but it is not wrapped in -// any special constructs for rendering purposes (such as markdown code blocks). -func (b *Block) Text() string { - return b.text +// Spans provides the raw text of the block's contents as a set of text spans. +// The text is pre-scrubbed and sanitized as determined by the block's Kind(), +// but it is not wrapped in any special constructs for rendering purposes (such +// as markdown code blocks). +func (b *Block) Spans() []*Span { + return b.spans } // List provides the list contents for a list block. Only relevant for blocks of @@ -89,46 +89,23 @@ func ParseBlocks(cfg *Config, blocks []comment.Block, inline bool) []*Block { for i, b := range blocks { switch v := b.(type) { case *comment.Code: - res[i] = NewBlock(cfg.Inc(0), CodeBlock, v.Text, inline) + res[i] = NewBlock( + cfg.Inc(0), + CodeBlock, + []*Span{NewSpan(cfg.Inc(0), RawTextSpan, v.Text, "")}, + inline, + ) case *comment.Heading: var b strings.Builder printText(&b, v.Text...) - res[i] = NewBlock(cfg.Inc(0), HeaderBlock, b.String(), inline) + res[i] = NewBlock(cfg.Inc(0), HeaderBlock, ParseSpans(cfg, v.Text), inline) case *comment.List: list := NewList(cfg.Inc(0), v) res[i] = NewListBlock(cfg.Inc(0), list, inline) case *comment.Paragraph: - var b strings.Builder - printText(&b, v.Text...) - text := collapseWhitespace(b.String()) - res[i] = NewBlock(cfg.Inc(0), ParagraphBlock, text, inline) + res[i] = NewBlock(cfg.Inc(0), ParagraphBlock, ParseSpans(cfg, v.Text), inline) } } return res } - -func printText(b *strings.Builder, text ...comment.Text) { - for i, t := range text { - if i > 0 { - b.WriteRune(' ') - } - - switch v := t.(type) { - case comment.Plain: - b.WriteString(string(v)) - case comment.Italic: - b.WriteString(string(v)) - case *comment.DocLink: - printText(b, v.Text...) - case *comment.Link: - printText(b, v.Text...) - } - } -} - -var whitespaceRegex = regexp.MustCompile(`\s+`) - -func collapseWhitespace(s string) string { - return string(whitespaceRegex.ReplaceAll([]byte(s), []byte(" "))) -} diff --git a/lang/config.go b/lang/config.go index 173ea7c..d2ec6ce 100644 --- a/lang/config.go +++ b/lang/config.go @@ -4,8 +4,13 @@ import ( "errors" "fmt" "go/ast" + "go/doc" + "go/parser" "go/token" "io" + "io/ioutil" + "os" + "path" "path/filepath" "regexp" "strings" @@ -19,10 +24,13 @@ type ( // a construct. Config struct { FileSet *token.FileSet + Files []*ast.File Level int Repo *Repo PkgDir string WorkDir string + Symbols map[string]Symbol + Pkg *doc.Package Log logger.Logger } @@ -83,6 +91,13 @@ func NewConfig(log logger.Logger, workDir string, pkgDir string, opts ...ConfigO return nil, err } + files, err := parsePkgFiles(pkgDir, cfg.FileSet) + if err != nil { + return nil, err + } + + cfg.Files = files + if cfg.Repo == nil || cfg.Repo.Remote == "" || cfg.Repo.DefaultBranch == "" || cfg.Repo.PathFromRoot == "" { repo, err := getRepoForDir(log, cfg.WorkDir, cfg.PkgDir, cfg.Repo) if err != nil { @@ -109,10 +124,13 @@ func NewConfig(log logger.Logger, workDir string, pkgDir string, opts ...ConfigO func (c *Config) Inc(step int) *Config { return &Config{ FileSet: c.FileSet, + Files: c.Files, Level: c.Level + step, PkgDir: c.PkgDir, WorkDir: c.WorkDir, Repo: c.Repo, + Symbols: c.Symbols, + Pkg: c.Pkg, Log: c.Log, } } @@ -352,3 +370,33 @@ func NewLocation(cfg *Config, node ast.Node) Location { Repo: cfg.Repo, } } + +func parsePkgFiles(pkgDir string, fs *token.FileSet) ([]*ast.File, error) { + rawFiles, err := ioutil.ReadDir(pkgDir) + if err != nil { + return nil, fmt.Errorf("gomarkdoc: error reading package dir: %w", err) + } + + var files []*ast.File + for _, f := range rawFiles { + if !strings.HasSuffix(f.Name(), ".go") && !strings.HasSuffix(f.Name(), ".cgo") { + continue + } + + p := path.Join(pkgDir, f.Name()) + + fi, err := os.Stat(p) + if err != nil || !fi.Mode().IsRegular() { + continue + } + + parsed, err := parser.ParseFile(fs, p, nil, parser.ParseComments) + if err != nil { + return nil, fmt.Errorf("gomarkdoc: failed to parse package file %s", f.Name()) + } + + files = append(files, parsed) + } + + return files, nil +} diff --git a/lang/doc.go b/lang/doc.go index ca27470..c27e13f 100644 --- a/lang/doc.go +++ b/lang/doc.go @@ -1,9 +1,5 @@ package lang -import ( - "go/doc/comment" -) - // Doc provides access to the documentation comment contents for a package or // symbol in a structured form. type Doc struct { @@ -19,8 +15,7 @@ func NewDoc(cfg *Config, text string) *Doc { // Replace CRLF with LF rawText := normalizeDoc(text) - var p comment.Parser - parsed := p.Parse(rawText) + parsed := cfg.Pkg.Parser().Parse(rawText) blocks := ParseBlocks(cfg, parsed.Content, false) diff --git a/lang/func.go b/lang/func.go index 0a7c372..ea6f5b7 100644 --- a/lang/func.go +++ b/lang/func.go @@ -103,6 +103,22 @@ func (fn *Func) Examples() (examples []*Example) { return } +// Anchor produces anchor text for the func. +func (fn *Func) Anchor() string { + if fn.doc.Recv != "" { + return Symbol{ + Kind: MethodSymbolKind, + Receiver: fn.doc.Recv, + Name: fn.doc.Name, + }.Anchor() + } + + return Symbol{ + Kind: FuncSymbolKind, + Name: fn.doc.Name, + }.Anchor() +} + func (fn *Func) rawRecv() string { // remove type parameters recv := strings.Split(fn.doc.Recv, "[")[0] diff --git a/lang/package.go b/lang/package.go index acc4a60..4a79dd5 100644 --- a/lang/package.go +++ b/lang/package.go @@ -41,8 +41,8 @@ type ( // raw documentation constructs provided by the standard library. This is only // recommended for advanced scenarios. Most consumers will find it easier to use // NewPackageFromBuild instead. -func NewPackage(cfg *Config, doc *doc.Package, examples []*doc.Example) *Package { - return &Package{cfg, doc, examples} +func NewPackage(cfg *Config, examples []*doc.Example) *Package { + return &Package{cfg, cfg.Pkg, examples} } // NewPackageFromBuild creates a representation of a package's documentation @@ -66,19 +66,17 @@ func NewPackageFromBuild(log logger.Logger, pkg *build.Package, opts ...PackageO return nil, err } - docPkg, err := getDocPkg(pkg, cfg.FileSet, options.includeUnexported) + cfg.Pkg, err = getDocPkg(pkg, cfg.FileSet, options.includeUnexported) if err != nil { return nil, err } - files, err := parsePkgFiles(pkg, cfg.FileSet) - if err != nil { - return nil, err - } + sym := PackageSymbols(cfg.Pkg) + cfg.Symbols = sym - examples := doc.Examples(files...) + examples := doc.Examples(cfg.Files...) - return NewPackage(cfg, docPkg, examples), nil + return NewPackage(cfg, examples), nil } // PackageWithUnexportedIncluded can be used along with the NewPackageFromBuild @@ -330,33 +328,3 @@ func getDocPkg(pkg *build.Package, fs *token.FileSet, includeUnexported bool) (* return doc.New(astPkg, importPath, doc.AllDecls), nil } - -func parsePkgFiles(pkg *build.Package, fs *token.FileSet) ([]*ast.File, error) { - rawFiles, err := ioutil.ReadDir(pkg.Dir) - if err != nil { - return nil, fmt.Errorf("gomarkdoc: error reading package dir: %w", err) - } - - var files []*ast.File - for _, f := range rawFiles { - if !strings.HasSuffix(f.Name(), ".go") && !strings.HasSuffix(f.Name(), ".cgo") { - continue - } - - p := path.Join(pkg.Dir, f.Name()) - - fi, err := os.Stat(p) - if err != nil || !fi.Mode().IsRegular() { - continue - } - - parsed, err := parser.ParseFile(fs, p, nil, parser.ParseComments) - if err != nil { - return nil, fmt.Errorf("gomarkdoc: failed to parse package file %s", f.Name()) - } - - files = append(files, parsed) - } - - return files, nil -} diff --git a/lang/span.go b/lang/span.go new file mode 100644 index 0000000..db39d81 --- /dev/null +++ b/lang/span.go @@ -0,0 +1,137 @@ +package lang + +import ( + "fmt" + "go/doc/comment" + "regexp" + "strings" +) + +type ( + // Span defines a single text span in a block for documentation of a symbol + // or package. + Span struct { + cfg *Config + kind SpanKind + text string + url string + } + + // SpanKind identifies the type of span element represented by the + // corresponding Span. + SpanKind string +) + +const ( + // TextSpan defines a span that represents plain text. + TextSpan SpanKind = "text" + + // RawTextSpan defines a span that represents plain text that should be + // displayed as-is. + RawTextSpan SpanKind = "rawText" + + // LinkSpan defines a span that represents a link. + LinkSpan SpanKind = "link" + + // AutolinkSpan defines a span that represents text which is itself a link. + AutolinkSpan SpanKind = "autolink" +) + +// NewSpan creates a new span. +func NewSpan(cfg *Config, kind SpanKind, text string, url string) *Span { + return &Span{cfg, kind, text, url} +} + +// Kind provides the kind of data that this span represents. +func (s *Span) Kind() SpanKind { + return s.kind +} + +// Text provides the raw text for the span. +func (s *Span) Text() string { + return s.text +} + +// URL provides the url associated with the span, if any. +func (s *Span) URL() string { + return s.url +} + +// ParseSpans turns a set of *comment.Text entries into a slice of spans. +func ParseSpans(cfg *Config, texts []comment.Text) []*Span { + var s []*Span + for _, t := range texts { + switch v := t.(type) { + case comment.Plain: + s = append(s, NewSpan(cfg.Inc(0), TextSpan, collapseWhitespace(string(v)), "")) + case comment.Italic: + s = append(s, NewSpan(cfg.Inc(0), TextSpan, collapseWhitespace(string(v)), "")) + case *comment.DocLink: + var b strings.Builder + printText(&b, v.Text...) + str := collapseWhitespace(b.String()) + + // Replace local links as needed + if v.ImportPath == "" { + name := symbolName(v.Recv, v.Name) + if sym, ok := cfg.Symbols[name]; ok { + s = append(s, NewSpan(cfg.Inc(0), LinkSpan, str, fmt.Sprintf("#%s", sym.Anchor()))) + } else { + cfg.Log.Warnf("Unable to find symbol %s", name) + s = append(s, NewSpan(cfg.Inc(0), TextSpan, collapseWhitespace(str), "")) + } + break + } + + s = append(s, NewSpan(cfg.Inc(0), LinkSpan, str, v.DefaultURL("https://pkg.go.dev/"))) + case *comment.Link: + var b strings.Builder + printText(&b, v.Text...) + str := collapseWhitespace(b.String()) + + if v.Auto { + s = append(s, NewSpan(cfg.Inc(0), AutolinkSpan, str, str)) + } + + s = append(s, NewSpan(cfg.Inc(0), LinkSpan, str, v.URL)) + } + } + + return s +} + +func printText(b *strings.Builder, text ...comment.Text) { + for i, t := range text { + if i > 0 { + b.WriteRune(' ') + } + + switch v := t.(type) { + case comment.Plain: + b.WriteString(string(v)) + case comment.Italic: + b.WriteString(string(v)) + case *comment.DocLink: + printText(b, v.Text...) + case *comment.Link: + // No need to linkify implicit links + if v.Auto { + printText(b, v.Text...) + continue + } + + b.WriteRune('[') + printText(b, v.Text...) + b.WriteRune(']') + b.WriteRune('(') + b.WriteString(v.URL) + b.WriteRune(')') + } + } +} + +var whitespaceRegex = regexp.MustCompile(`\s+`) + +func collapseWhitespace(s string) string { + return string(whitespaceRegex.ReplaceAll([]byte(s), []byte(" "))) +} diff --git a/lang/symbol.go b/lang/symbol.go new file mode 100644 index 0000000..bfe7c6c --- /dev/null +++ b/lang/symbol.go @@ -0,0 +1,181 @@ +package lang + +import ( + "fmt" + "go/ast" + "go/doc" + "strings" +) + +type ( + // Symbol provides identity information for a symbol in a package. + Symbol struct { + // Receiver holds the receiver for a method or field. + Receiver string + // Name holds the name of the symbol itself. + Name string + // Kind identifies the category of the symbol. + Kind SymbolKind + // Parent holds the linkable parent symbol which contains this one. + Parent *Symbol + } + + // SymbolKind identifies the type of symbol. + SymbolKind int +) + +// The list of valid symbol kinds. +const ( + TypeSymbolKind SymbolKind = iota + 1 + FuncSymbolKind + ConstSymbolKind + VarSymbolKind + MethodSymbolKind + FieldSymbolKind +) + +// PackageSymbols gets the list of symbols for a doc package. +func PackageSymbols(pkg *doc.Package) map[string]Symbol { + sym := make(map[string]Symbol) + for _, c := range pkg.Consts { + parent := Symbol{ + Name: c.Names[0], + Kind: ConstSymbolKind, + } + + for _, n := range c.Names { + sym[symbolName("", n)] = Symbol{ + Name: n, + Kind: ConstSymbolKind, + Parent: &parent, + } + } + } + + for _, v := range pkg.Vars { + parent := Symbol{ + Name: v.Names[0], + Kind: VarSymbolKind, + } + + for _, n := range v.Names { + sym[symbolName("", n)] = Symbol{ + Name: n, + Kind: VarSymbolKind, + Parent: &parent, + } + } + } + + for _, v := range pkg.Funcs { + sym[symbolName("", v.Name)] = Symbol{ + Name: v.Name, + Kind: FuncSymbolKind, + } + } + + for _, t := range pkg.Types { + typeSymbols(sym, t) + } + + return sym +} + +func typeSymbols(sym map[string]Symbol, t *doc.Type) { + typeSym := Symbol{ + Name: t.Name, + Kind: TypeSymbolKind, + } + + sym[t.Name] = typeSym + + for _, f := range t.Methods { + sym[symbolName(t.Name, f.Name)] = Symbol{ + Receiver: t.Name, + Name: f.Name, + Kind: MethodSymbolKind, + } + } + + for _, s := range t.Decl.Specs { + typ, ok := s.(*ast.TypeSpec).Type.(*ast.StructType) + if !ok { + continue + } + + for _, f := range typ.Fields.List { + for _, n := range f.Names { + sym[symbolName(t.Name, n.String())] = Symbol{ + Receiver: t.Name, + Name: n.String(), + Kind: FieldSymbolKind, + Parent: &typeSym, + } + } + } + } + + for _, f := range t.Funcs { + sym[symbolName("", f.Name)] = Symbol{ + Name: f.Name, + Kind: FuncSymbolKind, + } + } + + for _, c := range t.Consts { + parent := Symbol{ + Name: c.Names[0], + Kind: ConstSymbolKind, + } + + for _, n := range c.Names { + sym[symbolName("", n)] = Symbol{ + Name: n, + Kind: ConstSymbolKind, + Parent: &parent, + } + } + } + + for _, v := range t.Vars { + parent := Symbol{ + Name: v.Names[0], + Kind: VarSymbolKind, + } + + for _, n := range v.Names { + sym[symbolName("", n)] = Symbol{ + Name: n, + Kind: VarSymbolKind, + Parent: &parent, + } + } + } + +} + +// Anchor produces anchor text for the symbol. +func (s Symbol) Anchor() string { + if s.Parent != nil { + return s.Parent.Anchor() + } + + switch s.Kind { + case MethodSymbolKind, FieldSymbolKind: + return fmt.Sprintf("%s.%s", strings.TrimLeft(s.Receiver, "*"), s.Name) + default: + return s.Name + } +} + +// symbolName returns the string representation of the symbol. +func symbolName(receiver string, name string) string { + receiver = strings.TrimLeft(receiver, "*") + name = strings.TrimLeft(name, "*") + + if receiver == "" { + return name + } + + return fmt.Sprintf("%s.%s", receiver, name) +} diff --git a/lang/type.go b/lang/type.go index c0a8a8c..2415278 100644 --- a/lang/type.go +++ b/lang/type.go @@ -135,3 +135,11 @@ func (typ *Type) Vars() []*Value { return vars } + +// Anchor produces anchor text for the type. +func (typ *Type) Anchor() string { + return Symbol{ + Kind: TypeSymbolKind, + Name: typ.doc.Name, + }.Anchor() +} diff --git a/lang/value.go b/lang/value.go index 9c4e3dd..d22451c 100644 --- a/lang/value.go +++ b/lang/value.go @@ -45,3 +45,18 @@ func (v *Value) Doc() *Doc { func (v *Value) Decl() (string, error) { return printNode(v.doc.Decl, v.cfg.FileSet) } + +// Anchor produces anchor text for the value. +func (v *Value) Anchor() string { + var kind SymbolKind + if v.doc.Decl.Tok.String() == "const" { + kind = ConstSymbolKind + } else { + kind = VarSymbolKind + } + + return Symbol{ + Kind: kind, + Name: v.doc.Names[0], + }.Anchor() +} diff --git a/renderer.go b/renderer.go index 9ed21af..4f82bf7 100644 --- a/renderer.go +++ b/renderer.go @@ -97,7 +97,10 @@ func NewRenderer(opts ...RendererOption) (*Renderer, error) { }, "bold": renderer.format.Bold, + "anchor": renderer.format.Anchor, + "anchorHeader": renderer.format.AnchorHeader, "header": renderer.format.Header, + "rawAnchorHeader": renderer.format.RawAnchorHeader, "rawHeader": renderer.format.RawHeader, "codeBlock": renderer.format.CodeBlock, "link": renderer.format.Link, @@ -106,8 +109,8 @@ func NewRenderer(opts ...RendererOption) (*Renderer, error) { "accordionHeader": renderer.format.AccordionHeader, "accordionTerminator": renderer.format.AccordionTerminator, "localHref": renderer.format.LocalHref, + "rawLocalHref": renderer.format.RawLocalHref, "codeHref": renderer.format.CodeHref, - "paragraph": renderer.format.Paragraph, "escape": renderer.format.Escape, }) diff --git a/templates.go b/templates.go index d9af986..60efb70 100644 --- a/templates.go +++ b/templates.go @@ -5,17 +5,16 @@ package gomarkdoc var templates = map[string]string{ "doc": `{{- range (iter .Blocks) -}} {{- if eq .Entry.Kind "paragraph" -}} - {{- paragraph .Entry.Text -}} + {{- template "text" .Entry.Spans -}} {{- else if eq .Entry.Kind "code" -}} - {{- codeBlock "" .Entry.Text -}} + {{- codeBlock "" (include "text" .Entry.Spans) -}} {{- else if eq .Entry.Kind "header" -}} - {{- header .Entry.Level .Entry.Text -}} + {{- header .Entry.Level (include "text" .Entry.Spans) -}} {{- else if eq .Entry.Kind "list" -}} {{- template "list" .Entry.List -}} {{- end -}} {{- if (not .Last) -}}{{- spacer -}}{{- end -}} {{- end -}} - `, "example": `{{- accordionHeader .Title -}} {{- spacer -}} @@ -59,9 +58,9 @@ var templates = map[string]string{ Generated by {{link "gomarkdoc" "https://github.com/princjef/gomarkdoc"}} `, "func": `{{- if .Receiver -}} - {{- codeHref .Location | link (escape .Name) | printf "func \\(%s\\) %s" (escape .Receiver) | rawHeader .Level -}} + {{- rawAnchorHeader .Level (codeHref .Location | link (escape .Name) | printf "func \\(%s\\) %s" (escape .Receiver)) .Anchor -}} {{- else -}} - {{- codeHref .Location | link (escape .Name) | printf "func %s" | rawHeader .Level -}} + {{- rawAnchorHeader .Level (codeHref .Location | link (escape .Name) | printf "func %s") .Anchor -}} {{- end -}} {{- spacer -}} @@ -97,35 +96,23 @@ Generated by {{link "gomarkdoc" "https://github.com/princjef/gomarkdoc"}} {{- range .Funcs -}} - {{- if .Receiver -}} - {{- codeHref .Location | link (escape .Name) | printf "func \\(%s\\) %s" (escape .Receiver) | localHref | link .Signature | listEntry 0 -}} - {{- else -}} - {{- codeHref .Location | link (escape .Name) | printf "func %s" | localHref | link .Signature | listEntry 0 -}} - {{- end -}} + {{- (link .Signature (rawLocalHref .Anchor)) | listEntry 0 -}} {{- inlineSpacer -}} {{- end -}} {{- range .Types -}} - {{- codeHref .Location | link (escape .Name) | printf "type %s" | localHref | link .Title | listEntry 0 -}} + {{- (link .Title (rawLocalHref .Anchor)) | listEntry 0 -}} {{- inlineSpacer -}} {{- range .Funcs -}} - {{- if .Receiver -}} - {{- codeHref .Location | link (escape .Name) | printf "func \\(%s\\) %s" (escape .Receiver) | localHref | link .Signature | listEntry 1 -}} - {{- else -}} - {{- codeHref .Location | link (escape .Name) | printf "func %s" | localHref | link .Signature | listEntry 1 -}} - {{- end -}} + {{- (link .Signature (rawLocalHref .Anchor)) | listEntry 1 -}} {{- inlineSpacer -}} {{- end -}} {{- range .Methods -}} - {{- if .Receiver -}} - {{- codeHref .Location | link (escape .Name) | printf "func \\(%s\\) %s" (escape .Receiver) | localHref | link .Signature | listEntry 1 -}} - {{- else -}} - {{- codeHref .Location | link (escape .Name) | printf "func %s" | localHref | link .Signature | listEntry 1 -}} - {{- end -}} + {{- (link .Signature (rawLocalHref .Anchor)) | listEntry 1 -}} {{- inlineSpacer -}} {{- end -}} @@ -216,7 +203,18 @@ Generated by {{link "gomarkdoc" "https://github.com/princjef/gomarkdoc"}} {{- end -}} {{- end -}} `, - "type": `{{- codeHref .Location | link (escape .Name) | printf "type %s" | rawHeader .Level -}} + "text": `{{- range . -}} + {{- if eq .Kind "text" -}} + {{- escape .Text -}} + {{- else if eq .Kind "rawText" -}} + {{- .Text -}} + {{- else if eq .Kind "autolink" -}} + {{- .Text -}} + {{- else if eq .Kind "link" -}} + {{- link (escape .Text) .URL -}} + {{- end -}} +{{- end -}}`, + "type": `{{- rawAnchorHeader .Level (codeHref .Location | link (escape .Name) | printf "type %s") .Anchor -}} {{- spacer -}} {{- template "doc" .Doc -}} @@ -270,7 +268,8 @@ Generated by {{link "gomarkdoc" "https://github.com/princjef/gomarkdoc"}} {{- end -}} `, - "value": `{{- template "doc" .Doc -}} + "value": `{{- anchor .Anchor -}} +{{- template "doc" .Doc -}} {{- spacer -}} {{- codeBlock "go" .Decl -}} diff --git a/templates/doc.gotxt b/templates/doc.gotxt index 5e5f8c9..dae9ba2 100644 --- a/templates/doc.gotxt +++ b/templates/doc.gotxt @@ -1,13 +1,12 @@ {{- range (iter .Blocks) -}} {{- if eq .Entry.Kind "paragraph" -}} - {{- paragraph .Entry.Text -}} + {{- template "text" .Entry.Spans -}} {{- else if eq .Entry.Kind "code" -}} - {{- codeBlock "" .Entry.Text -}} + {{- codeBlock "" (include "text" .Entry.Spans) -}} {{- else if eq .Entry.Kind "header" -}} - {{- header .Entry.Level .Entry.Text -}} + {{- header .Entry.Level (include "text" .Entry.Spans) -}} {{- else if eq .Entry.Kind "list" -}} {{- template "list" .Entry.List -}} {{- end -}} {{- if (not .Last) -}}{{- spacer -}}{{- end -}} {{- end -}} - diff --git a/templates/func.gotxt b/templates/func.gotxt index 072db3a..323c517 100644 --- a/templates/func.gotxt +++ b/templates/func.gotxt @@ -1,7 +1,7 @@ {{- if .Receiver -}} - {{- codeHref .Location | link (escape .Name) | printf "func \\(%s\\) %s" (escape .Receiver) | rawHeader .Level -}} + {{- rawAnchorHeader .Level (codeHref .Location | link (escape .Name) | printf "func \\(%s\\) %s" (escape .Receiver)) .Anchor -}} {{- else -}} - {{- codeHref .Location | link (escape .Name) | printf "func %s" | rawHeader .Level -}} + {{- rawAnchorHeader .Level (codeHref .Location | link (escape .Name) | printf "func %s") .Anchor -}} {{- end -}} {{- spacer -}} diff --git a/templates/index.gotxt b/templates/index.gotxt index e378324..ab2e0e3 100644 --- a/templates/index.gotxt +++ b/templates/index.gotxt @@ -14,35 +14,23 @@ {{- range .Funcs -}} - {{- if .Receiver -}} - {{- codeHref .Location | link (escape .Name) | printf "func \\(%s\\) %s" (escape .Receiver) | localHref | link .Signature | listEntry 0 -}} - {{- else -}} - {{- codeHref .Location | link (escape .Name) | printf "func %s" | localHref | link .Signature | listEntry 0 -}} - {{- end -}} + {{- (link .Signature (rawLocalHref .Anchor)) | listEntry 0 -}} {{- inlineSpacer -}} {{- end -}} {{- range .Types -}} - {{- codeHref .Location | link (escape .Name) | printf "type %s" | localHref | link .Title | listEntry 0 -}} + {{- (link .Title (rawLocalHref .Anchor)) | listEntry 0 -}} {{- inlineSpacer -}} {{- range .Funcs -}} - {{- if .Receiver -}} - {{- codeHref .Location | link (escape .Name) | printf "func \\(%s\\) %s" (escape .Receiver) | localHref | link .Signature | listEntry 1 -}} - {{- else -}} - {{- codeHref .Location | link (escape .Name) | printf "func %s" | localHref | link .Signature | listEntry 1 -}} - {{- end -}} + {{- (link .Signature (rawLocalHref .Anchor)) | listEntry 1 -}} {{- inlineSpacer -}} {{- end -}} {{- range .Methods -}} - {{- if .Receiver -}} - {{- codeHref .Location | link (escape .Name) | printf "func \\(%s\\) %s" (escape .Receiver) | localHref | link .Signature | listEntry 1 -}} - {{- else -}} - {{- codeHref .Location | link (escape .Name) | printf "func %s" | localHref | link .Signature | listEntry 1 -}} - {{- end -}} + {{- (link .Signature (rawLocalHref .Anchor)) | listEntry 1 -}} {{- inlineSpacer -}} {{- end -}} diff --git a/templates/text.gotxt b/templates/text.gotxt new file mode 100644 index 0000000..1d4b981 --- /dev/null +++ b/templates/text.gotxt @@ -0,0 +1,11 @@ +{{- range . -}} + {{- if eq .Kind "text" -}} + {{- escape .Text -}} + {{- else if eq .Kind "rawText" -}} + {{- .Text -}} + {{- else if eq .Kind "autolink" -}} + {{- .Text -}} + {{- else if eq .Kind "link" -}} + {{- link (escape .Text) .URL -}} + {{- end -}} +{{- end -}} \ No newline at end of file diff --git a/templates/type.gotxt b/templates/type.gotxt index a61fd9a..3371038 100644 --- a/templates/type.gotxt +++ b/templates/type.gotxt @@ -1,4 +1,4 @@ -{{- codeHref .Location | link (escape .Name) | printf "type %s" | rawHeader .Level -}} +{{- rawAnchorHeader .Level (codeHref .Location | link (escape .Name) | printf "type %s") .Anchor -}} {{- spacer -}} {{- template "doc" .Doc -}} diff --git a/templates/value.gotxt b/templates/value.gotxt index 0dcdf3d..23354fc 100644 --- a/templates/value.gotxt +++ b/templates/value.gotxt @@ -1,3 +1,4 @@ +{{- anchor .Anchor -}} {{- template "doc" .Doc -}} {{- spacer -}} diff --git a/testData/docs/README.md b/testData/docs/README.md index 78b23ab..29abb5f 100644 --- a/testData/docs/README.md +++ b/testData/docs/README.md @@ -10,7 +10,7 @@ Package docs exercises the documentation features of golang 1.19 and above at th ### This is a heading -This heading has a paragraph with a reference to the standard library math/rand as well as a function in the file \[Func\], a type \[Type\], a type's function \[Type.Func\], a non\-standard library package \[golang.org/x/crypto@v0.5.0/bcrypt.Cost\], an external link Outside Link and a \[broken link\]. +This heading has a paragraph with a reference to the standard library [math/rand]() as well as a function in the file [Func](<#Func>), a type [Type](<#Type>), a type's function [Type.Func](<#Type.Func>), a non\-standard library package [golang.org/x/crypto/bcrypt.Cost](), an external link [Outside Link]() and a \[broken link\]. It also has a numbered list: @@ -59,14 +59,60 @@ in a random way ``` +There's also another file with a struct called [AnotherStruct](<#AnotherStruct>) that has additional methods and fields. + +We also have constants like [Constant](<#Constant>) and [Const1](<#Const1>) plus variables like [Var](<#Var>) and and [VarB](<#VarA>). + ## Index -- [func Func(param int) int](<#func-func>) -- [type Type](<#type-type>) - - [func (t *Type) Func()](<#func-type-func>) +- [Constants](<#constants>) +- [Variables](<#variables>) +- [func Func(param int) int](<#Func>) +- [type AnotherStruct](<#AnotherStruct>) + - [func NewAnotherStruct() *AnotherStruct](<#NewAnotherStruct>) + - [func (s *AnotherStruct) GetField() string](<#AnotherStruct.GetField>) +- [type Type](<#Type>) + - [func (t *Type) Func()](<#Type.Func>) + + +## Constants + +This is a constant block + +```go +const ( + Const1 = 1 + Const2 = 2 + Const3 = 3 +) +``` + +Constant is a constant. + +```go +const Constant = 3 +``` + +## Variables + +This is a var block + +```go +var ( + VarA = 'a' + VarB = 'b' + VarC = 'c' +) +``` + +Var is a var. +```go +var Var = 2 +``` -## func [Func]() + +## func [Func]() ```go func Func(param int) int @@ -74,7 +120,37 @@ func Func(param int) int Func is present in this file. -## type [Type]() + +## type [AnotherStruct]() + +AnotherStruct has methods like [\*AnotherStruct.GetField](<#AnotherStruct.GetField>) and also has an initializer called [NewAnotherStruct](<#NewAnotherStruct>). + +```go +type AnotherStruct struct { + Field string +} +``` + + +### func [NewAnotherStruct]() + +```go +func NewAnotherStruct() *AnotherStruct +``` + +NewAnotherStruct\(\) makes [\*AnotherStruct](<#AnotherStruct>). + + +### func \(\*AnotherStruct\) [GetField]() + +```go +func (s *AnotherStruct) GetField() string +``` + +GetField gets \[\*AnotherStruct.Field\]. + + +## type [Type]() Type is a type in this file. @@ -82,7 +158,8 @@ Type is a type in this file. type Type struct{} ``` -### func \(\*Type\) [Func]() + +### func \(\*Type\) [Func]() ```go func (t *Type) Func() diff --git a/testData/docs/anotherFile.go b/testData/docs/anotherFile.go new file mode 100644 index 0000000..b35d644 --- /dev/null +++ b/testData/docs/anotherFile.go @@ -0,0 +1,19 @@ +package docs + +// AnotherStruct has methods like [*AnotherStruct.GetField] and also has an +// initializer called [NewAnotherStruct]. +type AnotherStruct struct { + Field string +} + +// NewAnotherStruct() makes [*AnotherStruct]. +func NewAnotherStruct() *AnotherStruct { + return &AnotherStruct{ + Field: "test", + } +} + +// GetField gets [*AnotherStruct.Field]. +func (s *AnotherStruct) GetField() string { + return s.Field +} diff --git a/testData/docs/docs.go b/testData/docs/docs.go index 2409815..12f9fdf 100644 --- a/testData/docs/docs.go +++ b/testData/docs/docs.go @@ -6,7 +6,7 @@ // This heading has a paragraph with a reference to the standard library // [math/rand] as well as a function in the file [Func], a type [Type], a type's // function [Type.Func], a non-standard library package -// [golang.org/x/crypto@v0.5.0/bcrypt.Cost], an external link [Outside Link] and +// [golang.org/x/crypto/bcrypt.Cost], an external link [Outside Link] and // a [broken link]. // // It also has a numbered list: @@ -51,6 +51,12 @@ // in a random // way // +// There's also another file with a struct called [AnotherStruct] that has +// additional methods and fields. +// +// We also have constants like [Constant] and [Const1] plus variables like +// [Var] and and [VarB]. +// // [Outside Link]: https://golang.org/doc/articles/json_and_go.html package docs @@ -64,3 +70,23 @@ type Type struct{} // TypeFunc is a func within a type in this file. func (t *Type) Func() {} + +// Constant is a constant. +const Constant = 3 + +// Var is a var. +var Var = 2 + +// This is a constant block +const ( + Const1 = 1 + Const2 = 2 + Const3 = 3 +) + +// This is a var block +var ( + VarA = 'a' + VarB = 'b' + VarC = 'c' +) diff --git a/testData/embed/README.md b/testData/embed/README.md index cf33de2..4be9859 100644 --- a/testData/embed/README.md +++ b/testData/embed/README.md @@ -14,9 +14,10 @@ Package embed tests out embedding of documentation in an existing readme. ## Index -- [func EmbeddedFunc(param int) int](<#func-embeddedfunc>) +- [func EmbeddedFunc(param int) int](<#EmbeddedFunc>) + ## func [EmbeddedFunc]() ```go @@ -46,9 +47,10 @@ Package embed tests out embedding of documentation in an existing readme. ## Index -- [func EmbeddedFunc(param int) int](<#func-embeddedfunc>) +- [func EmbeddedFunc(param int) int](<#EmbeddedFunc>) + ## func [EmbeddedFunc]() ```go @@ -78,9 +80,10 @@ Package embed tests out embedding of documentation in an existing readme. ## Index -- [func EmbeddedFunc(param int) int](<#func-embeddedfunc>) +- [func EmbeddedFunc(param int) int](<#EmbeddedFunc>) + ## func [EmbeddedFunc]() ```go diff --git a/testData/lang/function/README.md b/testData/lang/function/README.md index 4c38227..6bcd8c8 100644 --- a/testData/lang/function/README.md +++ b/testData/lang/function/README.md @@ -10,18 +10,18 @@ import "github.com/princjef/gomarkdoc/testData/lang/function" - [Constants](<#constants>) - [Variables](<#variables>) -- [func Standalone(p1 int, p2 string) (int, error)](<#func-standalone>) -- [type Generic](<#type-generic>) - - [func (r Generic[T]) WithGenericReceiver()](<#func-generict-withgenericreceiver>) -- [type Receiver](<#type-receiver>) - - [func New() Receiver](<#func-new>) - - [func (r *Receiver) WithPtrReceiver()](<#func-receiver-withptrreceiver>) - - [func (r Receiver) WithReceiver()](<#func-receiver-withreceiver>) +- [func Standalone(p1 int, p2 string) (int, error)](<#Standalone>) +- [type Generic](<#Generic>) + - [func (r Generic[T]) WithGenericReceiver()](<#Generic[T].WithGenericReceiver>) +- [type Receiver](<#Receiver>) + - [func New() Receiver](<#New>) + - [func (r *Receiver) WithPtrReceiver()](<#Receiver.WithPtrReceiver>) + - [func (r Receiver) WithReceiver()](<#Receiver.WithReceiver>) ## Constants -Set of constants for this package. +Set of constants for this package. ```go const ( @@ -32,12 +32,13 @@ const ( ## Variables -Variable is a package\-level variable. +Variable is a package\-level variable. ```go var Variable = 5 ``` + ## func [Standalone]() ```go @@ -115,6 +116,7 @@ func main() {

+ ## type [Generic]() Generic is a struct with a generic type. @@ -123,6 +125,7 @@ Generic is a struct with a generic type. type Generic[T any] struct{} ``` + ### func \(Generic\[T\]\) [WithGenericReceiver]() ```go @@ -152,6 +155,7 @@ func main() {

+ ## type [Receiver]() Receiver is a type used to demonstrate functions with receivers. @@ -204,6 +208,7 @@ func main() {

+ ### func [New]() ```go @@ -212,6 +217,7 @@ func New() Receiver New is an initializer for Receiver. + ### func \(\*Receiver\) [WithPtrReceiver]() ```go @@ -220,6 +226,7 @@ func (r *Receiver) WithPtrReceiver() WithPtrReceiver has a pointer receiver. + ### func \(Receiver\) [WithReceiver]() ```go diff --git a/testData/nested/README.md b/testData/nested/README.md index 62c92c7..afef288 100755 --- a/testData/nested/README.md +++ b/testData/nested/README.md @@ -8,9 +8,10 @@ import "github.com/princjef/gomarkdoc/testData/nested" ## Index -- [func Parent() int](<#func-parent>) +- [func Parent() int](<#Parent>) + ## func [Parent]() ```go diff --git a/testData/nested/inner/README.md b/testData/nested/inner/README.md index 336b327..da48ecb 100755 --- a/testData/nested/inner/README.md +++ b/testData/nested/inner/README.md @@ -8,9 +8,10 @@ import "github.com/princjef/gomarkdoc/testData/nested/inner" ## Index -- [func Child() int](<#func-child>) +- [func Child() int](<#Child>) + ## func [Child]() ```go diff --git a/testData/simple/README.md b/testData/simple/README.md index 3dfe300..2e954f6 100755 --- a/testData/simple/README.md +++ b/testData/simple/README.md @@ -10,11 +10,12 @@ Package simple contains, some simple code to exercise basic scenarios for docume ## Index -- [type Num](<#type-num>) - - [func AddNums(num1, num2 Num) Num](<#func-addnums>) - - [func (n Num) Add(num Num) Num](<#func-num-add>) +- [type Num](<#Num>) + - [func AddNums(num1, num2 Num) Num](<#AddNums>) + - [func (n Num) Add(num Num) Num](<#Num.Add>) + ## type [Num]() Num is a number. @@ -25,6 +26,7 @@ It is just a test type so that we can make sure this works. type Num int ``` + ### func [AddNums]() ```go @@ -33,6 +35,7 @@ func AddNums(num1, num2 Num) Num AddNums adds two Nums together. + ### func \(Num\) [Add]() ```go diff --git a/testData/tags/README.md b/testData/tags/README.md index 9ced294..3bbead3 100755 --- a/testData/tags/README.md +++ b/testData/tags/README.md @@ -10,10 +10,11 @@ Package tags contains code to demonstrate usage of build tags. ## Index -- [func Tagged() int](<#func-tagged>) -- [func Untagged() int](<#func-untagged>) +- [func Tagged() int](<#Tagged>) +- [func Untagged() int](<#Untagged>) + ## func [Tagged]() ```go @@ -22,6 +23,7 @@ func Tagged() int Tagged is only visible with tags. + ## func [Untagged]() ```go diff --git a/testData/unexported/README.md b/testData/unexported/README.md index 4b4a917..10fe16e 100755 --- a/testData/unexported/README.md +++ b/testData/unexported/README.md @@ -10,12 +10,13 @@ Package unexported contains some simple code to exercise basic scenarios for doc ## Index -- [type Num](<#type-num>) - - [func AddNums(num1, num2 Num) Num](<#func-addnums>) - - [func addInternal(num1, num2 Num) Num](<#func-addinternal>) - - [func (n Num) Add(num Num) Num](<#func-num-add>) +- [type Num](<#Num>) + - [func AddNums(num1, num2 Num) Num](<#AddNums>) + - [func addInternal(num1, num2 Num) Num](<#addInternal>) + - [func (n Num) Add(num Num) Num](<#Num.Add>) + ## type [Num]() Num is a number. @@ -26,6 +27,7 @@ It is just a test type so that we can make sure this works. type Num int ``` + ### func [AddNums]() ```go @@ -34,6 +36,7 @@ func AddNums(num1, num2 Num) Num AddNums adds two Nums together. + ### func [addInternal]() ```go @@ -42,6 +45,7 @@ func addInternal(num1, num2 Num) Num addInternal is a private version of AddNums. + ### func \(Num\) [Add]() ```go diff --git a/testData/untagged/README.md b/testData/untagged/README.md index 1c9ca81..5ca4f59 100755 --- a/testData/untagged/README.md +++ b/testData/untagged/README.md @@ -10,9 +10,10 @@ Package untagged contains code to demonstrate usage of build tags. ## Index -- [func Untagged() int](<#func-untagged>) +- [func Untagged() int](<#Untagged>) + ## func [Untagged]() ```go