abbreviations

package module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 4, 2025 License: MIT Imports: 13 Imported by: 0

README

Goldmark Abbreviations Extension

Option Functions:

  • WithHeadingAbbr(bool) - Enable or disable abbreviations in headings (default: false)
  • WithShowInvalidNames(bool) - Show invalid abbreviation names as HTML lists or HTML comments (default: false)
  • WithMaximumMatches(int) - Limit the number of times each abbreviation will be matched and converted (default: unlimited)
  • WithEndnotesList(title...) - Generate list endnotes (defaults to "Abbreviations")
  • WithEndnotesTable(title...) - Generate table endnotes (defaults to "Abbreviations")
  • WithEndnotesGlossary(title...) - Generate glossary endnotes (defaults to "Glossary")

This is a comprehensive Goldmark extension that provides abbreviation handling mostly compatible with PHP Markdown Extra syntax when configured with its default values. This extension converts abbreviation definitions into <abbr> HTML elements with proper title attributes.

Installation

go get github.com/zmtcreative/gm-abbreviations

Quick Start

Basic Usage
package main

import (
    "fmt"
    "github.com/yuin/goldmark"
    "github.com/zmtcreative/gm-abbreviations"
)

func main() {
    md := goldmark.New(
        goldmark.WithExtensions(
            abbreviations.NewAbbreviations(),
        ),
    )

    source := `## This is HTML

This is a basic description of HTML. It often uses CSS for styling.
Use CSS to make your HTML look pretty.

*[HTML]: HyperText Markup Language
*[CSS]: Cascading Style Sheets`

    var buf bytes.Buffer
    if err := md.Convert([]byte(source), &buf); err != nil {
        panic(err)
    }
    fmt.Print(buf.String())
}

Output:

<h2>This is HTML</h2>
<p>This is a basic description of <abbr title="HyperText Markup Language">HTML</abbr>.
It often uses <abbr title="Cascading Style Sheets">CSS</abbr> for styling.
Use <abbr title="Cascading Style Sheets">CSS</abbr> to make your
<abbr title="HyperText Markup Language">HTML</abbr> look pretty.</p>
Advanced Options

You can combine multiple configuration options:

md := goldmark.New(
    goldmark.WithExtensions(
        abbreviations.NewAbbreviations(
            abbreviations.WithHeadingAbbr(true),         // Enable abbreviations in headings
            abbreviations.WithShowInvalidNames(true),    // Show invalid abbreviation names as lists
            abbreviations.WithMaximumMatches(2),         // Limit to 2 matches per abbreviation
            abbreviations.WithEndnotesList(),            // Generate list endnotes with default title
            abbreviations.WithEndnotesTable("Acronyms"), // Generate table endnotes with custom title
            abbreviations.WithEndnotesGlossary(),        // Generate glossary endnotes with default title
        ),
    ),
)
Maximum Matches Control

By default, every occurrence of an abbreviation in the text will be converted to an <abbr> tag. You can limit this behavior:

// Only convert the first occurrence of each abbreviation
md := goldmark.New(
    goldmark.WithExtensions(
        abbreviations.NewAbbreviations(
            abbreviations.WithMaximumMatches(1),
        ),
    ),
)

// Disable all abbreviation conversion (definitions still processed for endnotes)
md := goldmark.New(
    goldmark.WithExtensions(
        abbreviations.NewAbbreviations(
            abbreviations.WithMaximumMatches(0),
        ),
    ),
)

With WithMaximumMatches(2) and the text "HTML is great and HTML is useful for web HTML development", only the first two instances of "HTML" would be converted to <abbr> tags, leaving the third instance as plain text.

Symbol Management

By default, abbreviation names can contain letters, numbers, spaces, and these symbols: -, _, ., +, /, :, ;, &, #, '. You can customize which symbols are allowed:

// Use only specific symbols
md := goldmark.New(
    goldmark.WithExtensions(
        abbreviations.NewAbbreviations(
            abbreviations.WithAllowedSymbols([]rune{'-', '_', '@'}),
        ),
    ),
)

// Add additional symbols to the defaults
md := goldmark.New(
    goldmark.WithExtensions(
        abbreviations.NewAbbreviations(
            abbreviations.WithAdditionalAllowedSymbols([]rune{'@', '!'}),
        ),
    ),
)

// Remove specific symbols from the defaults
md := goldmark.New(
    goldmark.WithExtensions(
        abbreviations.NewAbbreviations(
            abbreviations.WithoutAllowedSymbols([]rune{'#', '&'}),
        ),
    ),
)

You can also manage symbols after creating the extension:

ext := abbreviations.NewAbbreviations()

// Set completely new allowed symbols
ext.SetAllowedSymbols([]rune{'-', '_', '.'})

// Add a symbol
ext.AddAllowedSymbol('@')

// Remove a symbol
ext.RemoveAllowedSymbol('#')

md := goldmark.New(goldmark.WithExtensions(ext))

Option Functions:

  • WithHeadingAbbr(bool) - Enable or disable abbreviations in headings (default: false)
  • WithShowInvalidNames(bool) - Show invalid abbreviation names as HTML lists or HTML comments (default: false)
  • WithMaximumMatches(int) - Limit the number of times each abbreviation will be matched and converted (default: unlimited)
  • WithEndnotesList(title...) - Generate list endnotes (defaults to "Abbreviations")
  • WithEndnotesTable(title...) - Generate table endnotes (defaults to "Abbreviations")
  • WithEndnotesGlossary(title...) - Generate glossary endnotes (defaults to "Glossary")
  • WithAllowedSymbols([]rune) - Set custom allowed symbols for abbreviation names
  • WithAdditionalAllowedSymbols([]rune) - Add symbols to the default allowed symbols
  • WithoutAllowedSymbols([]rune) - Remove specific symbols from the default allowed symbols

Each endnotes function accepts an optional title parameter. If no title is provided, the default is used.

The default initialization when none of these options are specified:

  • abbreviations.WithHeadingAbbr(false) - Abbreviations disabled in headings
  • abbreviations.WithShowInvalidNames(false) - Invalid abbreviation names rendered as HTML comments
  • No Endnotes -- none of the endnote options are used

For more detailed information, see the FEATURES.md document.

License

MIT License - see LICENSE.md for details.

  • Goldmark - The extensible Markdown parser this extension is built for
  • PHP Markdown Extra - The original specification this extension implements

Documentation

Overview

Package abbreviations provides a Goldmark extension for handling abbreviations in Markdown documents, similar to PHP Markdown Extra's abbreviation syntax.

This extension allows you to define abbreviations using the syntax:

*[ABBR]: Definition text

And automatically converts abbreviation occurrences in the text to HTML <abbr> tags with appropriate title attributes.

Basic Usage

md := goldmark.New(
    goldmark.WithExtensions(
        abbreviations.NewAbbreviations(),
    ),
)

source := `This is HTML.

*[HTML]: HyperText Markup Language`

// Converts to: <p>This is <abbr title="HyperText Markup Language">HTML</abbr>.</p>

Configuration Options

The extension supports several configuration options:

  • WithHeadingAbbr(true) - Enable abbreviations in headings (disabled by default)
  • WithEndnotesList() - Generate abbreviation list at document end
  • WithEndnotesTable() - Generate abbreviation table at document end
  • WithEndnotesGlossary() - Generate abbreviation glossary at document end
  • WithEndnotesList(title) - Generate abbreviation list with custom title
  • WithEndnotesTable(title) - Generate abbreviation table with custom title
  • WithEndnotesGlossary(title) - Generate abbreviation glossary with custom title

Features

  • Automatic text replacement with <abbr> tags
  • Code blocks are excluded from processing
  • Prevents nested abbreviation tags
  • Unicode-aware text processing
  • Integration with footnotes extension
  • Invalid abbreviation definitions are handled gracefully

For more information, see: https://github.com/zmtcreative/gm-abbreviations

Index

Constants

This section is empty.

Variables

View Source
var Abbreviations = NewAbbreviations()

Abbreviations is a default instance of the abbreviations extension with default settings. This provides an alternative way to initialize the extension:

goldmark.WithExtensions(abbreviations.Abbreviations)

The preferred method is still using the constructor:

goldmark.WithExtensions(abbreviations.NewAbbreviations())
View Source
var KindAbbreviationEndnotesGlossary = ast.NewNodeKind("AbbreviationEndnotesGlossary")

KindAbbreviationEndnotesGlossary is the AST node kind for AbbreviationEndnotesGlossary nodes. This can be used for AST traversal and node type checking.

View Source
var KindAbbreviationEndnotesList = ast.NewNodeKind("AbbreviationEndnotesList")

KindAbbreviationEndnotesList is the AST node kind for AbbreviationEndnotesList nodes. This can be used for AST traversal and node type checking.

View Source
var KindAbbreviationEndnotesTable = ast.NewNodeKind("AbbreviationEndnotesTable")

KindAbbreviationEndnotesTable is the AST node kind for AbbreviationEndnotesTable nodes. This can be used for AST traversal and node type checking.

View Source
var KindInvalidAbbreviationDefinition = ast.NewNodeKind("InvalidAbbreviationDefinition")

KindInvalidAbbreviationDefinition is the AST node kind for InvalidAbbreviationDefinition nodes. This can be used for AST traversal and node type checking.

View Source
var KindInvalidAbbreviationList = ast.NewNodeKind("InvalidAbbreviationList")

KindInvalidAbbreviationList is the AST node kind for InvalidAbbreviationList nodes. This can be used for AST traversal and node type checking.

Functions

func NewAbbreviations

func NewAbbreviations(opts ...AbbreviationsOption) *abbreviations

NewAbbreviations creates a new abbreviations extension with the given options. By default, abbreviations are disabled in headings and no endnotes are generated.

Example usage:

// Basic usage with default settings
ext := abbreviations.NewAbbreviations()

// With custom options
ext := abbreviations.NewAbbreviations(
    abbreviations.WithHeadingAbbr(true),
    abbreviations.WithEndnotesList(),
)

md := goldmark.New(goldmark.WithExtensions(ext))

Types

type AbbreviationEndnotesGlossary added in v0.1.1

type AbbreviationEndnotesGlossary struct {
	ast.BaseBlock
	Abbreviations map[string]string
	EndnotesTitle string
}

AbbreviationEndnotesGlossary represents an abbreviation endnotes glossary in the AST. This node contains all abbreviations defined in the document and renders them as a definition list at the end of the document when WithEndnotesGlossary() is used.

The glossary is inserted before footnotes if the footnotes extension is also enabled.

func NewAbbreviationEndnotesGlossary added in v0.1.1

func NewAbbreviationEndnotesGlossary(abbreviations map[string]string, title string) *AbbreviationEndnotesGlossary

NewAbbreviationEndnotesGlossary creates a new AbbreviationEndnotesGlossary node. The abbreviations parameter should contain a map of abbreviation names to their definitions. The title parameter specifies the endnotes section title.

This function is primarily used internally by the extension's transformer and should not typically be called by user code.

func (*AbbreviationEndnotesGlossary) Dump added in v0.1.1

func (n *AbbreviationEndnotesGlossary) Dump(source []byte, level int)

Dump implements ast.Node.Dump

func (*AbbreviationEndnotesGlossary) Kind added in v0.1.1

Kind implements ast.Node.Kind

type AbbreviationEndnotesList

type AbbreviationEndnotesList struct {
	ast.BaseBlock
	Abbreviations map[string]string
	EndnotesTitle string
}

AbbreviationEndnotesList represents an abbreviation endnotes list in the AST. This node contains all abbreviations defined in the document and renders them as a bulleted list at the end of the document when WithEndnotesList() is used.

The list is inserted before footnotes if the footnotes extension is also enabled.

func NewAbbreviationEndnotesList

func NewAbbreviationEndnotesList(abbreviations map[string]string, title string) *AbbreviationEndnotesList

NewAbbreviationEndnotesList creates a new AbbreviationEndnotesList node. The abbreviations parameter should contain a map of abbreviation names to their definitions. The title parameter specifies the endnotes section title.

This function is primarily used internally by the extension's transformer and should not typically be called by user code.

func (*AbbreviationEndnotesList) Dump

func (n *AbbreviationEndnotesList) Dump(source []byte, level int)

Dump implements ast.Node.Dump

func (*AbbreviationEndnotesList) Kind

Kind implements ast.Node.Kind

type AbbreviationEndnotesTable

type AbbreviationEndnotesTable struct {
	ast.BaseBlock
	Abbreviations map[string]string
	EndnotesTitle string
}

AbbreviationEndnotesTable represents an abbreviation endnotes table in the AST. This node contains all abbreviations defined in the document and renders them as a table at the end of the document when WithEndnotesTable() is used.

The table is inserted before footnotes if the footnotes extension is also enabled.

func NewAbbreviationEndnotesTable

func NewAbbreviationEndnotesTable(abbreviations map[string]string, title string) *AbbreviationEndnotesTable

NewAbbreviationEndnotesTable creates a new AbbreviationEndnotesTable node. The abbreviations parameter should contain a map of abbreviation names to their definitions. The title parameter specifies the endnotes section title.

This function is primarily used internally by the extension's transformer and should not typically be called by user code.

func (*AbbreviationEndnotesTable) Dump

func (n *AbbreviationEndnotesTable) Dump(source []byte, level int)

Dump implements ast.Node.Dump

func (*AbbreviationEndnotesTable) Kind

Kind implements ast.Node.Kind

type AbbreviationsEndnotesType

type AbbreviationsEndnotesType int

AbbreviationsEndnotesType represents the type of endnotes to generate at the end of the document. This determines how abbreviations are displayed in the optional endnotes section.

const (
	// EndnotesNone means no endnotes will be generated (default behavior).
	// Abbreviations will only appear as <abbr> tags in the text.
	EndnotesNone AbbreviationsEndnotesType = iota

	// EndnotesList generates abbreviations as a bulleted list at the document end.
	// Use WithEndnotesList() or WithEndnotesListTitle() to enable this option.
	EndnotesList

	// EndnotesTable generates abbreviations as a table at the document end.
	// Use WithEndnotesTable() or WithEndnotesTableTitle() to enable this option.
	EndnotesTable

	// EndnotesGlossary generates abbreviations as a definition list at the document end.
	// Use WithEndnotesGlossary() or WithEndnotesGlossaryTitle() to enable this option.
	EndnotesGlossary
)

type AbbreviationsOption

type AbbreviationsOption func(*abbreviations)

AbbreviationsOption is a functional option for configuring the abbreviations extension. Options are applied when creating a new extension instance with NewAbbreviations.

func WithAdditionalAllowedSymbols added in v0.1.1

func WithAdditionalAllowedSymbols(symbols []rune) AbbreviationsOption

WithAdditionalAllowedSymbols adds additional symbols to the default allowed symbols. This extends the default set rather than replacing it.

Example usage:

ext := abbreviations.NewAbbreviations(
    abbreviations.WithAdditionalAllowedSymbols([]rune{'@', '!'}),
)

func WithAllowedSymbols added in v0.1.1

func WithAllowedSymbols(symbols []rune) AbbreviationsOption

WithAllowedSymbols sets the allowed symbols for abbreviation names. This replaces the default allowed symbols with the provided list.

Example usage:

ext := abbreviations.NewAbbreviations(
    abbreviations.WithAllowedSymbols([]rune{'-', '_', '.'}),
)

func WithEndnotesGlossary added in v0.1.1

func WithEndnotesGlossary(title ...string) AbbreviationsOption

WithEndnotesGlossary enables abbreviations to be listed as a definition list at the end of the document. The glossary will be inserted before footnotes if the footnotes extension is also used.

If no title is provided, defaults to "Glossary". If a title is provided, it will be used instead. Only the first title parameter is used if multiple are provided.

Usage:

WithEndnotesGlossary()                // Uses default title "Glossary"
WithEndnotesGlossary("Custom Title")  // Uses custom title "Custom Title"

The generated HTML structure will be:

<div class="abbreviations abbr-glossary">
    <p class="abbr-title">{title}</p>
    <dl>
        <dt>HTML</dt>
        <dd>HyperText Markup Language</dd>
        <dt>CSS</dt>
        <dd>Cascading Style Sheets</dd>
    </dl>
</div>

func WithEndnotesList added in v0.1.1

func WithEndnotesList(title ...string) AbbreviationsOption

WithEndnotesList enables abbreviations to be listed as a bulleted list at the end of the document. The list will be inserted before footnotes if the footnotes extension is also used.

If no title is provided, defaults to "Abbreviations". If a title is provided, it will be used instead. Only the first title parameter is used if multiple are provided.

Usage:

WithEndnotesList()                    // Uses default title "Abbreviations"
WithEndnotesList("Custom Title")      // Uses custom title "Custom Title"

The generated HTML structure will be:

<div class="abbreviations abbr-list">
    <p class="abbr-title">{title}</p>
    <ul>
        <li><strong>HTML</strong>: HyperText Markup Language</li>
        <li><strong>CSS</strong>: Cascading Style Sheets</li>
    </ul>
</div>

func WithEndnotesTable added in v0.1.1

func WithEndnotesTable(title ...string) AbbreviationsOption

WithEndnotesTable enables abbreviations to be listed as a table at the end of the document. The table will be inserted before footnotes if the footnotes extension is also used.

If no title is provided, defaults to "Abbreviations". If a title is provided, it will be used instead. Only the first title parameter is used if multiple are provided.

Usage:

WithEndnotesTable()                   // Uses default title "Abbreviations"
WithEndnotesTable("Custom Title")     // Uses custom title "Custom Title"

The generated HTML structure will be:

<div class="abbreviations abbr-table">
    <p class="abbr-title">{title}</p>
    <table>
        <thead>
            <tr><th>Abbreviation</th><th>Definition</th></tr>
        </thead>
        <tbody>
            <tr><td>HTML</td><td>HyperText Markup Language</td></tr>
            <tr><td>CSS</td><td>Cascading Style Sheets</td></tr>
        </tbody>
    </table>
</div>

func WithHeadingAbbr

func WithHeadingAbbr(allow bool) AbbreviationsOption

WithHeadingAbbr sets whether abbreviations should be applied in headings. By default, abbreviations are not processed in headings (h1-h6 tags).

Setting allow to true enables abbreviation processing in headings:

ext := abbreviations.NewAbbreviations(
    abbreviations.WithHeadingAbbr(true),
)

func WithHeadingAbbreviations added in v0.1.1

func WithHeadingAbbreviations(allow bool) AbbreviationsOption

WithHeadingAbbreviations sets whether abbreviations should be applied in headings. This is an alternative name for WithHeadingAbbr.

func WithMaximumMatches added in v0.1.1

func WithMaximumMatches(maximumMatches int) AbbreviationsOption

WithMaximumMatches enables limiting the number of times each abbreviation will be matched and converted. By default, abbreviations are unlimited and every occurrence of an abbreviation in the text will be converted.

Setting maximumMatches to a positive integer limits how many times each individual abbreviation name gets matched in the body text. Once the limit is reached, subsequent occurrences will not be converted.

Setting maximumMatches to 0 (zero) is valid and means NO matches should be made - effectively disabling all abbreviation conversion while still processing abbreviation definitions.

Usage:

WithMaximumMatches(1)     // Only convert the first occurrence of each abbreviation
WithMaximumMatches(3)     // Convert up to 3 occurrences of each abbreviation
WithMaximumMatches(0)     // Disable all abbreviation conversion

Example:

ext := abbreviations.NewAbbreviations(
    abbreviations.WithMaximumMatches(2),
)

With the above configuration, if a document contains "HTML HTML HTML" and an abbreviation definition "*[HTML]: HyperText Markup Language", only the first two instances of "HTML" will be converted to <abbr> tags.

func WithShowInvalidNames added in v0.1.1

func WithShowInvalidNames(show bool) AbbreviationsOption

WithShowInvalidNames sets whether invalid abbreviation names should be rendered as HTML lists. By default, invalid abbreviation names are not displayed (showInvalidNames = false).

Setting show to true enables rendering of invalid abbreviation definitions as bulleted lists with CSS class "abbr-invalid" to help users identify problematic definitions:

ext := abbreviations.NewAbbreviations(
    abbreviations.WithShowInvalidNames(true),
)

Invalid abbreviation definitions include those with names that:

  • Start with symbols (like --HTML or _CSS)
  • Contain prohibited characters
  • Are shorter than 2 characters

When enabled, these invalid definitions will be rendered as:

<ul>
    <li class="abbr-invalid" title="Invalid Abbreviation Name">*[--HTML]: Invalid definition</li>
</ul>

func WithoutAllowedSymbols added in v0.1.1

func WithoutAllowedSymbols(symbols []rune) AbbreviationsOption

WithoutAllowedSymbols removes specific symbols from the allowed symbols. This allows removing default symbols that you don't want to allow.

Example usage:

ext := abbreviations.NewAbbreviations(
    abbreviations.WithoutAllowedSymbols([]rune{'#', '&'}),
)

type InvalidAbbreviationDefinition

type InvalidAbbreviationDefinition struct {
	ast.BaseBlock
	OriginalText string
	ErrorMessage string
}

InvalidAbbreviationDefinition represents an invalid abbreviation definition in the AST. This node is created when an abbreviation definition doesn't meet validation criteria, such as starting with invalid characters or containing prohibited symbols.

Invalid definitions are rendered as a list item with CSS class "abbr-invalid" to help users identify problematic abbreviation definitions in their documents.

func NewInvalidAbbreviationDefinition

func NewInvalidAbbreviationDefinition(originalText, errorMessage string) *InvalidAbbreviationDefinition

NewInvalidAbbreviationDefinition creates a new InvalidAbbreviationDefinition node. The originalText parameter should contain the full original abbreviation definition line. The errorMessage parameter should contain the specific reason why the abbreviation is invalid.

This function is primarily used internally by the extension's parser and should not typically be called by user code.

func (*InvalidAbbreviationDefinition) Dump

func (n *InvalidAbbreviationDefinition) Dump(source []byte, level int)

Dump implements ast.Node.Dump

func (*InvalidAbbreviationDefinition) Kind

Kind implements ast.Node.Kind

type InvalidAbbreviationList

type InvalidAbbreviationList struct {
	ast.BaseBlock
}

InvalidAbbreviationList represents a container for multiple invalid abbreviation definitions in the AST. This node groups consecutive invalid abbreviation definitions together and renders them as a bulleted list with appropriate CSS styling and error indicators.

func NewInvalidAbbreviationList

func NewInvalidAbbreviationList() *InvalidAbbreviationList

NewInvalidAbbreviationList creates a new InvalidAbbreviationList node.

This function is primarily used internally by the extension's transformer and should not typically be called by user code.

func (*InvalidAbbreviationList) Dump

func (n *InvalidAbbreviationList) Dump(source []byte, level int)

Dump implements ast.Node.Dump

func (*InvalidAbbreviationList) Kind

Kind implements ast.Node.Kind

Directories

Path Synopsis
cmd
benchmark command
Package main provides a standalone performance testing tool for the abbreviations extension.
Package main provides a standalone performance testing tool for the abbreviations extension.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL