cjk.go

 1package extension
 2
 3import (
 4	"github.com/yuin/goldmark"
 5	"github.com/yuin/goldmark/parser"
 6	"github.com/yuin/goldmark/renderer/html"
 7)
 8
 9// A CJKOption sets options for CJK support mostly for HTML based renderers.
10type CJKOption func(*cjk)
11
12// A EastAsianLineBreaks is a style of east asian line breaks.
13type EastAsianLineBreaks int
14
15const (
16	//EastAsianLineBreaksNone renders line breaks as it is.
17	EastAsianLineBreaksNone EastAsianLineBreaks = iota
18	// EastAsianLineBreaksSimple is a style where soft line breaks are ignored
19	// if both sides of the break are east asian wide characters.
20	EastAsianLineBreaksSimple
21	// EastAsianLineBreaksCSS3Draft is a style where soft line breaks are ignored
22	// even if only one side of the break is an east asian wide character.
23	EastAsianLineBreaksCSS3Draft
24)
25
26// WithEastAsianLineBreaks is a functional option that indicates whether softline breaks
27// between east asian wide characters should be ignored.
28// style defauts to [EastAsianLineBreaksSimple] .
29func WithEastAsianLineBreaks(style ...EastAsianLineBreaks) CJKOption {
30	return func(c *cjk) {
31		if len(style) == 0 {
32			c.EastAsianLineBreaks = EastAsianLineBreaksSimple
33			return
34		}
35		c.EastAsianLineBreaks = style[0]
36	}
37}
38
39// WithEscapedSpace is a functional option that indicates that a '\' escaped half-space(0x20) should not be rendered.
40func WithEscapedSpace() CJKOption {
41	return func(c *cjk) {
42		c.EscapedSpace = true
43	}
44}
45
46type cjk struct {
47	EastAsianLineBreaks EastAsianLineBreaks
48	EscapedSpace        bool
49}
50
51// CJK is a goldmark extension that provides functionalities for CJK languages.
52var CJK = NewCJK(WithEastAsianLineBreaks(), WithEscapedSpace())
53
54// NewCJK returns a new extension with given options.
55func NewCJK(opts ...CJKOption) goldmark.Extender {
56	e := &cjk{
57		EastAsianLineBreaks: EastAsianLineBreaksNone,
58	}
59	for _, opt := range opts {
60		opt(e)
61	}
62	return e
63}
64
65func (e *cjk) Extend(m goldmark.Markdown) {
66	m.Renderer().AddOptions(html.WithEastAsianLineBreaks(
67		html.EastAsianLineBreaks(e.EastAsianLineBreaks)))
68	if e.EscapedSpace {
69		m.Renderer().AddOptions(html.WithWriter(html.NewWriter(html.WithEscapedSpace())))
70		m.Parser().AddOptions(parser.WithEscapedSpace())
71	}
72}