Skip to content

Commit

Permalink
feat: added VanillaNoteRendering
Browse files Browse the repository at this point in the history
- Search notes for [note title name](valid url)
- Added note validation checker for the above
- Basic sequential rendering process implementation
- Added Deep Data Merge for propesed LinkMaps
- Enabled table rendering and checkbox goldmark extensions

Co-authored-by: Anirudh Sudhir <[email protected]>
  • Loading branch information
bwaklog and anirudhsudhir committed Apr 10, 2024
1 parent c79fd90 commit 4ebb93e
Show file tree
Hide file tree
Showing 12 changed files with 312 additions and 53 deletions.
1 change: 1 addition & 0 deletions cmd/anna/anna.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,5 @@ func (cmd *Cmd) VanillaRender() {
e.RenderUserDefinedPages(helpers.SiteDataPath, templ)

e.RenderTags(helpers.SiteDataPath, templ)
cmd.VanillaNoteRender(p.LayoutConfig)
}
6 changes: 4 additions & 2 deletions cmd/anna/notes.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,20 @@ import (
"os"

"github.com/acmpesuecc/anna/pkg/helpers"
"github.com/acmpesuecc/anna/pkg/parser"
zettel_engine "github.com/acmpesuecc/anna/pkg/zettel/engine"
zettel_parser "github.com/acmpesuecc/anna/pkg/zettel/parser"
)

func (cmd *Cmd) VanillaNoteRender() {
func (cmd *Cmd) VanillaNoteRender(LayoutConfig parser.LayoutConfig) {
p := zettel_parser.Parser{
ErrorLogger: log.New(os.Stderr, "ERROR\t", log.Ldate|log.Ltime|log.Lshortfile),
}
p.NotesMergedData.Notes = make(map[template.URL]zettel_parser.Note)
p.NotesMergedData.LinkStore = make(map[template.URL][]*zettel_parser.Note)

fileSystem := os.DirFS(helpers.SiteDataPath + "content/notes")
p.Layout = LayoutConfig
p.ParseNotesDir(helpers.SiteDataPath+"content/notes/", fileSystem)

e := zettel_engine.Engine{
Expand All @@ -38,5 +40,5 @@ func (cmd *Cmd) VanillaNoteRender() {
}

e.GenerateLinkStore()
e.RenderUserNotes()
e.RenderUserNotes(helpers.SiteDataPath, templ)
}
7 changes: 6 additions & 1 deletion pkg/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (

"github.com/acmpesuecc/anna/pkg/helpers"
"github.com/yuin/goldmark"
"github.com/yuin/goldmark/extension"
"github.com/yuin/goldmark/renderer/html"
"gopkg.in/yaml.v3"
)
Expand Down Expand Up @@ -84,7 +85,7 @@ type Parser struct {

func (p *Parser) ParseMDDir(baseDirPath string, baseDirFS fs.FS) {
fs.WalkDir(baseDirFS, ".", func(path string, dir fs.DirEntry, err error) error {
if path != "." {
if (path != "." && !strings.Contains(path, "notes")) {
if dir.IsDir() {
subDir := os.DirFS(path)
p.ParseMDDir(path, subDir)
Expand Down Expand Up @@ -187,6 +188,10 @@ func (p *Parser) ParseMarkdownContent(filecontent string) (Frontmatter, string,
var parsedMarkdown bytes.Buffer

md := goldmark.New(
goldmark.WithExtensions(
extension.TaskList,
extension.Table,
),
goldmark.WithRendererOptions(
html.WithUnsafe(),
),
Expand Down
37 changes: 34 additions & 3 deletions pkg/zettel/engine/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func (e *Engine) RenderNote(fileOutPath string, pagePath template.URL, templ *te
dirPath = fileOutPath + "rendered/" + dirPath

err := os.MkdirAll(dirPath, 0750)
//fmt.Printf("%s => Creating %s\n", pagePath, dirPath)
if err != nil {
e.ErrorLogger.Fatal(err)
}
Expand All @@ -38,7 +39,7 @@ func (e *Engine) RenderNote(fileOutPath string, pagePath template.URL, templ *te
var buffer bytes.Buffer

// Storing the rendered HTML file to a buffer
err := templ.ExecuteTemplate(&buffer, "note", e.NotesMergedData)
err := templ.ExecuteTemplate(&buffer, "note", e.NotesMergedData.Notes[noteURL])
if err != nil {
e.ErrorLogger.Fatal(err)
}
Expand All @@ -50,10 +51,40 @@ func (e *Engine) RenderNote(fileOutPath string, pagePath template.URL, templ *te
}
}

func (e *Engine) RenderUserNotes(){
func (e *Engine) RenderUserNotes(fileOutPath string, templ *template.Template) {
// Loop and render user notes
for _, Note := range e.NotesMergedData.Notes {

//htmlFilePath, _ := strings.CutSuffix(string(noteURL), ".md")
//destinationPath := fileOutPath + "render/" + htmlFilePath + ".html"
fileInPath := strings.TrimSuffix(string(Note.CompleteURL), ".html")

e.RenderNote(fileOutPath, template.URL(fileInPath), templ, Note.CompleteURL)

}
}

func (e *Engine) RetrieveNotePointer(noteTitle string) *zettel_parser.Note {
for _, Note := range e.NotesMergedData.Notes {
if Note.Frontmatter.Title == noteTitle {
return &Note
}
}
return nil
}

func (e *Engine) GenerateLinkStore(){
func (e *Engine) GenerateLinkStore() {
// Populate the LinkStore map
for _, Note := range e.NotesMergedData.Notes {
for _, referencedNoteTitle := range Note.LinkedNoteTitles {
referencedNotePointer := e.RetrieveNotePointer(referencedNoteTitle)
if referencedNotePointer == nil {
e.ErrorLogger.Fatalf("ERR: Failed to get pointer to note %s\n", referencedNoteTitle)
}
e.NotesMergedData.LinkStore[Note.CompleteURL] = append(
e.NotesMergedData.LinkStore[Note.CompleteURL],
referencedNotePointer,
)
}
}
}
105 changes: 63 additions & 42 deletions pkg/zettel/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,15 @@ type Note struct {
Frontmatter Frontmatter
Body template.HTML
LinkedNoteTitles []string
LayoutConfig parser.LayoutConfig
Layout parser.LayoutConfig
}

type Parser struct {
// Holds the data of all of the notes
NotesMergedData NotesMerged

Layout parser.LayoutConfig

// Common logger for all parser functions
ErrorLogger *log.Logger
}
Expand Down Expand Up @@ -70,19 +72,21 @@ func (p *Parser) ParseNotesDir(baseDirPath string, baseDirFS fs.FS) {
p.ErrorLogger.Fatal(err)
}

fronmatter, body, parseSuccess := p.ParseNoteMarkdownContent(string(content))
fronmatter, body, linkedNoteTitles, parseSuccess := p.ParseNoteMarkdownContent(string(content))
if parseSuccess {
// ISSUE
p.AddNote(baseDirPath, fileName, fronmatter, body)
p.AddNote(baseDirPath, fileName, fronmatter, body, linkedNoteTitles)
// fmt.Println(fileName, linkedNoteTitles)
}
}
}
}
return nil
})
p.ValidateNoteReferences()
}

func (p *Parser) ParseNoteMarkdownContent(filecontent string) (Frontmatter, string, bool) {
func (p *Parser) ParseNoteMarkdownContent(filecontent string) (Frontmatter, string, []string, bool) {
var parsedFrontmatter Frontmatter
var markdown string
/*
Expand All @@ -97,14 +101,14 @@ func (p *Parser) ParseNoteMarkdownContent(filecontent string) (Frontmatter, stri
frontmatterSplit := ""

if len(splitContents) <= 1 {
return Frontmatter{}, "", false
return Frontmatter{}, "", []string{}, false
}

regex := regexp.MustCompile(`title(.*): (.*)`)
match := regex.FindStringSubmatch(splitContents[1])

if match == nil {
return Frontmatter{}, "", false
return Frontmatter{}, "", []string{}, false
}

frontmatterSplit = splitContents[1]
Expand All @@ -118,6 +122,33 @@ func (p *Parser) ParseNoteMarkdownContent(filecontent string) (Frontmatter, stri
// TODO:
// This section must replace the callouts with
// the html url references
/*
REGEX:
using regex we need to identify for the references to other
notes of the following pattern
[Note Title Name](/note/somefilename)
*/

re := regexp.MustCompile(`\[[^\]]*\]\(/notes/[^\]]*\.md\)`)
re_sub := regexp.MustCompile(`\[.*\]`)
matches := re.FindAllString(markdown, -1)
// fmt.Printf("%s\n", parsedFrontmatter.Title)

linkedNoteTitles := []string{}

for _, match := range matches {
/*
Extracting the file "Titles" from the first match
ex: [Nunc ullamcorper](/notes/2021-09-01-nunc-ullamcorper.md)
will extract out "[Nunc ullamcorper]"
*/
sub_match := re_sub.FindString(match)
sub_match = strings.Trim(sub_match, "[]")
// fmt.Printf("\t%s\n", sub_match)

linkedNoteTitles = append(linkedNoteTitles, sub_match)
}

// Parsing markdown to HTML
var parsedMarkdown bytes.Buffer
Expand All @@ -132,10 +163,10 @@ func (p *Parser) ParseNoteMarkdownContent(filecontent string) (Frontmatter, stri
p.ErrorLogger.Fatal(err)
}

return parsedFrontmatter, parsedMarkdown.String(), true
return parsedFrontmatter, parsedMarkdown.String(), linkedNoteTitles, true
}

func (p *Parser) AddNote(baseDirPath string, dirEntryPath string, frontmatter Frontmatter, body string) {
func (p *Parser) AddNote(baseDirPath string, dirEntryPath string, frontmatter Frontmatter, body string, linkedNoteTitles []string) {
filepath := baseDirPath + dirEntryPath

var date int64
Expand All @@ -160,48 +191,38 @@ func (p *Parser) AddNote(baseDirPath string, dirEntryPath string, frontmatter Fr
FilenameWithoutExtension: strings.Split(dirEntryPath, ".")[0],
Frontmatter: frontmatter,
Body: template.HTML(body),
LinkedNoteTitles: []string{},
// Layout: p.LayoutConfig,
LinkedNoteTitles: linkedNoteTitles,
Layout: p.Layout,
}

p.NotesMergedData.Notes[template.URL(key)] = note

/*
REGEX:
using regex we need to identify for the references to other
notes of the following pattern
[Note Title Name](/note/somefilename)
*/

re := regexp.MustCompile(`\[.*\]\((\/notes\/).*(.md)\)`)
re_sub := regexp.MustCompile(`\[.*\]`)
matches := re.FindAllString(string(note.Body), -1)

for _, match := range matches {
/*
Extracting the file "Titles" from the first match
ex: [Nunc ullamcorper](/notes/2021-09-01-nunc-ullamcorper.md)
will extract out "[Nunc ullamcorper]"
*/
sub_match := re_sub.FindString(match)
sub_match = strings.Trim(sub_match, "[]")
p.NotesMergedData.Notes[note.CompleteURL] = note
//fmt.Println(note.Layout)
}

note.LinkedNoteTitles = append(note.LinkedNoteTitles, sub_match)
func (p *Parser) ValidateNoteTitle(ReferenceNoteTitle string) bool {
for _, Note := range p.NotesMergedData.Notes {
if Note.Frontmatter.Title == ReferenceNoteTitle {
return true
}
}
return false
}

func (p *Parser) ValidateNoteReferences() {
/*
This function is going to validate whether all the
references in the notes have a valid link to another
note
This function is going to validate whether all the
references in the notes have a valid link to another
note
Example: for `[Nunc ullamcorper](/notes/1234.md)` to be
a valid reference, the title part of the frontmatter
of the note `/note/1234.md` must have "Nunc ullamcorper"
Example: for `[Nunc ullamcorper](/notes/1234.md)` to be
a valid reference, the title part of the frontmatter
of the note `/note/1234.md` must have "Nunc ullamcorper"
*/



for _, Note := range p.NotesMergedData.Notes {
for _, ReferenceNoteTitle := range Note.LinkedNoteTitles {
if !p.ValidateNoteTitle(ReferenceNoteTitle) {
p.ErrorLogger.Fatalf("ERR: Referenced note title (%s) doesnt have an existing note", ReferenceNoteTitle)
}
}
}
}
8 changes: 8 additions & 0 deletions site/content/notes/test1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
title: Lorem Ipsum
date: 2024-02-02
type: zettler
head: true
---

Sed ut velit ante. Suspendisse ac porta urna, eget iaculis dui. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vel enim dolor. [Nunc ullamcorper](/notes/test2.html) neque ut mattis commodo. Morbi bibendum sem accumsan mi imperdiet, id egestas nulla posuere. Morbi sodales justo euismod nulla porttitor [lobortis](/notes/test3.html) sed ut sem
6 changes: 6 additions & 0 deletions site/content/notes/test2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
title: Nunc ullamcorper
date: 2024-02-02
type: zettler
head: false
---
8 changes: 8 additions & 0 deletions site/content/notes/test3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
title: lobortis
date: 2024-02-02
type: zettler
head: false
---

This is back to the head [Lorem Ipsum](/notes/test1.html)
Loading

0 comments on commit 4ebb93e

Please sign in to comment.