diff --git a/cmd/anna/anna.go b/cmd/anna/anna.go index 788ef70..976cb45 100644 --- a/cmd/anna/anna.go +++ b/cmd/anna/anna.go @@ -1,6 +1,7 @@ package anna import ( + "fmt" "html/template" "log" "os" @@ -20,8 +21,8 @@ type Cmd struct { func (cmd *Cmd) VanillaRender() { // Defining Engine and Parser Structures p := parser.Parser{ - Templates: make(map[template.URL]parser.TemplateData), - TagsMap: make(map[template.URL][]parser.TemplateData), + Templates: make(map[template.URL]parser.TemplateData, 10), + TagsMap: make(map[template.URL][]parser.TemplateData, 10), ErrorLogger: log.New(os.Stderr, "ERROR\t", log.Ldate|log.Ltime|log.Lshortfile), RenderDrafts: cmd.RenderDrafts, LiveReload: cmd.LiveReload, @@ -30,8 +31,10 @@ func (cmd *Cmd) VanillaRender() { e := engine.Engine{ ErrorLogger: log.New(os.Stderr, "ERROR\t", log.Ldate|log.Ltime|log.Lshortfile), } - e.DeepDataMerge.Templates = make(map[template.URL]parser.TemplateData) - e.DeepDataMerge.TagsMap = make(map[template.URL][]parser.TemplateData) + e.DeepDataMerge.Templates = make(map[template.URL]parser.TemplateData, 10) + e.DeepDataMerge.TagsMap = make(map[template.URL][]parser.TemplateData, 10) + e.DeepDataMerge.Notes = make(map[template.URL]parser.Note, 10) + e.DeepDataMerge.LinkStore = make(map[template.URL][]*parser.Note, 10) helper := helpers.Helper{ ErrorLogger: e.ErrorLogger, @@ -45,7 +48,9 @@ func (cmd *Cmd) VanillaRender() { p.ParseConfig(helpers.SiteDataPath + "layout/config.yml") fileSystem := os.DirFS(helpers.SiteDataPath + "content/") + p.Notes = make(map[template.URL]parser.Note, 10) p.ParseMDDir(helpers.SiteDataPath+"content/", fileSystem) + p.BackLinkParser() p.ParseRobots(helpers.SiteDataPath+"layout/robots.txt", helpers.SiteDataPath+"rendered/robots.txt") p.ParseLayoutFiles() @@ -77,5 +82,11 @@ func (cmd *Cmd) VanillaRender() { e.RenderUserDefinedPages(helpers.SiteDataPath, templ) e.RenderTags(helpers.SiteDataPath, templ) - cmd.VanillaNoteRender(p.LayoutConfig) + + // Zettel engine functionality + e.DeepDataMerge.Notes = p.Notes + + e.GenerateLinkStore() + fmt.Println(e.DeepDataMerge.LinkStore) + e.RenderNotes(helpers.SiteDataPath, templ) } diff --git a/cmd/anna/notes.go b/cmd/anna/notes.go.temp similarity index 77% rename from cmd/anna/notes.go rename to cmd/anna/notes.go.temp index 3e1054c..a0c43cc 100644 --- a/cmd/anna/notes.go +++ b/cmd/anna/notes.go.temp @@ -5,24 +5,23 @@ import ( "log" "os" + "github.com/acmpesuecc/anna/pkg/engine" "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(LayoutConfig parser.LayoutConfig) { - p := zettel_parser.Parser{ + p := 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) + p.Notes = make(map[template.URL]parser.Note) + e.LinkStore = make(map[template.URL][]*parser.Note) fileSystem := os.DirFS(helpers.SiteDataPath + "content/notes") p.Layout = LayoutConfig p.ParseNotesDir(helpers.SiteDataPath+"content/notes/", fileSystem) - e := zettel_engine.Engine{ + e := engine.Engine{ ErrorLogger: log.New(os.Stderr, "ERROR\t", log.Ldate|log.Ltime|log.Lshortfile), } e.NotesMergedData.Notes = make(map[template.URL]zettel_parser.Note) diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 4bbcfda..ab46ec4 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -28,6 +28,12 @@ type DeepDataMerge struct { // Posts contains the template data of files in the posts directory Posts []parser.TemplateData + //Stores all the notes + Notes map[template.URL]parser.Note + + //Stores the links of each note to other notes + LinkStore map[template.URL][]*parser.Note + // Stores the index generated for search functionality JSONIndex map[template.URL]JSONIndexTemplate } diff --git a/pkg/engine/user_engine.go b/pkg/engine/user_engine.go index 7254108..754d1c4 100644 --- a/pkg/engine/user_engine.go +++ b/pkg/engine/user_engine.go @@ -5,7 +5,6 @@ import ( "html/template" "os" "runtime" - "strings" "sync" "github.com/acmpesuecc/anna/pkg/parser" @@ -28,14 +27,6 @@ func (e *Engine) RenderEngineGeneratedFiles(fileOutPath string, template *templa DeepDataMerge: e.DeepDataMerge, PageURL: "posts.html", } - // e.DeepDataMerge.Templates["posts.html"] = parser.TemplateData{ - // Frontmatter: parser.Frontmatter{Title: "Posts"}, - // } - - // pageData := PageData{ - // DeepDataMerge: e.DeepDataMerge, - // PageURL: "posts.html", - // } err := template.ExecuteTemplate(&postsBuffer, "posts", postsData) if err != nil { @@ -67,8 +58,7 @@ func (e *Engine) RenderUserDefinedPages(fileOutPath string, templ *template.Temp semaphore := make(chan struct{}, concurrency) for _, templateURL := range templateURLs { - fileInPath := strings.TrimSuffix(templateURL, ".html") - if fileInPath == ".html" { + if templateURL == ".html" { continue } diff --git a/pkg/engine/zettel_engine.go b/pkg/engine/zettel_engine.go new file mode 100644 index 0000000..f4268a7 --- /dev/null +++ b/pkg/engine/zettel_engine.go @@ -0,0 +1,94 @@ +package engine + +import ( + "html/template" + "runtime" + "sync" +) + +func (e *Engine) RenderNotes(fileOutPath string, templ *template.Template) { + // templ.Funcs(funcMap template.FuncMap) + + numCPU := runtime.NumCPU() + numTemplates := len(e.DeepDataMerge.Notes) + concurrency := numCPU * 2 // Adjust the concurrency factor based on system hardware resources + + if numTemplates < concurrency { + concurrency = numTemplates + } + + templateURLs := make([]string, 0, numTemplates) + for templateURL := range e.DeepDataMerge.Notes { + templateURLs = append(templateURLs, string(templateURL)) + } + + var wg sync.WaitGroup + semaphore := make(chan struct{}, concurrency) + + for _, url := range templateURLs { + if url == ".html" { + continue + } + + wg.Add(1) + semaphore <- struct{}{} + + go func(templateURL string) { + defer func() { + <-semaphore + wg.Done() + }() + + e.RenderPage(fileOutPath, template.URL(url), templ, "note") + }(url) + } + + wg.Wait() +} + +func (e *Engine) GenerateLinkStore() { + for url, note := range e.DeepDataMerge.Notes { + for _, linkURL := range note.LinkedNoteURLs { + linkNote, ok := e.DeepDataMerge.Notes[linkURL] + if ok { + e.DeepDataMerge.LinkStore[url] = append(e.DeepDataMerge.LinkStore[url], &linkNote) + } + } + } +} + +// func (z *Zettel) RetrieveNotePointer(noteTitle string) *zettel_parser.Note { +// for _, Note := range e.NotesMergedData.Notes { +// if Note.Frontmatter.Title == noteTitle { +// return &Note +// } +// } +// return nil +// } + +// func (e *Engine) GenerateRootNote(fileOutPath string, templ *template.Template) { +// // This is the page that acts as the root of all the +// // notes part of the site + +// // Creating a map of all head notes + +// var buffer bytes.Buffer + +// fmt.Println(e.NotesMergedData.LinkStore) + +// /* +// t := template.Must(templ.Funcs(template.FuncMap{ +// "Deref": func(i *zettel_parser.Note) zettel_parser.Note { return *note }, +// }).Parse(src)) +// */ + +// err := templ.ExecuteTemplate(&buffer, "root", e.NotesMergedData.LinkStore) +// if err != nil { +// e.ErrorLogger.Fatal(err) +// } + +// err = os.WriteFile(fileOutPath+"rendered/notes.html", buffer.Bytes(), 0666) +// if err != nil { +// e.ErrorLogger.Fatal(err) +// } +// } diff --git a/pkg/parser/parser.go b/pkg/parser/parser.go index 648519d..17d40f9 100644 --- a/pkg/parser/parser.go +++ b/pkg/parser/parser.go @@ -36,6 +36,10 @@ type Frontmatter struct { PreviewImage string `yaml:"previewimage"` Tags []string `yaml:"tags"` Authors []string `yaml:"authors"` + + // Head is specifically used for + // mentioning the head of the notes + Head bool `yaml:"head"` } // This struct holds all of the data required to render any page of the site @@ -63,6 +67,9 @@ type Parser struct { // Posts contains the template data of files in the posts directory Posts []TemplateData + //Stores all the notes + Notes map[template.URL]Note + // TODO: Look into the two below fields into a single one MdFilesName []string MdFilesPath []string @@ -81,13 +88,19 @@ 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 != "." && !strings.Contains(path, "notes") { + if path != "." && path != ".obsidian" { if dir.IsDir() { subDir := os.DirFS(path) p.ParseMDDir(path, subDir) } else { if filepath.Ext(path) == ".md" { - fileName := filepath.Base(path) + // OLD IMPL + // fileName := filepath.Base(path) + // + // NEW IMPL + // /contents/notes/2134321.md ==> notes/2134321.md + fileName := strings.TrimPrefix(path, baseDirPath) + // fmt.Println(fileNameWithPath, fileName) content, err := os.ReadFile(baseDirPath + path) if err != nil { @@ -96,10 +109,15 @@ func (p *Parser) ParseMDDir(baseDirPath string, baseDirFS fs.FS) { fronmatter, body, parseSuccess := p.ParseMarkdownContent(string(content)) if parseSuccess { - if (fronmatter.Draft && p.RenderDrafts) || !fronmatter.Draft { - p.AddFileAndRender(baseDirPath, fileName, fronmatter, body) + if fronmatter.Type == "post" { + if (fronmatter.Draft && p.RenderDrafts) || !fronmatter.Draft { + p.AddFile(baseDirPath, fileName, fronmatter, body) + } + } else { + p.AddFile(baseDirPath, fileName, fronmatter, body) } } + } } } @@ -107,8 +125,9 @@ func (p *Parser) ParseMDDir(baseDirPath string, baseDirFS fs.FS) { }) } -func (p *Parser) AddFileAndRender(baseDirPath string, dirEntryPath string, frontmatter Frontmatter, body string) { +func (p *Parser) AddFile(baseDirPath string, dirEntryPath string, frontmatter Frontmatter, body string) { p.MdFilesName = append(p.MdFilesName, dirEntryPath) + // fmt.Println(baseDirPath, dirEntryPath) filepath := baseDirPath + dirEntryPath p.MdFilesPath = append(p.MdFilesPath, filepath) @@ -122,30 +141,51 @@ func (p *Parser) AddFileAndRender(baseDirPath string, dirEntryPath string, front key, _ := strings.CutPrefix(filepath, helpers.SiteDataPath+"content/") url, _ := strings.CutSuffix(key, ".md") url += ".html" - if frontmatter.Type == "post" { - url = "posts/" + url - } - page := TemplateData{ - CompleteURL: template.URL(url), - Date: date, - Frontmatter: frontmatter, - Body: template.HTML(body), - LiveReload: p.LiveReload, - } + if frontmatter.Type == "post" || frontmatter.Type == "page" { + + page := TemplateData{ + CompleteURL: template.URL(url), + Date: date, + Frontmatter: frontmatter, + Body: template.HTML(body), + LiveReload: p.LiveReload, + } + + // Adding the page to the merged map storing all site pages + if frontmatter.Type == "post" { + // url = "posts/" + url + p.Posts = append(p.Posts, page) + } + + p.Templates[template.URL(url)] = page + + // Adding the page to the tags map with the corresponding tags + for _, tag := range page.Frontmatter.Tags { + tagsMapKey := "tags/" + tag + ".html" + p.TagsMap[template.URL(tagsMapKey)] = append(p.TagsMap[template.URL(tagsMapKey)], page) + + } - // Adding the page to the merged map storing all site pages - if frontmatter.Type == "post" { - p.Posts = append(p.Posts, page) } - p.Templates[template.URL(url)] = page + if frontmatter.Type == "note" { + // url = "notes/" + url - // Adding the page to the tags map with the corresponding tags - for _, tag := range page.Frontmatter.Tags { - tagsMapKey := "tags/" + tag + ".html" - p.TagsMap[template.URL(tagsMapKey)] = append(p.TagsMap[template.URL(tagsMapKey)], page) + note := Note{ + CompleteURL: template.URL(url), + Date: date, + Frontmatter: frontmatter, + Body: template.HTML(body), + LinkedNoteURLs: []template.URL{}, + } + + p.Notes[note.CompleteURL] = note + + // NOTE: not adding the template urls of referenced ntoes + // rather, will populate it while links } + } func (p *Parser) ParseMarkdownContent(filecontent string) (Frontmatter, string, bool) { diff --git a/pkg/parser/parser_test.go b/pkg/parser/parser_test.go index 15705fe..2697003 100644 --- a/pkg/parser/parser_test.go +++ b/pkg/parser/parser_test.go @@ -65,7 +65,7 @@ func TestAddFileandRender(t *testing.T) { want_parser.Posts = append(want_parser.Posts, want_page) } - got_parser.AddFileAndRender("", filename, sample_frontmatter, sample_body) + got_parser.AddFile("", filename, sample_frontmatter, sample_body) if !reflect.DeepEqual(got_parser, want_parser) { t.Errorf("want %v; \ngot %v", want_parser, got_parser) diff --git a/pkg/parser/zettel_parser.go b/pkg/parser/zettel_parser.go new file mode 100644 index 0000000..33cae74 --- /dev/null +++ b/pkg/parser/zettel_parser.go @@ -0,0 +1,78 @@ +package parser + +import ( + "errors" + "fmt" + "html/template" + "regexp" + "strings" +) + +type Note struct { + CompleteURL template.URL + Date int64 + Frontmatter Frontmatter + Body template.HTML + LinkedNoteURLs []template.URL +} + +func (p *Parser) BackLinkParser() { + /* + This function is going to validate whether all the + references in the notes have a valid link to another + note + + Example: for `[Nunc ullamcorper]]` to be + a valid reference, the title part of the frontmatter + of the note `/note/1234.md` must have "Nunc ullamcorper" + */ + + for noteURL, note := range p.Notes { + + noteBody := string(note.Body) // template.HTML -> string + // noteParentDir := note.CompleteURL + + // fmt.Println("Finding links for :", noteParentDir) + + backlinkRE := regexp.MustCompile(`\[[^\]]*\]\]`) + backlinks := backlinkRE.FindAllString(noteBody, -1) + + for _, backlink := range backlinks { + // Now that we have the backlinks to titles, + // we need to walk the notes dir to find if there + // are any matches + noteTitle := strings.Trim(backlink, "[]") + + referenceCompleteURL, err := p.ValidateBackLink(noteTitle) + if err != nil{ + p.ErrorLogger.Fatal(err) + } else { + // creating anchor tag reference for parsed markdown + anchorReference := fmt.Sprintf(`%s`, referenceCompleteURL, noteTitle) + noteBody = strings.ReplaceAll(noteBody, backlink, anchorReference) + + // fmt.Println(note.LinkedNoteURLs) + note.LinkedNoteURLs = append(note.LinkedNoteURLs, referenceCompleteURL) + } + } + + p.Notes[noteURL] = Note{ + CompleteURL: note.CompleteURL, + Date: note.Date, + Frontmatter: note.Frontmatter, + Body: template.HTML(noteBody), + LinkedNoteURLs: note.LinkedNoteURLs, + } + + } +} + +func (p *Parser) ValidateBackLink(noteTitle string) (template.URL, error) { + for _, note := range p.Notes { + if note.Frontmatter.Title == noteTitle { + return note.CompleteURL, nil + } + } + errorMessage := fmt.Sprintf("ERR: Failed to find a note for backlink %s\n", noteTitle) + return "", errors.New(errorMessage) +} diff --git a/pkg/zettel/engine/engine.go b/pkg/zettel/engine/engine.go deleted file mode 100644 index 425c4ee..0000000 --- a/pkg/zettel/engine/engine.go +++ /dev/null @@ -1,117 +0,0 @@ -package zettel_engine - -import ( - "bytes" - "fmt" - "html/template" - "log" - "os" - "strings" - - zettel_parser "github.com/acmpesuecc/anna/pkg/zettel/parser" -) - -type Engine struct { - - // Holds the data of all of the notes - NotesMergedData zettel_parser.NotesMerged - - // Common logger for all engine functions - ErrorLogger *log.Logger -} - -func (e *Engine) RenderNote(fileOutPath string, pagePath template.URL, templ *template.Template, noteURL template.URL) { - // Creating subdirectories if the filepath contains '/' - dirPath := "" - if strings.Contains(string(pagePath), "/") { - // Extracting the directory path from the page path - dirPath, _ := strings.CutSuffix(string(pagePath), e.NotesMergedData.Notes[noteURL].FilenameWithoutExtension) - dirPath = fileOutPath + "rendered/" + dirPath - - err := os.MkdirAll(dirPath, 0750) - if err != nil { - e.ErrorLogger.Fatal(err) - } - } - - filename, _ := strings.CutSuffix(string(pagePath), ".md") - filepath := fileOutPath + "rendered/" + dirPath + filename + ".html" - var buffer bytes.Buffer - - // Storing the rendered HTML file to a buffer - err := templ.ExecuteTemplate(&buffer, "note", e.NotesMergedData.Notes[noteURL]) - if err != nil { - e.ErrorLogger.Fatal(err) - } - - // Flushing data from the buffer to the disk - err = os.WriteFile(filepath, buffer.Bytes(), 0666) - if err != nil { - e.ErrorLogger.Fatal(err) - } -} - -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() { - // 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, - ) - } - } -} - -func (e *Engine) GenerateRootNote(fileOutPath string, templ *template.Template) { - // This is the page that acts as the root of all the - // notes part of the site - - // Creating a map of all head notes - - var buffer bytes.Buffer - - fmt.Println(e.NotesMergedData.LinkStore) - - /* - t := template.Must(templ.Funcs(template.FuncMap{ - "Deref": func(i *zettel_parser.Note) zettel_parser.Note { return *note }, - }).Parse(src)) - */ - - err := templ.ExecuteTemplate(&buffer, "root", e.NotesMergedData.LinkStore) - if err != nil { - e.ErrorLogger.Fatal(err) - } - - err = os.WriteFile(fileOutPath+"rendered/notes.html", buffer.Bytes(), 0666) - if err != nil { - e.ErrorLogger.Fatal(err) - } -} diff --git a/pkg/zettel/parser/parser.go b/pkg/zettel/parser/parser.temp similarity index 77% rename from pkg/zettel/parser/parser.go rename to pkg/zettel/parser/parser.temp index 4dd21df..86a3a87 100644 --- a/pkg/zettel/parser/parser.go +++ b/pkg/zettel/parser/parser.temp @@ -14,32 +14,15 @@ import ( "github.com/acmpesuecc/anna/pkg/helpers" "github.com/acmpesuecc/anna/pkg/parser" + "github.com/acmpesuecc/anna/pkg/zettel" "github.com/yuin/goldmark" "github.com/yuin/goldmark/renderer/html" "gopkg.in/yaml.v3" ) -type NotesMerged struct { - //Stores all the notes - Notes map[template.URL]Note - - //Stores the links of each note to other notes - LinkStore map[template.URL][]*Note -} - -type Note struct { - CompleteURL template.URL - FilenameWithoutExtension string - Date int64 - Frontmatter Frontmatter - Body template.HTML - LinkedNoteTitles []string - Layout parser.LayoutConfig -} - type Parser struct { // Holds the data of all of the notes - NotesMergedData NotesMerged + NotesMergedData zettel.NotesMerged Layout parser.LayoutConfig @@ -47,17 +30,6 @@ type Parser struct { ErrorLogger *log.Logger } -type Frontmatter struct { - Title string `yaml:"title"` - Date string `yaml:"date"` - JSFiles []string `yaml:"scripts"` - Type string `yaml:"type"` - Description string `yaml:"description"` - PreviewImage string `yaml:"previewimage"` - Head bool `yaml:"head"` - // Tags []string `yaml:"tags"` -} - func (p *Parser) ParseNotesDir(baseDirPath string, baseDirFS fs.FS) { fs.WalkDir(baseDirFS, ".", func(path string, dir fs.DirEntry, err error) error { if path != "." && path != ".obsidian" { @@ -77,18 +49,18 @@ func (p *Parser) ParseNotesDir(baseDirPath string, baseDirFS fs.FS) { if parseSuccess { // ISSUE p.AddNote(baseDirPath, fileName, fronmatter, body, linkedNoteTitles) - // fmt.Println(fileName, linkedNoteTitles) + fmt.Println(fileName, linkedNoteTitles) } } } } return nil }) - p.ValidateNoteReferences() + // p.ValidateNoteReferences() } -func (p *Parser) ParseNoteMarkdownContent(filecontent string) (Frontmatter, string, []string, bool) { - var parsedFrontmatter Frontmatter +func (p *Parser) ParseNoteMarkdownContent(filecontent string) (parser.Frontmatter, string, []string, bool) { + var parsedFrontmatter parser.Frontmatter var markdown string /* --- @@ -102,14 +74,14 @@ func (p *Parser) ParseNoteMarkdownContent(filecontent string) (Frontmatter, stri frontmatterSplit := "" if len(splitContents) <= 1 { - return Frontmatter{}, "", []string{}, false + return parser.Frontmatter{}, "", []string{}, false } regex := regexp.MustCompile(`title(.*): (.*)`) match := regex.FindStringSubmatch(splitContents[1]) if match == nil { - return Frontmatter{}, "", []string{}, false + return parser.Frontmatter{}, "", []string{}, false } frontmatterSplit = splitContents[1] @@ -184,7 +156,7 @@ func (p *Parser) ParseNoteMarkdownContent(filecontent string) (Frontmatter, stri return parsedFrontmatter, parsedMarkdown.String(), linkedNoteTitles, true } -func (p *Parser) AddNote(baseDirPath string, dirEntryPath string, frontmatter Frontmatter, body string, linkedNoteTitles []string) { +func (p *Parser) AddNote(baseDirPath string, dirEntryPath string, frontmatter parser.Frontmatter, body string, linkedNoteTitles []string) { filepath := baseDirPath + dirEntryPath var date int64 @@ -203,14 +175,12 @@ func (p *Parser) AddNote(baseDirPath string, dirEntryPath string, frontmatter Fr url = "posts/" + url } - note := Note{ - CompleteURL: template.URL(url), - Date: date, - FilenameWithoutExtension: strings.Split(dirEntryPath, ".")[0], - Frontmatter: frontmatter, - Body: template.HTML(body), - LinkedNoteTitles: linkedNoteTitles, - Layout: p.Layout, + note := zettel.Note{ + CompleteURL: template.URL(url), + Date: date, + Frontmatter: frontmatter, + Body: template.HTML(body), + LinkedNoteTitles: linkedNoteTitles, } p.NotesMergedData.Notes[note.CompleteURL] = note diff --git a/site/content/docs.md b/site/content/docs.md index 66ca0d7..da96122 100644 --- a/site/content/docs.md +++ b/site/content/docs.md @@ -1,6 +1,7 @@ --- date: 2024-04-10 title: Anna Documentation +type: page --- # Anna diff --git a/site/content/index.md b/site/content/index.md index 282127b..8b93c18 100644 --- a/site/content/index.md +++ b/site/content/index.md @@ -1,7 +1,7 @@ --- date: 2024-02-24 title: Home -scripts: +type: page previewimage: "/static/plane.jpg" description: "homepage for our ssg" --- diff --git a/site/content/notes/Lorem Ipsum.md b/site/content/notes/Lorem Ipsum.md deleted file mode 100644 index 7f1c37e..0000000 --- a/site/content/notes/Lorem Ipsum.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -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]] neque ut mattis commodo. Morbi bibendum sem accumsan mi imperdiet, id egestas nulla posuere. Morbi sodales justo euismod nulla porttitor [[lobortis]] sed ut sem diff --git a/site/content/notes/Nunc ullamcorper.md b/site/content/notes/Nunc ullamcorper.md deleted file mode 100644 index 3c41d57..0000000 --- a/site/content/notes/Nunc ullamcorper.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Nunc ullamcorper -date: 2024-02-02 -type: zettler -head: false ---- diff --git a/site/content/notes/Shower Thoughts/213454.md b/site/content/notes/Shower Thoughts/213454.md new file mode 100644 index 0000000..a05ef70 --- /dev/null +++ b/site/content/notes/Shower Thoughts/213454.md @@ -0,0 +1,8 @@ +--- +title: Commodo ullamcorper a lacus +date: 2024-02-02 +type: note +head: false +--- + +Dictum sit amet justo donec enim diam vulputate. Scelerisque in dictum non consectetur. Justo laoreet sit amet cursus sit amet. Sapien pellentesque habitant morbi tristique senectus et netus. Ut morbi tincidunt augue interdum velit euismod. Fusce id velit ut tortor pretium viverra suspendisse potenti. Lobortis feugiat vivamus at augue eget. Fames ac turpis egestas sed tempus urna. Dignissim convallis aenean et tortor at risus viverra adipiscing at. Faucibus purus in massa tempor nec. Eget arcu dictum varius duis at consectetur lorem donec massa. Risus nec feugiat in fermentum posuere urna nec tincidunt. Eget nunc lobortis mattis aliquam faucibus purus in. Pellentesque habitant morbi tristique senectus et netus et malesuada fames. Ultricies tristique nulla aliquet enim tortor. Aliquet lectus proin nibh nisl. Tortor pretium viverra suspendisse potenti nullam ac tortor vitae purus. Malesuada fames ac turpis egestas maecenas pharetra convallis posuere morbi. Eget magna fermentum iaculis eu non diam phasellus. diff --git a/site/content/notes/Shower Thoughts/98fh19.md b/site/content/notes/Shower Thoughts/98fh19.md new file mode 100644 index 0000000..fa6cabd --- /dev/null +++ b/site/content/notes/Shower Thoughts/98fh19.md @@ -0,0 +1,10 @@ +--- +title: Lorem Ipsum +date: 2024-02-02 +type: note +head: true +--- + +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. In vitae turpis massa sed elementum tempus. Mauris augue neque gravida in fermentum et sollicitudin. Nunc sed id semper risus. Vestibulum mattis ullamcorper velit sed ullamcorper. Non consectetur a erat nam at. At tempor commodo ullamcorper a. Eu mi bibendum neque egestas congue quisque egestas diam. Amet consectetur adipiscing elit duis. Scelerisque eu ultrices vitae auctor eu augue. Sed ullamcorper morbi tincidunt ornare massa eget egestas. [[Commodo ullamcorper a lacus]] vestibulum sed. In ornare quam viverra orci sagittis eu volutpat. Fames ac turpis egestas integer eget aliquet. Rhoncus aenean vel elit scelerisque. Mi sit amet mauris commodo quis imperdiet massa tincidunt. Platea dictumst quisque sagittis purus sit. Aliquet nec ullamcorper sit amet risus. Mi bibendum neque egestas congue quisque egestas diam. + +Dictum sit amet justo donec enim diam vulputate. Scelerisque in dictum non consectetur. Justo laoreet sit amet cursus sit amet. Sapien pellentesque habitant morbi tristique senectus et netus. Ut morbi tincidunt augue interdum velit euismod. [[Fusce id velit ut]] tortor pretium viverra suspendisse potenti. Lobortis feugiat vivamus at augue eget. Fames ac turpis egestas sed tempus urna. Dignissim convallis aenean et tortor at risus viverra adipiscing at. Faucibus purus in massa tempor nec. Eget arcu dictum varius duis at consectetur lorem donec massa. Risus nec feugiat in fermentum posuere urna nec tincidunt. Eget nunc lobortis mattis aliquam faucibus purus in. Pellentesque habitant morbi tristique senectus et netus et malesuada fames. Ultricies tristique nulla aliquet enim tortor. Aliquet lectus proin nibh nisl. Tortor pretium viverra suspendisse potenti nullam ac tortor vitae purus. Malesuada fames ac turpis egestas maecenas pharetra convallis posuere morbi. Eget magna fermentum iaculis eu non diam phasellus. diff --git a/site/content/notes/Workflow/123bf8.md b/site/content/notes/Workflow/123bf8.md new file mode 100644 index 0000000..095411d --- /dev/null +++ b/site/content/notes/Workflow/123bf8.md @@ -0,0 +1,10 @@ +--- +title: Posuere sollicitudin aliquam +date: 2024-02-02 +type: note +head: false +--- + +Venenatis a condimentum vitae sapien pellentesque habitant morbi. Non enim praesent elementum facilisis leo vel fringilla est. Justo laoreet sit amet cursus sit amet dictum sit. Amet nulla facilisi morbi tempus. Faucibus scelerisque eleifend donec pretium. Feugiat in ante metus dictum at tempor. Id velit ut tortor pretium viverra suspendisse potenti nullam ac. Ullamcorper morbi tincidunt ornare massa. Nec ultrices dui sapien eget mi proin. Tempor orci eu lobortis elementum nibh tellus. Et netus et malesuada fames ac turpis. Condimentum vitae sapien pellentesque habitant. Netus et malesuada fames ac turpis egestas maecenas pharetra convallis. Sit amet mattis vulputate enim nulla. Pulvinar elementum integer enim neque volutpat ac tincidunt vitae. Urna porttitor rhoncus dolor purus non enim. Mus mauris vitae ultricies leo integer malesuada nunc vel. Accumsan lacus vel facilisis volutpat est velit. Id ornare arcu odio ut sem. Augue neque gravida in fermentum. + +Porttitor rhoncus dolor purus non enim praesent. At volutpat diam ut venenatis. In cursus turpis massa tincidunt dui ut. Urna molestie at elementum eu facilisis sed odio morbi. Mattis rhoncus urna neque viverra justo nec ultrices dui sapien. Interdum consectetur libero id faucibus nisl tincidunt eget nullam. Risus pretium quam vulputate dignissim suspendisse in. Nullam ac tortor vitae purus faucibus ornare suspendisse sed. Ultrices sagittis orci a scelerisque purus semper eget duis. In nibh mauris cursus mattis molestie a iaculis at. Elit pellentesque habitant morbi tristique. Ornare quam viverra orci sagittis eu volutpat odio facilisis mauris. Nulla facilisi cras fermentum odio eu. At tellus at urna condimentum mattis pellentesque id nibh. diff --git a/site/content/notes/Workflow/3957f1.md b/site/content/notes/Workflow/3957f1.md new file mode 100644 index 0000000..fd1432e --- /dev/null +++ b/site/content/notes/Workflow/3957f1.md @@ -0,0 +1,10 @@ +--- +title: Fusce id velit ut +date: 2024-02-02 +type: note +head: true +--- + +[[Lorem Ipsum]] dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + +Vel turpis nunc eget lorem dolor sed viverra. Amet consectetur adipiscing elit duis tristique sollicitudin nibh. Venenatis lectus magna fringilla urna porttitor rhoncus dolor purus non. Vel pharetra vel turpis nunc eget lorem. Ut faucibus pulvinar elementum integer enim neque volutpat ac. Elit ullamcorper dignissim cras tincidunt. [[Posuere sollicitudin aliquam]] ultrices sagittis orci a scelerisque. Rhoncus aenean vel elit scelerisque mauris. Ultrices neque ornare aenean euismod. Nisi quis eleifend quam adipiscing vitae proin. Sem nulla pharetra diam sit amet nisl suscipit adipiscing. Mattis rhoncus urna neque viverra justo nec ultrices. diff --git a/site/content/notes/lobortis.md b/site/content/notes/lobortis.md deleted file mode 100644 index b861d61..0000000 --- a/site/content/notes/lobortis.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: lobortis -date: 2024-02-02 -type: zettler -head: false ---- - -This is back to the head [[Lorem Ipsum]] diff --git a/site/layout/note.html b/site/layout/note.html new file mode 100644 index 0000000..6b0746d --- /dev/null +++ b/site/layout/note.html @@ -0,0 +1,67 @@ +{{ define "note"}} +{{$PageData := index .DeepDataMerge.Notes .PageURL}} +{{ template "head" .}} + + + + {{template "header" .}} +
+
+ {{ if eq $PageData.Frontmatter.Type "post" }} +
+

{{ $PageData.Frontmatter.Title }}

+
+

+ Published on {{$PageData.Frontmatter.Date}} + + {{ if eq (len $PageData.Frontmatter.Authors) 0 }} + {{.DeepDataMerge.LayoutConfig.Author}} + {{ else }} + {{range $PageData.Frontmatter.Authors }} + {{ . }}, + {{ end }} + {{ end }} +

+
+
+ {{range $PageData.Frontmatter.Tags}} +
+ {{.}} +
+ {{end}} +
+
+ {{ else }} + {{ end }} + {{$PageData.Body}} +
+ +
+
+

Related Posts

+ {{range index .DeepDataMerge.LinkStore .PageURL }} + +
+

{{ .Frontmatter.Title }}

+

{{ .Frontmatter.Description }}

+

{{ printf "%10s" .Body }}

+

{{ .Frontmatter.Date }}

+
+
+ {{end}} +
+
+ {{template "footer" .}} + + + + +{{ end}} diff --git a/site/static/index.json b/site/static/index.json index 8dfa96c..a66a6b0 100644 --- a/site/static/index.json +++ b/site/static/index.json @@ -1 +1 @@ -{"docs.html":{"CompleteURL":"docs.html","Frontmatter":{"Title":"Anna Documentation","Date":"2024-04-10","Draft":false,"JSFiles":null,"Type":"","Description":"","PreviewImage":"","Tags":null,"Authors":null},"Tags":null},"index.html":{"CompleteURL":"index.html","Frontmatter":{"Title":"Home","Date":"2024-02-24","Draft":false,"JSFiles":null,"Type":"","Description":"homepage for our ssg","PreviewImage":"/static/plane.jpg","Tags":null,"Authors":null},"Tags":null},"posts/bench.html":{"CompleteURL":"posts/bench.html","Frontmatter":{"Title":"benchmark","Date":"2024-01-01","Draft":false,"JSFiles":null,"Type":"post","Description":"","PreviewImage":"","Tags":["test-post"],"Authors":null},"Tags":["test-post"]},"posts/building_anna.html":{"CompleteURL":"posts/building_anna.html","Frontmatter":{"Title":"Building anna","Date":"2024-04-04","Draft":false,"JSFiles":null,"Type":"post","Description":"This page contains a post about anna, a static site generator written in Go. This team project was built as part of AIEP 2024","PreviewImage":"","Tags":["acm","hsp","go","tech","talk","aiep"],"Authors":["Adhesh","Aditya","Nathan","Anirudh"]},"Tags":["acm","hsp","go","tech","talk","aiep"]},"posts/week-1.html":{"CompleteURL":"posts/week-1.html","Frontmatter":{"Title":"Week-1 Progress","Date":"2024-03-18","Draft":false,"JSFiles":null,"Type":"post","Description":"","PreviewImage":"","Tags":["progress"],"Authors":["Adhesh","Aditya","Anirudh","Nathan"]},"Tags":["progress"]},"posts/week-2.html":{"CompleteURL":"posts/week-2.html","Frontmatter":{"Title":"Week-2 Progress","Date":"2024-03-25","Draft":false,"JSFiles":null,"Type":"post","Description":"","PreviewImage":"","Tags":["progress"],"Authors":["Adhesh","Aditya","Anirudh","Nathan"]},"Tags":["progress"]},"posts/week-3.html":{"CompleteURL":"posts/week-3.html","Frontmatter":{"Title":"Week-3 Progress","Date":"2024-04-01","Draft":false,"JSFiles":null,"Type":"post","Description":"","PreviewImage":"","Tags":["progress"],"Authors":["Adhesh","Aditya","Anirudh","Nathan"]},"Tags":["progress"]}} \ No newline at end of file +{"docs.html":{"CompleteURL":"docs.html","Frontmatter":{"Title":"Anna Documentation","Date":"2024-04-10","Draft":false,"JSFiles":null,"Type":"page","Description":"","PreviewImage":"","Tags":null,"Authors":null,"Head":false},"Tags":null},"index.html":{"CompleteURL":"index.html","Frontmatter":{"Title":"Home","Date":"2024-02-24","Draft":false,"JSFiles":null,"Type":"page","Description":"homepage for our ssg","PreviewImage":"/static/plane.jpg","Tags":null,"Authors":null,"Head":false},"Tags":null},"posts/bench.html":{"CompleteURL":"posts/bench.html","Frontmatter":{"Title":"benchmark","Date":"2024-01-01","Draft":false,"JSFiles":null,"Type":"post","Description":"","PreviewImage":"","Tags":["test-post"],"Authors":null,"Head":false},"Tags":["test-post"]},"posts/building_anna.html":{"CompleteURL":"posts/building_anna.html","Frontmatter":{"Title":"Building anna","Date":"2024-04-04","Draft":false,"JSFiles":null,"Type":"post","Description":"This page contains a post about anna, a static site generator written in Go. This team project was built as part of AIEP 2024","PreviewImage":"","Tags":["acm","hsp","go","tech","talk","aiep"],"Authors":["Adhesh","Aditya","Nathan","Anirudh"],"Head":false},"Tags":["acm","hsp","go","tech","talk","aiep"]},"posts/week-1.html":{"CompleteURL":"posts/week-1.html","Frontmatter":{"Title":"Week-1 Progress","Date":"2024-03-18","Draft":false,"JSFiles":null,"Type":"post","Description":"","PreviewImage":"","Tags":["progress"],"Authors":["Adhesh","Aditya","Anirudh","Nathan"],"Head":false},"Tags":["progress"]},"posts/week-2.html":{"CompleteURL":"posts/week-2.html","Frontmatter":{"Title":"Week-2 Progress","Date":"2024-03-25","Draft":false,"JSFiles":null,"Type":"post","Description":"","PreviewImage":"","Tags":["progress"],"Authors":["Adhesh","Aditya","Anirudh","Nathan"],"Head":false},"Tags":["progress"]},"posts/week-3.html":{"CompleteURL":"posts/week-3.html","Frontmatter":{"Title":"Week-3 Progress","Date":"2024-04-01","Draft":false,"JSFiles":null,"Type":"post","Description":"","PreviewImage":"","Tags":["progress"],"Authors":["Adhesh","Aditya","Anirudh","Nathan"],"Head":false},"Tags":["progress"]},"posts/zettel_impl.html":{"CompleteURL":"posts/zettel_impl.html","Frontmatter":{"Title":"Implementing Zettelkasten in Anna","Date":"2024-04-10","Draft":false,"JSFiles":null,"Type":"post","Description":"This post focuses of the Proof of Concept behind how we plan to integrate zettelkasten in anna(our SSG) and implementing the new note taking functionality, supporting a new version of *Deep Data Merge* along with","PreviewImage":"","Tags":["blog","tech","aiep"],"Authors":["Aditya Hegde","Anirudh Sudhir"],"Head":false},"Tags":["blog","tech","aiep"]}} \ No newline at end of file diff --git a/site/static/scripts/graph.js b/site/static/scripts/graph.js index 462d03a..2059a82 100644 --- a/site/static/scripts/graph.js +++ b/site/static/scripts/graph.js @@ -89,7 +89,7 @@ async function onClick(event, d) { if (commonPosts.length === 0 && d.group !== 0) { const nodeName = d.id.replace(/\.md$/, ""); // Remove the ".md" extension from the node name (eh) - window.location.href = `/posts/${nodeName}.html`; // If it's a leaf node, automatically redirect + window.location.href = `/${nodeName}`; // If it's a leaf node, automatically redirect } else { setupGraph(); diff --git a/test/engine/json_index_test/want_index.json b/test/engine/json_index_test/want_index.json index 317502d..ae28840 100644 --- a/test/engine/json_index_test/want_index.json +++ b/test/engine/json_index_test/want_index.json @@ -1 +1 @@ -{"docs.md":{"CompleteURL":"docs.html","Frontmatter":{"Title":"Anna Documentation","Date":"","Draft":false,"JSFiles":null,"Type":"","Description":"","PreviewImage":"","Tags":null,"Authors":null},"Tags":null}} \ No newline at end of file +{"docs.md":{"CompleteURL":"docs.html","Frontmatter":{"Title":"Anna Documentation","Date":"","Draft":false,"JSFiles":null,"Type":"","Description":"","PreviewImage":"","Tags":null,"Authors":null,"Head":false},"Tags":null}}