Просмотр исходного кода

added the markdown conversion!

AETH-erial 6 месяцев назад
Родитель
Сommit
5624c55527
5 измененных файлов с 83 добавлено и 62 удалено
  1. 1 0
      go.mod
  2. 2 0
      go.sum
  3. 8 7
      pkg/controller/admin_handlers.go
  4. 16 17
      pkg/controller/html_handlers.go
  5. 56 38
      pkg/helpers/helpers.go

+ 1 - 0
go.mod

@@ -23,6 +23,7 @@ require (
 	github.com/go-playground/universal-translator v0.18.1 // indirect
 	github.com/go-playground/validator/v10 v10.17.0 // indirect
 	github.com/goccy/go-json v0.10.2 // indirect
+	github.com/gomarkdown/markdown v0.0.0-20240328165702-4d01890c35c0 // indirect
 	github.com/google/uuid v1.6.0 // indirect
 	github.com/joho/godotenv v1.5.1 // indirect
 	github.com/josharian/intern v1.0.0 // indirect

+ 2 - 0
go.sum

@@ -55,6 +55,8 @@ github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGF
 github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
 github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
 github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/gomarkdown/markdown v0.0.0-20240328165702-4d01890c35c0 h1:4gjrh/PN2MuWCCElk8/I4OCKRKWCCo2zEct3VKCbibU=
+github.com/gomarkdown/markdown v0.0.0-20240328165702-4d01890c35c0/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA=
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=

+ 8 - 7
pkg/controller/admin_handlers.go

@@ -19,15 +19,16 @@ func (c *Controller) AddDocument(ctx *gin.Context) {
 
 	var upload helpers.DocumentUpload
 
-	err := ctx.BindJSON(&upload); if err != nil {
+	err := ctx.BindJSON(&upload)
+	if err != nil {
 		ctx.JSON(400, map[string]string{
 			"Error": err.Error(),
 		})
 		return
 	}
-
-	doc := helpers.NewDocument(upload.Name, nil, upload.Text, upload.Category)
-	err = helpers.AddDocument(doc, c.RedisConfig); if err != nil {
+	newPost := helpers.NewDocument(upload.Name, nil, upload.Text, upload.Category)
+	err = helpers.AddDocument(newPost, c.RedisConfig)
+	if err != nil {
 		ctx.JSON(400, map[string]string{
 			"Error": err.Error(),
 		})
@@ -60,7 +61,8 @@ func (c *Controller) Auth(ctx *gin.Context) {
 
 	var cred helpers.Credentials
 
-	err := ctx.ShouldBind(&cred); if err != nil {
+	err := ctx.ShouldBind(&cred)
+	if err != nil {
 		ctx.JSON(400, map[string]string{
 			"Error": err.Error(),
 		})
@@ -78,7 +80,6 @@ func (c *Controller) Auth(ctx *gin.Context) {
 
 }
 
-
 // @Name AdminPanel
 // @Summary serve the admin panel page
 // @Tags admin
@@ -88,7 +89,7 @@ func (c *Controller) AdminPanel(ctx *gin.Context) {
 	ctx.HTML(http.StatusOK, "admin", gin.H{
 		"navigation": gin.H{
 			"headers": c.Headers().Elements,
-			"menu": c.Menu(),
+			"menu":    c.Menu(),
 		},
 		"Tables": c.AdminTables().Tables,
 	})

+ 16 - 17
pkg/controller/html_handlers.go

@@ -1,6 +1,7 @@
 package controller
 
 import (
+	"html/template"
 	"net/http"
 
 	"git.aetherial.dev/aeth/keiji/pkg/helpers"
@@ -33,14 +34,13 @@ func (c *Controller) ServePost(ctx *gin.Context) {
 	}
 	ctx.HTML(http.StatusOK, "blogpost", gin.H{
 		"navigation": gin.H{
-			"menu": c.Menu(),
+			"menu":    c.Menu(),
 			"headers": c.Headers().Elements,
 		},
-		"title": doc.Ident,
-		"Ident": doc.Ident,
+		"title":   doc.Ident,
+		"Ident":   doc.Ident,
 		"Created": doc.Created,
-		"Body": doc.Body,
-
+		"Body":    template.HTML(helpers.MdToHTML([]byte(doc.Body))),
 	})
 
 }
@@ -59,14 +59,13 @@ func (c *Controller) ServeBlogHome(ctx *gin.Context) {
 	}
 	ctx.HTML(http.StatusOK, "home", gin.H{
 		"navigation": gin.H{
-			"menu": c.Menu(),
+			"menu":    c.Menu(),
 			"headers": c.Headers().Elements,
 		},
 		"listings": docs,
 	})
 }
 
-
 // @Name ServeHtml
 // @Summary serves HTML files out of the HTML directory
 // @Tags webpages
@@ -81,7 +80,7 @@ func (c *Controller) ServeHome(ctx *gin.Context) {
 	}
 	ctx.HTML(http.StatusOK, "home", gin.H{
 		"navigation": gin.H{
-			"menu": c.Menu(),
+			"menu":    c.Menu(),
 			"headers": c.Headers().Elements,
 		},
 		"listings": docs,
@@ -102,7 +101,7 @@ func (c *Controller) ServeCreativeWriting(ctx *gin.Context) {
 	}
 	ctx.HTML(http.StatusOK, "home", gin.H{
 		"navigation": gin.H{
-			"menu": c.Menu(),
+			"menu":    c.Menu(),
 			"headers": c.Headers().Elements,
 		},
 		"listings": docs,
@@ -124,7 +123,7 @@ func (c *Controller) ServeTechnicalWriteups(ctx *gin.Context) {
 	}
 	ctx.HTML(http.StatusOK, "home", gin.H{
 		"navigation": gin.H{
-			"menu": c.Menu(),
+			"menu":    c.Menu(),
 			"headers": c.Headers().Elements,
 		},
 		"listings": docs,
@@ -141,16 +140,16 @@ func (c *Controller) ServeDigitalArt(ctx *gin.Context) {
 	fnames, err := helpers.GetImageData(rds)
 	if err != nil {
 		ctx.HTML(http.StatusInternalServerError, "unhandled_error",
-		gin.H{
-			"StatusCode": http.StatusInternalServerError,
-			"Reason": err.Error(),
-		},
-	)
-	return
+			gin.H{
+				"StatusCode": http.StatusInternalServerError,
+				"Reason":     err.Error(),
+			},
+		)
+		return
 	}
 	ctx.HTML(http.StatusOK, "digital_art", gin.H{
 		"navigation": gin.H{
-			"menu": c.Menu(),
+			"menu":    c.Menu(),
 			"headers": c.Headers().Elements,
 		},
 		"images": fnames,

+ 56 - 38
pkg/helpers/helpers.go

@@ -6,6 +6,9 @@ import (
 	"strings"
 	"time"
 
+	"github.com/gomarkdown/markdown"
+	"github.com/gomarkdown/markdown/html"
+	"github.com/gomarkdown/markdown/parser"
 	"github.com/redis/go-redis/v9"
 )
 
@@ -27,83 +30,81 @@ var Topics = []string{
 
 var TopicMap = map[string]string{
 	TECHNICAL: TECHNICAL,
-	BLOG: BLOG,
-	CREATIVE: CREATIVE,
+	BLOG:      BLOG,
+	CREATIVE:  CREATIVE,
 }
 
 type HeaderCollection struct {
-	Category	string		`json:"category"`
-	Elements	[]HeaderElem	`json:"elements"`
+	Category string       `json:"category"`
+	Elements []HeaderElem `json:"elements"`
 }
 
 type HeaderElem struct {
-	Png		string	`json:"png"`
-	Link	string	`json:"link"`
+	Png  string `json:"png"`
+	Link string `json:"link"`
 }
 
 type ImageElement struct {
-	ImgUrl	string	`json:"img_url"`
+	ImgUrl string `json:"img_url"`
 }
 
 type MenuElement struct {
-	Png		string	`json:"png"`
-	Category	string	`json:"category"`
-	MenuLinks	[]MenuLinkPair	`json:"menu_links"`
+	Png       string         `json:"png"`
+	Category  string         `json:"category"`
+	MenuLinks []MenuLinkPair `json:"menu_links"`
 }
 
 type MenuLinkPair struct {
-	MenuLink	string	`json:"menu_link"`
-	LinkText 	string	`json:"link_text"`
+	MenuLink string `json:"menu_link"`
+	LinkText string `json:"link_text"`
 }
 
 type Document struct {
-	Ident	string	`json:"identifier"`
-	Created	string	`json:"created"`
-	Body	string	`json:"body"`
-	Category	string	`json:"category"`
-	Sample  string
+	Ident    string `json:"identifier"`
+	Created  string `json:"created"`
+	Body     string `json:"body"`
+	Category string `json:"category"`
+	Sample   string
 }
 
 type AdminTables struct {
-	Tables		[]Table	`json:"tables"`
+	Tables []Table `json:"tables"`
 }
 
 type Table struct {
-	TableName	string	`json:"table_name"`
-	TableData	[]TableData	`json:"table_data"`
+	TableName string      `json:"table_name"`
+	TableData []TableData `json:"table_data"`
 }
 
 type TableData struct {
-	DisplayName		string	`json:"display_name"`
-	Link			string	`json:"link"`
+	DisplayName string `json:"display_name"`
+	Link        string `json:"link"`
 }
 
-
 func NewDocument(ident string, created *time.Time, body string, category string) Document {
-	
+
 	var ts time.Time
 	if created == nil {
 		rn := time.Now()
 		ts = time.Date(rn.Year(), rn.Month(), rn.Day(), rn.Hour(), rn.Minute(),
-						rn.Second(), rn.Nanosecond(), rn.Location())
+			rn.Second(), rn.Nanosecond(), rn.Location())
 	} else {
 		ts = *created
 	}
-	
+
 	return Document{Ident: ident, Created: ts.String(), Body: body, Category: category}
 }
 
 type DocumentUpload struct {
-	Name	string	`json:"name"`
-	Category	string	`json:"category"`
-	Text	string	`json:"text"`
+	Name     string `json:"name"`
+	Category string `json:"category"`
+	Text     string `json:"text"`
 }
 
-
 type HeaderIo interface {
 	GetHeaders() (*HeaderCollection, error)
 	AddHeaders(HeaderCollection) error
-	GetMenuLinks()	(*MenuElement, error)
+	GetMenuLinks() (*MenuElement, error)
 }
 
 /*
@@ -119,7 +120,8 @@ func GetHeaders(redisCfg RedisConf) (*HeaderCollection, error) {
 		return nil, err
 	}
 	header := &HeaderCollection{}
-	err = json.Unmarshal([]byte(d), header); if err != nil {
+	err = json.Unmarshal([]byte(d), header)
+	if err != nil {
 		return nil, err
 	}
 	return header, nil
@@ -138,7 +140,8 @@ func GetMenuLinks(redisCfg RedisConf) (*MenuElement, error) {
 		return nil, err
 	}
 	header := &MenuElement{}
-	err = json.Unmarshal([]byte(d), header); if err != nil {
+	err = json.Unmarshal([]byte(d), header)
+	if err != nil {
 		return nil, err
 	}
 	return header, nil
@@ -157,7 +160,8 @@ func GetAdminTables(redisCfg RedisConf) (*AdminTables, error) {
 		return nil, err
 	}
 	tables := &AdminTables{}
-	err = json.Unmarshal([]byte(d), tables); if err != nil {
+	err = json.Unmarshal([]byte(d), tables)
+	if err != nil {
 		return nil, err
 	}
 	return tables, nil
@@ -198,6 +202,7 @@ func (d *Document) MakeSample() string {
 
 /*
 Retrieve all documents from the category specified in the argument category
+
 	:param category: the category to get documents from
 */
 func GetAllDocuments(category string, redisCfg RedisConf) ([]*Document, error) {
@@ -216,11 +221,10 @@ func GetAllDocuments(category string, redisCfg RedisConf) ([]*Document, error) {
 			continue
 		}
 		docs = append(docs, &Document{
-			Ident: doc.Ident,
+			Ident:   doc.Ident,
 			Created: doc.Created,
-			Body: doc.Body,
-			Sample: doc.MakeSample(),
-
+			Body:    doc.Body,
+			Sample:  doc.MakeSample(),
 		})
 	}
 	return docs, nil
@@ -235,4 +239,18 @@ func AddDocument(d Document, redisCfg RedisConf) error {
 	return rdc.AddDoc(d)
 }
 
+/*
+	 convert markdown to html
+		:param md: the byte array containing the Markdown to convert
+*/
+func MdToHTML(md []byte) []byte {
+	extensions := parser.CommonExtensions | parser.AutoHeadingIDs | parser.NoEmptyLineBeforeBlock
+	p := parser.NewWithExtensions(extensions)
+	doc := p.Parse(md)
+
+	htmlFlags := html.CommonFlags | html.HrefTargetBlank
+	opts := html.RendererOptions{Flags: htmlFlags}
+	renderer := html.NewRenderer(opts)
 
+	return markdown.Render(doc, renderer)
+}