Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
canifa_note
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vũ Hoàng Anh
canifa_note
Commits
242f64fa
Commit
242f64fa
authored
Dec 14, 2023
by
Steven
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: implement html render
parent
3edce174
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
264 additions
and
277 deletions
+264
-277
.golangci.yaml
.golangci.yaml
+4
-0
block.go
plugin/gomark/ast/block.go
+6
-56
inline.go
plugin/gomark/ast/inline.go
+9
-63
node.go
plugin/gomark/ast/node.go
+29
-25
parser.go
plugin/gomark/parser/parser.go
+1
-1
parser_test.go
plugin/gomark/parser/parser_test.go
+37
-1
tokenizer.go
plugin/gomark/parser/tokenizer/tokenizer.go
+4
-4
html.go
plugin/gomark/render/html/html.go
+171
-0
html_test.go
plugin/gomark/render/html/html_test.go
+2
-2
renderer.go
plugin/gomark/render/renderer.go
+1
-0
html.go
plugin/gomark/renderer/html/html.go
+0
-124
renderer.go
plugin/gomark/renderer/renderer.go
+0
-1
No files found.
.golangci.yaml
View file @
242f64fa
...
...
@@ -69,6 +69,10 @@ linters-settings:
disabled
:
true
-
name
:
use-any
disabled
:
true
-
name
:
exported
disabled
:
true
-
name
:
unhandled-error
disabled
:
true
gocritic
:
disabled-checks
:
-
ifElseChain
...
...
plugin/gomark/ast/block.go
View file @
242f64fa
package
ast
import
"fmt"
type
BaseBlock
struct
{
BaseNode
}
...
...
@@ -10,14 +8,8 @@ type LineBreak struct {
BaseBlock
}
var
NodeTypeLineBreak
=
NewNodeType
(
"LineBreak"
)
func
(
*
LineBreak
)
Type
()
NodeType
{
return
NodeTypeLineBreak
}
func
(
n
*
LineBreak
)
String
()
string
{
return
n
.
Type
()
.
String
()
return
LineBreakNode
}
type
Paragraph
struct
{
...
...
@@ -26,18 +18,8 @@ type Paragraph struct {
Children
[]
Node
}
var
NodeTypeParagraph
=
NewNodeType
(
"Paragraph"
)
func
(
*
Paragraph
)
Type
()
NodeType
{
return
NodeTypeParagraph
}
func
(
n
*
Paragraph
)
String
()
string
{
str
:=
n
.
Type
()
.
String
()
for
_
,
child
:=
range
n
.
Children
{
str
+=
" "
+
child
.
String
()
}
return
str
return
ParagraphNode
}
type
CodeBlock
struct
{
...
...
@@ -47,14 +29,8 @@ type CodeBlock struct {
Content
string
}
var
NodeTypeCodeBlock
=
NewNodeType
(
"CodeBlock"
)
func
(
*
CodeBlock
)
Type
()
NodeType
{
return
NodeTypeCodeBlock
}
func
(
n
*
CodeBlock
)
String
()
string
{
return
n
.
Type
()
.
String
()
+
" "
+
n
.
Language
+
" "
+
n
.
Content
return
CodeBlockNode
}
type
Heading
struct
{
...
...
@@ -64,18 +40,8 @@ type Heading struct {
Children
[]
Node
}
var
NodeTypeHeading
=
NewNodeType
(
"Heading"
)
func
(
*
Heading
)
Type
()
NodeType
{
return
NodeTypeHeading
}
func
(
n
*
Heading
)
String
()
string
{
str
:=
n
.
Type
()
.
String
()
+
" "
+
fmt
.
Sprintf
(
"%d"
,
n
.
Level
)
for
_
,
child
:=
range
n
.
Children
{
str
+=
" "
+
child
.
String
()
}
return
str
return
HeadingNode
}
type
HorizontalRule
struct
{
...
...
@@ -85,14 +51,8 @@ type HorizontalRule struct {
Symbol
string
}
var
NodeTypeHorizontalRule
=
NewNodeType
(
"HorizontalRule"
)
func
(
*
HorizontalRule
)
Type
()
NodeType
{
return
NodeTypeHorizontalRule
}
func
(
n
*
HorizontalRule
)
String
()
string
{
return
n
.
Type
()
.
String
()
return
HorizontalRuleNode
}
type
Blockquote
struct
{
...
...
@@ -101,16 +61,6 @@ type Blockquote struct {
Children
[]
Node
}
var
NodeTypeBlockquote
=
NewNodeType
(
"Blockquote"
)
func
(
*
Blockquote
)
Type
()
NodeType
{
return
NodeTypeBlockquote
}
func
(
n
*
Blockquote
)
String
()
string
{
str
:=
n
.
Type
()
.
String
()
for
_
,
child
:=
range
n
.
Children
{
str
+=
" "
+
child
.
String
()
}
return
str
return
BlockquoteNode
}
plugin/gomark/ast/inline.go
View file @
242f64fa
...
...
@@ -10,14 +10,8 @@ type Text struct {
Content
string
}
var
NodeTypeText
=
NewNodeType
(
"Text"
)
func
(
*
Text
)
Type
()
NodeType
{
return
NodeTypeText
}
func
(
n
*
Text
)
String
()
string
{
return
n
.
Type
()
.
String
()
+
" "
+
n
.
Content
return
TextNode
}
type
Bold
struct
{
...
...
@@ -28,14 +22,8 @@ type Bold struct {
Content
string
}
var
NodeTypeBold
=
NewNodeType
(
"Bold"
)
func
(
*
Bold
)
Type
()
NodeType
{
return
NodeTypeBold
}
func
(
n
*
Bold
)
String
()
string
{
return
n
.
Type
()
.
String
()
+
" "
+
n
.
Symbol
+
" "
+
n
.
Content
return
BoldNode
}
type
Italic
struct
{
...
...
@@ -46,14 +34,8 @@ type Italic struct {
Content
string
}
var
NodeTypeItalic
=
NewNodeType
(
"Italic"
)
func
(
*
Italic
)
Type
()
NodeType
{
return
NodeTypeItalic
}
func
(
n
*
Italic
)
String
()
string
{
return
n
.
Type
()
.
String
()
+
" "
+
n
.
Symbol
+
" "
+
n
.
Content
return
ItalicNode
}
type
BoldItalic
struct
{
...
...
@@ -64,14 +46,8 @@ type BoldItalic struct {
Content
string
}
var
NodeTypeBoldItalic
=
NewNodeType
(
"BoldItalic"
)
func
(
*
BoldItalic
)
Type
()
NodeType
{
return
NodeTypeBoldItalic
}
func
(
n
*
BoldItalic
)
String
()
string
{
return
n
.
Type
()
.
String
()
+
" "
+
n
.
Symbol
+
" "
+
n
.
Content
return
BoldItalicNode
}
type
Code
struct
{
...
...
@@ -80,14 +56,8 @@ type Code struct {
Content
string
}
var
NodeTypeCode
=
NewNodeType
(
"Code"
)
func
(
*
Code
)
Type
()
NodeType
{
return
NodeTypeCode
}
func
(
n
*
Code
)
String
()
string
{
return
n
.
Type
()
.
String
()
+
" "
+
n
.
Content
return
CodeNode
}
type
Image
struct
{
...
...
@@ -97,14 +67,8 @@ type Image struct {
URL
string
}
var
NodeTypeImage
=
NewNodeType
(
"Image"
)
func
(
*
Image
)
Type
()
NodeType
{
return
NodeTypeImage
}
func
(
n
*
Image
)
String
()
string
{
return
n
.
Type
()
.
String
()
+
" "
+
n
.
AltText
+
" "
+
n
.
URL
return
ImageNode
}
type
Link
struct
{
...
...
@@ -114,14 +78,8 @@ type Link struct {
URL
string
}
var
NodeTypeLink
=
NewNodeType
(
"Link"
)
func
(
*
Link
)
Type
()
NodeType
{
return
NodeTypeLink
}
func
(
n
*
Link
)
String
()
string
{
return
n
.
Type
()
.
String
()
+
" "
+
n
.
Text
+
" "
+
n
.
URL
return
LinkNode
}
type
Tag
struct
{
...
...
@@ -130,14 +88,8 @@ type Tag struct {
Content
string
}
var
NodeTypeTag
=
NewNodeType
(
"Tag"
)
func
(
*
Tag
)
Type
()
NodeType
{
return
NodeTypeTag
}
func
(
n
*
Tag
)
String
()
string
{
return
n
.
Type
()
.
String
()
+
" "
+
n
.
Content
return
TagNode
}
type
Strikethrough
struct
{
...
...
@@ -146,12 +98,6 @@ type Strikethrough struct {
Content
string
}
var
NodeTypeStrikethrough
=
NewNodeType
(
"Strikethrough"
)
func
(
*
Strikethrough
)
Type
()
NodeType
{
return
NodeTypeStrikethrough
}
func
(
n
*
Strikethrough
)
String
()
string
{
return
n
.
Type
()
.
String
()
+
" "
+
n
.
Content
return
StrikethroughNode
}
plugin/gomark/ast/node.go
View file @
242f64fa
package
ast
type
NodeType
uint32
const
(
UnknownNode
NodeType
=
iota
// Block nodes.
LineBreakNode
ParagraphNode
CodeBlockNode
HeadingNode
HorizontalRuleNode
BlockquoteNode
// Inline nodes.
TextNode
BoldNode
ItalicNode
BoldItalicNode
CodeNode
ImageNode
LinkNode
TagNode
StrikethroughNode
)
type
Node
interface
{
// Type returns a node type.
Type
()
NodeType
// String returns a string representation of this node.
// This method is used for debugging.
String
()
string
// GetPrevSibling returns a previous sibling node of this node.
GetPrevSibling
()
Node
// PrevSibling returns a previous sibling node of this node.
PrevSibling
()
Node
//
Get
NextSibling returns a next sibling node of this node.
Get
NextSibling
()
Node
// NextSibling returns a next sibling node of this node.
NextSibling
()
Node
// SetPrevSibling sets a previous sibling node to this node.
SetPrevSibling
(
Node
)
...
...
@@ -21,32 +40,17 @@ type Node interface {
SetNextSibling
(
Node
)
}
type
NodeType
int
func
(
t
NodeType
)
String
()
string
{
return
nodeTypeNames
[
t
]
}
var
nodeTypeIndex
NodeType
var
nodeTypeNames
=
[]
string
{
""
}
func
NewNodeType
(
name
string
)
NodeType
{
nodeTypeNames
=
append
(
nodeTypeNames
,
name
)
nodeTypeIndex
++
return
nodeTypeIndex
}
type
BaseNode
struct
{
prevSibling
Node
nextSibling
Node
}
func
(
n
*
BaseNode
)
Get
PrevSibling
()
Node
{
func
(
n
*
BaseNode
)
PrevSibling
()
Node
{
return
n
.
prevSibling
}
func
(
n
*
BaseNode
)
Get
NextSibling
()
Node
{
func
(
n
*
BaseNode
)
NextSibling
()
Node
{
return
n
.
nextSibling
}
...
...
plugin/gomark/parser/parser.go
View file @
242f64fa
...
...
@@ -88,7 +88,7 @@ func ParseInline(tokens []*tokenizer.Token) ([]ast.Node, error) {
tokens
=
tokens
[
size
:
]
if
prevNode
!=
nil
{
// Merge text nodes if possible.
if
prevNode
.
Type
()
==
ast
.
NodeTypeText
&&
node
.
Type
()
==
ast
.
NodeTypeText
{
if
prevNode
.
Type
()
==
ast
.
TextNode
&&
node
.
Type
()
==
ast
.
TextNode
{
prevNode
.
(
*
ast
.
Text
)
.
Content
+=
node
.
(
*
ast
.
Text
)
.
Content
break
}
...
...
plugin/gomark/parser/parser_test.go
View file @
242f64fa
...
...
@@ -127,8 +127,44 @@ func StringifyNodes(nodes []ast.Node) string {
var
result
string
for
_
,
node
:=
range
nodes
{
if
node
!=
nil
{
result
+=
node
.
String
(
)
result
+=
StringifyNode
(
node
)
}
}
return
result
}
func
StringifyNode
(
node
ast
.
Node
)
string
{
switch
n
:=
node
.
(
type
)
{
case
*
ast
.
LineBreak
:
return
"LineBreak()"
case
*
ast
.
CodeBlock
:
return
"CodeBlock("
+
n
.
Language
+
", "
+
n
.
Content
+
")"
case
*
ast
.
Paragraph
:
return
"Paragraph("
+
StringifyNodes
(
n
.
Children
)
+
")"
case
*
ast
.
Heading
:
return
"Heading("
+
StringifyNodes
(
n
.
Children
)
+
")"
case
*
ast
.
HorizontalRule
:
return
"HorizontalRule("
+
n
.
Symbol
+
")"
case
*
ast
.
Blockquote
:
return
"Blockquote("
+
StringifyNodes
(
n
.
Children
)
+
")"
case
*
ast
.
Text
:
return
"Text("
+
n
.
Content
+
")"
case
*
ast
.
Bold
:
return
"Bold("
+
n
.
Symbol
+
n
.
Content
+
n
.
Symbol
+
")"
case
*
ast
.
Italic
:
return
"Italic("
+
n
.
Symbol
+
n
.
Content
+
n
.
Symbol
+
")"
case
*
ast
.
BoldItalic
:
return
"BoldItalic("
+
n
.
Symbol
+
n
.
Content
+
n
.
Symbol
+
")"
case
*
ast
.
Code
:
return
"Code("
+
n
.
Content
+
")"
case
*
ast
.
Image
:
return
"Image("
+
n
.
URL
+
", "
+
n
.
AltText
+
")"
case
*
ast
.
Link
:
return
"Link("
+
n
.
Text
+
", "
+
n
.
URL
+
")"
case
*
ast
.
Tag
:
return
"Tag("
+
n
.
Content
+
")"
case
*
ast
.
Strikethrough
:
return
"Strikethrough("
+
n
.
Content
+
")"
}
return
""
}
plugin/gomark/parser/tokenizer/tokenizer.go
View file @
242f64fa
...
...
@@ -68,14 +68,14 @@ func Tokenize(text string) []*Token {
case
' '
:
tokens
=
append
(
tokens
,
NewToken
(
Space
,
" "
))
default
:
var
last
Token
*
Token
var
prev
Token
*
Token
if
len
(
tokens
)
>
0
{
last
Token
=
tokens
[
len
(
tokens
)
-
1
]
prev
Token
=
tokens
[
len
(
tokens
)
-
1
]
}
if
lastToken
==
nil
||
last
Token
.
Type
!=
Text
{
if
prevToken
==
nil
||
prev
Token
.
Type
!=
Text
{
tokens
=
append
(
tokens
,
NewToken
(
Text
,
string
(
c
)))
}
else
{
last
Token
.
Value
+=
string
(
c
)
prev
Token
.
Value
+=
string
(
c
)
}
}
}
...
...
plugin/gomark/render/html/html.go
0 → 100644
View file @
242f64fa
package
html
import
(
"bytes"
"fmt"
"github.com/usememos/memos/plugin/gomark/ast"
)
// HTMLRender is a simple renderer that converts AST to HTML.
type
HTMLRender
struct
{
output
*
bytes
.
Buffer
context
*
RendererContext
}
type
RendererContext
struct
{
}
// NewHTMLRender creates a new HTMLRender.
func
NewHTMLRender
()
*
HTMLRender
{
return
&
HTMLRender
{
output
:
new
(
bytes
.
Buffer
),
context
:
&
RendererContext
{},
}
}
// RenderNode renders a single AST node to HTML.
func
(
r
*
HTMLRender
)
RenderNode
(
node
ast
.
Node
)
{
switch
n
:=
node
.
(
type
)
{
case
*
ast
.
LineBreak
:
r
.
renderLineBreak
(
n
)
case
*
ast
.
Paragraph
:
r
.
renderParagraph
(
n
)
case
*
ast
.
CodeBlock
:
r
.
renderCodeBlock
(
n
)
case
*
ast
.
Heading
:
r
.
renderHeading
(
n
)
case
*
ast
.
HorizontalRule
:
r
.
renderHorizontalRule
(
n
)
case
*
ast
.
Blockquote
:
r
.
renderBlockquote
(
n
)
case
*
ast
.
Bold
:
r
.
renderBold
(
n
)
case
*
ast
.
Italic
:
r
.
renderItalic
(
n
)
case
*
ast
.
BoldItalic
:
r
.
renderBoldItalic
(
n
)
case
*
ast
.
Code
:
r
.
renderCode
(
n
)
case
*
ast
.
Image
:
r
.
renderImage
(
n
)
case
*
ast
.
Link
:
r
.
renderLink
(
n
)
case
*
ast
.
Tag
:
r
.
renderTag
(
n
)
case
*
ast
.
Strikethrough
:
r
.
renderStrikethrough
(
n
)
case
*
ast
.
Text
:
r
.
renderText
(
n
)
default
:
// Handle other block types if needed.
}
}
// RenderNodes renders a slice of AST nodes to HTML.
func
(
r
*
HTMLRender
)
RenderNodes
(
nodes
[]
ast
.
Node
)
{
for
_
,
node
:=
range
nodes
{
r
.
RenderNode
(
node
)
}
}
// Render renders the AST to HTML.
func
(
r
*
HTMLRender
)
Render
(
astRoot
[]
ast
.
Node
)
string
{
r
.
RenderNodes
(
astRoot
)
return
r
.
output
.
String
()
}
func
(
r
*
HTMLRender
)
renderLineBreak
(
_
*
ast
.
LineBreak
)
{
r
.
output
.
WriteString
(
"<br>"
)
}
func
(
r
*
HTMLRender
)
renderParagraph
(
node
*
ast
.
Paragraph
)
{
r
.
output
.
WriteString
(
"<p>"
)
r
.
RenderNodes
(
node
.
Children
)
r
.
output
.
WriteString
(
"</p>"
)
}
func
(
r
*
HTMLRender
)
renderCodeBlock
(
node
*
ast
.
CodeBlock
)
{
r
.
output
.
WriteString
(
"<pre><code>"
)
r
.
output
.
WriteString
(
node
.
Content
)
r
.
output
.
WriteString
(
"</code></pre>"
)
}
func
(
r
*
HTMLRender
)
renderHeading
(
node
*
ast
.
Heading
)
{
element
:=
fmt
.
Sprintf
(
"<h%d>"
,
node
.
Level
)
r
.
output
.
WriteString
(
fmt
.
Sprintf
(
"<%s>"
,
element
))
r
.
RenderNodes
(
node
.
Children
)
r
.
output
.
WriteString
(
fmt
.
Sprintf
(
"</%s>"
,
element
))
}
func
(
r
*
HTMLRender
)
renderHorizontalRule
(
_
*
ast
.
HorizontalRule
)
{
r
.
output
.
WriteString
(
"<hr>"
)
}
func
(
r
*
HTMLRender
)
renderBlockquote
(
node
*
ast
.
Blockquote
)
{
prevSibling
,
nextSibling
:=
node
.
PrevSibling
(),
node
.
NextSibling
()
if
prevSibling
==
nil
||
prevSibling
.
Type
()
!=
ast
.
BlockquoteNode
{
r
.
output
.
WriteString
(
"<blockquote>"
)
}
r
.
RenderNodes
(
node
.
Children
)
if
nextSibling
==
nil
||
nextSibling
.
Type
()
!=
ast
.
BlockquoteNode
{
r
.
output
.
WriteString
(
"</blockquote>"
)
}
}
func
(
r
*
HTMLRender
)
renderText
(
node
*
ast
.
Text
)
{
r
.
output
.
WriteString
(
node
.
Content
)
}
func
(
r
*
HTMLRender
)
renderBold
(
node
*
ast
.
Bold
)
{
r
.
output
.
WriteString
(
"<strong>"
)
r
.
output
.
WriteString
(
node
.
Content
)
r
.
output
.
WriteString
(
"</strong>"
)
}
func
(
r
*
HTMLRender
)
renderItalic
(
node
*
ast
.
Italic
)
{
r
.
output
.
WriteString
(
"<em>"
)
r
.
output
.
WriteString
(
node
.
Content
)
r
.
output
.
WriteString
(
"</em>"
)
}
func
(
r
*
HTMLRender
)
renderBoldItalic
(
node
*
ast
.
BoldItalic
)
{
r
.
output
.
WriteString
(
"<strong><em>"
)
r
.
output
.
WriteString
(
node
.
Content
)
r
.
output
.
WriteString
(
"</em></strong>"
)
}
func
(
r
*
HTMLRender
)
renderCode
(
node
*
ast
.
Code
)
{
r
.
output
.
WriteString
(
"<code>"
)
r
.
output
.
WriteString
(
node
.
Content
)
r
.
output
.
WriteString
(
"</code>"
)
}
func
(
r
*
HTMLRender
)
renderImage
(
node
*
ast
.
Image
)
{
r
.
output
.
WriteString
(
`<img src="`
)
r
.
output
.
WriteString
(
node
.
URL
)
r
.
output
.
WriteString
(
`" alt="`
)
r
.
output
.
WriteString
(
node
.
AltText
)
r
.
output
.
WriteString
(
`" />`
)
}
func
(
r
*
HTMLRender
)
renderLink
(
node
*
ast
.
Link
)
{
r
.
output
.
WriteString
(
`<a href="`
)
r
.
output
.
WriteString
(
node
.
URL
)
r
.
output
.
WriteString
(
`">`
)
r
.
output
.
WriteString
(
node
.
Text
)
r
.
output
.
WriteString
(
"</a>"
)
}
func
(
r
*
HTMLRender
)
renderTag
(
node
*
ast
.
Tag
)
{
r
.
output
.
WriteString
(
`<span>`
)
r
.
output
.
WriteString
(
`# `
)
r
.
output
.
WriteString
(
node
.
Content
)
r
.
output
.
WriteString
(
`</span>`
)
}
func
(
r
*
HTMLRender
)
renderStrikethrough
(
node
*
ast
.
Strikethrough
)
{
r
.
output
.
WriteString
(
`<del>`
)
r
.
output
.
WriteString
(
node
.
Content
)
r
.
output
.
WriteString
(
`</del>`
)
}
plugin/gomark/render
er
/html/html_test.go
→
plugin/gomark/render/html/html_test.go
View file @
242f64fa
...
...
@@ -9,7 +9,7 @@ import (
"github.com/usememos/memos/plugin/gomark/parser/tokenizer"
)
func
TestHTMLRender
er
(
t
*
testing
.
T
)
{
func
TestHTMLRender
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
text
string
expected
string
...
...
@@ -36,7 +36,7 @@ func TestHTMLRenderer(t *testing.T) {
tokens
:=
tokenizer
.
Tokenize
(
test
.
text
)
nodes
,
err
:=
parser
.
Parse
(
tokens
)
require
.
NoError
(
t
,
err
)
actual
:=
NewHTMLRender
er
()
.
Render
(
nodes
)
actual
:=
NewHTMLRender
()
.
Render
(
nodes
)
require
.
Equal
(
t
,
test
.
expected
,
actual
)
}
}
plugin/gomark/render/renderer.go
0 → 100644
View file @
242f64fa
package
render
plugin/gomark/renderer/html/html.go
deleted
100644 → 0
View file @
3edce174
package
html
import
(
"bytes"
"fmt"
"github.com/usememos/memos/plugin/gomark/ast"
)
// HTMLRenderer is a simple renderer that converts AST to HTML.
// nolint
type
HTMLRenderer
struct
{
output
*
bytes
.
Buffer
context
*
RendererContext
}
type
RendererContext
struct
{
}
// NewHTMLRenderer creates a new HTMLRenderer.
func
NewHTMLRenderer
()
*
HTMLRenderer
{
return
&
HTMLRenderer
{
output
:
new
(
bytes
.
Buffer
),
context
:
&
RendererContext
{},
}
}
// RenderNode renders a single AST node to HTML.
func
(
r
*
HTMLRenderer
)
RenderNode
(
node
ast
.
Node
)
{
prevSibling
,
nextSibling
:=
node
.
GetPrevSibling
(),
node
.
GetNextSibling
()
switch
n
:=
node
.
(
type
)
{
case
*
ast
.
LineBreak
:
r
.
output
.
WriteString
(
"<br>"
)
case
*
ast
.
Paragraph
:
r
.
output
.
WriteString
(
"<p>"
)
r
.
RenderNodes
(
n
.
Children
)
r
.
output
.
WriteString
(
"</p>"
)
case
*
ast
.
CodeBlock
:
r
.
output
.
WriteString
(
"<pre><code>"
)
r
.
output
.
WriteString
(
n
.
Content
)
r
.
output
.
WriteString
(
"</code></pre>"
)
case
*
ast
.
Heading
:
r
.
output
.
WriteString
(
fmt
.
Sprintf
(
"<h%d>"
,
n
.
Level
))
r
.
RenderNodes
(
n
.
Children
)
r
.
output
.
WriteString
(
fmt
.
Sprintf
(
"</h%d>"
,
n
.
Level
))
case
*
ast
.
HorizontalRule
:
r
.
output
.
WriteString
(
"<hr>"
)
case
*
ast
.
Blockquote
:
if
prevSibling
==
nil
||
prevSibling
.
Type
()
!=
ast
.
NodeTypeBlockquote
{
r
.
output
.
WriteString
(
"<blockquote>"
)
}
r
.
RenderNodes
(
n
.
Children
)
if
nextSibling
!=
nil
&&
nextSibling
.
Type
()
==
ast
.
NodeTypeBlockquote
{
r
.
RenderNode
(
nextSibling
)
}
if
prevSibling
==
nil
||
prevSibling
.
Type
()
!=
ast
.
NodeTypeBlockquote
{
r
.
output
.
WriteString
(
"</blockquote>"
)
}
case
*
ast
.
BoldItalic
:
r
.
output
.
WriteString
(
"<strong><em>"
)
r
.
output
.
WriteString
(
n
.
Content
)
r
.
output
.
WriteString
(
"</em></strong>"
)
case
*
ast
.
Bold
:
r
.
output
.
WriteString
(
"<strong>"
)
r
.
output
.
WriteString
(
n
.
Content
)
r
.
output
.
WriteString
(
"</strong>"
)
case
*
ast
.
Italic
:
r
.
output
.
WriteString
(
"<em>"
)
r
.
output
.
WriteString
(
n
.
Content
)
r
.
output
.
WriteString
(
"</em>"
)
case
*
ast
.
Code
:
r
.
output
.
WriteString
(
"<code>"
)
r
.
output
.
WriteString
(
n
.
Content
)
r
.
output
.
WriteString
(
"</code>"
)
case
*
ast
.
Link
:
r
.
output
.
WriteString
(
`<a href="`
)
r
.
output
.
WriteString
(
n
.
URL
)
r
.
output
.
WriteString
(
`">`
)
r
.
output
.
WriteString
(
n
.
Text
)
r
.
output
.
WriteString
(
"</a>"
)
case
*
ast
.
Image
:
r
.
output
.
WriteString
(
`<img src="`
)
r
.
output
.
WriteString
(
n
.
URL
)
r
.
output
.
WriteString
(
`" alt="`
)
r
.
output
.
WriteString
(
n
.
AltText
)
r
.
output
.
WriteString
(
`" />`
)
case
*
ast
.
Tag
:
r
.
output
.
WriteString
(
`<span>`
)
r
.
output
.
WriteString
(
`# `
)
r
.
output
.
WriteString
(
n
.
Content
)
r
.
output
.
WriteString
(
`</span>`
)
case
*
ast
.
Strikethrough
:
r
.
output
.
WriteString
(
`<del>`
)
r
.
output
.
WriteString
(
n
.
Content
)
r
.
output
.
WriteString
(
`</del>`
)
case
*
ast
.
Text
:
r
.
output
.
WriteString
(
n
.
Content
)
default
:
// Handle other block types if needed.
}
}
// RenderNodes renders a slice of AST nodes to HTML.
func
(
r
*
HTMLRenderer
)
RenderNodes
(
nodes
[]
ast
.
Node
)
{
for
_
,
node
:=
range
nodes
{
prevSibling
:=
node
.
GetPrevSibling
()
if
prevSibling
!=
nil
{
if
prevSibling
.
Type
()
==
node
.
Type
()
{
if
node
.
Type
()
==
ast
.
NodeTypeBlockquote
{
continue
}
}
}
r
.
RenderNode
(
node
)
}
}
// Render renders the AST to HTML.
func
(
r
*
HTMLRenderer
)
Render
(
astRoot
[]
ast
.
Node
)
string
{
r
.
RenderNodes
(
astRoot
)
return
r
.
output
.
String
()
}
plugin/gomark/renderer/renderer.go
deleted
100644 → 0
View file @
3edce174
package
renderer
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment