code.gitea.io/gitea@v1.19.3/modules/markup/markdown/math/math.go (about)

     1  // Copyright 2022 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package math
     5  
     6  import (
     7  	"github.com/yuin/goldmark"
     8  	"github.com/yuin/goldmark/parser"
     9  	"github.com/yuin/goldmark/renderer"
    10  	"github.com/yuin/goldmark/util"
    11  )
    12  
    13  // Extension is a math extension
    14  type Extension struct {
    15  	enabled           bool
    16  	parseDollarInline bool
    17  	parseDollarBlock  bool
    18  }
    19  
    20  // Option is the interface Options should implement
    21  type Option interface {
    22  	SetOption(e *Extension)
    23  }
    24  
    25  type extensionFunc func(e *Extension)
    26  
    27  func (fn extensionFunc) SetOption(e *Extension) {
    28  	fn(e)
    29  }
    30  
    31  // Enabled enables or disables this extension
    32  func Enabled(enable ...bool) Option {
    33  	value := true
    34  	if len(enable) > 0 {
    35  		value = enable[0]
    36  	}
    37  	return extensionFunc(func(e *Extension) {
    38  		e.enabled = value
    39  	})
    40  }
    41  
    42  // WithInlineDollarParser enables or disables the parsing of $...$
    43  func WithInlineDollarParser(enable ...bool) Option {
    44  	value := true
    45  	if len(enable) > 0 {
    46  		value = enable[0]
    47  	}
    48  	return extensionFunc(func(e *Extension) {
    49  		e.parseDollarInline = value
    50  	})
    51  }
    52  
    53  // WithBlockDollarParser enables or disables the parsing of $$...$$
    54  func WithBlockDollarParser(enable ...bool) Option {
    55  	value := true
    56  	if len(enable) > 0 {
    57  		value = enable[0]
    58  	}
    59  	return extensionFunc(func(e *Extension) {
    60  		e.parseDollarBlock = value
    61  	})
    62  }
    63  
    64  // Math represents a math extension with default rendered delimiters
    65  var Math = &Extension{
    66  	enabled:           true,
    67  	parseDollarBlock:  true,
    68  	parseDollarInline: true,
    69  }
    70  
    71  // NewExtension creates a new math extension with the provided options
    72  func NewExtension(opts ...Option) *Extension {
    73  	r := &Extension{
    74  		enabled:           true,
    75  		parseDollarBlock:  true,
    76  		parseDollarInline: true,
    77  	}
    78  
    79  	for _, o := range opts {
    80  		o.SetOption(r)
    81  	}
    82  	return r
    83  }
    84  
    85  // Extend extends goldmark with our parsers and renderers
    86  func (e *Extension) Extend(m goldmark.Markdown) {
    87  	if !e.enabled {
    88  		return
    89  	}
    90  
    91  	m.Parser().AddOptions(parser.WithBlockParsers(
    92  		util.Prioritized(NewBlockParser(e.parseDollarBlock), 701),
    93  	))
    94  
    95  	inlines := []util.PrioritizedValue{
    96  		util.Prioritized(NewInlineBracketParser(), 501),
    97  	}
    98  	if e.parseDollarInline {
    99  		inlines = append(inlines, util.Prioritized(NewInlineDollarParser(), 501))
   100  	}
   101  	m.Parser().AddOptions(parser.WithInlineParsers(inlines...))
   102  
   103  	m.Renderer().AddOptions(renderer.WithNodeRenderers(
   104  		util.Prioritized(NewBlockRenderer(), 501),
   105  		util.Prioritized(NewInlineRenderer(), 502),
   106  	))
   107  }