namumark.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. package markup
  2. import (
  3. "database/sql"
  4. "log"
  5. "regexp"
  6. "strconv"
  7. "strings"
  8. "github.com/dlclark/regexp2"
  9. )
  10. type namumark struct {
  11. db *sql.DB
  12. data map[string]string
  13. render_data string
  14. }
  15. func Namumark_new(db *sql.DB, data map[string]string) *namumark {
  16. data_string := data["data"]
  17. data_string = "\n" + data_string + "\n"
  18. data_string = strings.ReplaceAll(data_string, "\r", "")
  19. return &namumark{
  20. db,
  21. data,
  22. data_string,
  23. }
  24. }
  25. type replacer struct {
  26. re *regexp2.Regexp
  27. prefix string
  28. }
  29. func (class *namumark) render_text() {
  30. string_data := class.render_data
  31. replacers := []replacer{
  32. { regexp2.MustCompile(`'''((?:(?!''').)+)'''`, 0), "b" },
  33. { regexp2.MustCompile(`''((?:(?!'').)+)''`, 0), "i" },
  34. { regexp2.MustCompile(`__((?:(?!__).)+)__`, 0), "u" },
  35. { regexp2.MustCompile(`\^\^\^((?:(?!\^\^\^).)+)\^\^\^`, 0), "sup" },
  36. { regexp2.MustCompile(`\^\^((?:(?!\^\^).)+)\^\^`, 0), "sup" },
  37. { regexp2.MustCompile(`,,,((?:(?!,,,).)+),,,`, 0), "sub" },
  38. { regexp2.MustCompile(`,,((?:(?!,,).)+),,`, 0), "sub" },
  39. { regexp2.MustCompile(`--((?:(?!--).)+)--`, 0), "s" },
  40. { regexp2.MustCompile(`~~((?:(?!~~).)+)~~`, 0), "s" },
  41. }
  42. for _, rep := range replacers {
  43. for {
  44. m, _ := rep.re.FindStringMatch(string_data)
  45. if m == nil {
  46. break
  47. }
  48. gps := m.Groups()
  49. start := m.Index
  50. end := start + len(m.String())
  51. replacement := "[" + rep.prefix + "(" + gps[1].Captures[0].String() + ")]"
  52. string_data = string_data[:start] + replacement + string_data[end:]
  53. }
  54. }
  55. class.render_data = string_data
  56. }
  57. func (class *namumark) render_heading() {
  58. string_data := class.render_data
  59. r := regexp.MustCompile(`\n(?:(={1,6})(#?) ?([^\n]+))\n`)
  60. r_sub := regexp.MustCompile(` ?(#?={1,6}[^=]*)$`)
  61. string_data = r.ReplaceAllStringFunc(string_data, func(m string) string {
  62. match := r.FindStringSubmatch(m)
  63. heading_data := r_sub.ReplaceAllString(match[3], "")
  64. heading_len := strconv.Itoa(len(match[1]))
  65. heading_render := "[h" + heading_len + "(" + heading_data + ")]"
  66. return heading_render
  67. })
  68. class.render_data = string_data
  69. }
  70. func (class *namumark) render_macro() {
  71. string_data := class.render_data
  72. r := regexp2.MustCompile(`\[([^\[\]\(\)]+)\]`, 0)
  73. string_data, _ = r.ReplaceFunc(
  74. string_data,
  75. func(m regexp2.Match) string {
  76. macro_name := m.GroupByNumber(1).String()
  77. if macro_name == "toc" || macro_name == "목차" {
  78. return "[toc()]"
  79. } else {
  80. return ""
  81. }
  82. },
  83. -1,
  84. -1,
  85. )
  86. class.render_data = string_data
  87. }
  88. func (class *namumark) render_link() {
  89. string_data := class.render_data
  90. r := regexp2.MustCompile(`\[\[((?:(?!\[\[|\]\]|\|).)+)(?:\|((?:(?!\[\[|\]\]).)+))?\]\]`, 0)
  91. string_data, _ = r.ReplaceFunc(
  92. string_data,
  93. func(m regexp2.Match) string {
  94. target := m.GroupByNumber(1).String()
  95. label := m.GroupByNumber(2).String()
  96. if label == "" {
  97. label = target
  98. }
  99. tag_name := "a"
  100. if strings.HasPrefix(target, "http://") || strings.HasPrefix(target, "https://") {
  101. tag_name = "ex"
  102. }
  103. log.Default().Println(tag_name, target)
  104. return "[" + tag_name + "(" + target + "," + label + ")]"
  105. },
  106. -1,
  107. -1,
  108. )
  109. class.render_data = string_data
  110. }
  111. func (class *namumark) render_last() {
  112. string_data := class.render_data
  113. r := regexp.MustCompile(`(\n| )+$`)
  114. string_data = r.ReplaceAllString(string_data, "")
  115. r = regexp.MustCompile(`^(\n| )+`)
  116. string_data = r.ReplaceAllString(string_data, "")
  117. r = regexp.MustCompile(`\n?<front_br>`)
  118. string_data = r.ReplaceAllString(string_data, "")
  119. r = regexp.MustCompile(`<back_br>\n?`)
  120. string_data = r.ReplaceAllString(string_data, "")
  121. class.render_data = string_data
  122. }
  123. func (class *namumark) main() map[string]any {
  124. class.render_text()
  125. class.render_link()
  126. class.render_heading()
  127. class.render_macro()
  128. class.render_last()
  129. log.Default().Println(class.render_data)
  130. class.data["data"] = class.render_data
  131. render_data_class := Macromark_new(class.db, class.data, "html")
  132. render_data := render_data_class.main()
  133. return render_data
  134. }