-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhtml.go
More file actions
120 lines (101 loc) · 3.23 KB
/
html.go
File metadata and controls
120 lines (101 loc) · 3.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package md4c
/*
#cgo LDFLAGS: -lmd4c-html
#include <md4c-html.h>
#include <stdlib.h>
#include <string.h>
// HTML出力を文字列として受け取るための構造体
typedef struct {
char* data;
size_t size;
size_t capacity;
} output_buffer_t;
// 出力バッファを初期化
static output_buffer_t* create_output_buffer() {
output_buffer_t* buf = (output_buffer_t*)malloc(sizeof(output_buffer_t));
buf->capacity = 4096;
buf->size = 0;
buf->data = (char*)malloc(buf->capacity);
return buf;
}
// 出力バッファに追記
static void append_output(const MD_CHAR* text, MD_SIZE size, void* userdata) {
output_buffer_t* buf = (output_buffer_t*)userdata;
// 容量が足りない場合は拡張
while (buf->size + size > buf->capacity) {
buf->capacity *= 2;
buf->data = (char*)realloc(buf->data, buf->capacity);
}
memcpy(buf->data + buf->size, text, size);
buf->size += size;
}
// 出力バッファを解放
static void free_output_buffer(output_buffer_t* buf) {
if (buf) {
if (buf->data) {
free(buf->data);
}
free(buf);
}
}
// ラッパー関数
static int render_html(const MD_CHAR* input, MD_SIZE input_size,
output_buffer_t* buf, unsigned parser_flags, unsigned renderer_flags) {
return md_html(input, input_size, append_output, (void*)buf, parser_flags, renderer_flags);
}
*/
import "C"
import (
"unsafe"
)
// HTML renderer flags
const (
HTMLFlagDebug = C.MD_HTML_FLAG_DEBUG
HTMLFlagVerbatimEntities = C.MD_HTML_FLAG_VERBATIM_ENTITIES
HTMLFlagSkipUTF8BOM = C.MD_HTML_FLAG_SKIP_UTF8_BOM
HTMLFlagXHTML = C.MD_HTML_FLAG_XHTML
)
// HTMLRenderer はマークダウンをHTMLに変換するレンダラー
type HTMLRenderer struct {
parserFlags uint32
rendererFlags uint32
}
// NewHTMLRenderer は新しいHTMLレンダラーを作成
func NewHTMLRenderer(parserFlags uint32, rendererFlags uint32) *HTMLRenderer {
return &HTMLRenderer{
parserFlags: parserFlags,
rendererFlags: rendererFlags,
}
}
// Render はマークダウンをHTMLに変換
func (r *HTMLRenderer) Render(markdown string) (string, error) {
cMarkdown := C.CString(markdown)
defer C.free(unsafe.Pointer(cMarkdown))
// 出力バッファを作成
buf := C.create_output_buffer()
defer C.free_output_buffer(buf)
// HTMLレンダリング(ラッパー関数を使用)
result := C.render_html(
(*C.MD_CHAR)(unsafe.Pointer(cMarkdown)),
C.MD_SIZE(len(markdown)),
buf,
C.uint(r.parserFlags),
C.uint(r.rendererFlags),
)
if result != 0 {
return "", &ParseError{Code: int(result)}
}
// C文字列をGoの文字列に変換
html := C.GoStringN(buf.data, C.int(buf.size))
return html, nil
}
// RenderHTML はマークダウンをHTMLに変換する便利関数
func RenderHTML(markdown string, parserFlags uint32) (string, error) {
renderer := NewHTMLRenderer(parserFlags, 0)
return renderer.Render(markdown)
}
// RenderHTMLWithFlags はパーサーとレンダラーの両方のフラグを指定してHTMLに変換
func RenderHTMLWithFlags(markdown string, parserFlags uint32, rendererFlags uint32) (string, error) {
renderer := NewHTMLRenderer(parserFlags, rendererFlags)
return renderer.Render(markdown)
}