miki

Miki: personal wiki with the fmd markup format
git clone https://wtenison.com/repo/miki.git
Log | Files | Refs | README | LICENSE

commit ebf601d0429409d0a53f75801afc26ca92f4fc23
parent 02c91ecfff01f2b61607b2968460a5e72fe22e3e
Author: weetat <wtenison@protonmail.com>
Date:   Sat,  1 Mar 2025 19:54:51 +0000

Fix double line breaks and generate README from fmd

Skip the <br> when the previous node was also a newline. README.md is
now generated from data/README.fmd.

Diffstat:
MREADME.md | 19+++++++++++++++----
Msrc/fmd/fmd_test.go | 25++++++++++++-------------
Msrc/fmd/interpreter.go | 6+++++-
Msrc/fmd/lexer.go | 5++++-
Msrc/fmd/parser.go | 15++++++++++++---
5 files changed, 48 insertions(+), 22 deletions(-)

diff --git a/README.md b/README.md @@ -1,5 +1,16 @@ -# miki +<h1>Miki</h1> <br> -A personal wiki project. +This is a personal educational and quality of life project.<br> +The goal is to produce a web application with which I may<br> +conviently create and view documentation, notes, and eventualy<br> +list collections (for things such as TODO, contacts, etc.).<br> -<div>test</div> -\ No newline at end of file +For this project I am using my own "Markdown" format called<br> +<i>fmd</i>, which this README is generated from. It is my attempt<br> +to produce a form of Markdown for myself that is readable<br> +and practically customizable within reason.<br> + +I have spend far more time on producing working code than<br> +documentation at this point, but it is on my TODO list.<br> +Bear with me, thank you for your patience, and thank you<br> +for taking a look around. +\ No newline at end of file diff --git a/src/fmd/fmd_test.go b/src/fmd/fmd_test.go @@ -1,30 +1,29 @@ package fmd import ( - "os" "testing" ) func TestFMD(t *testing.T) { - _path := ("/home/weetat/projects/miki/data/fmd/home.fmd") + _path := ("/home/weetat/projects/miki/data/README.fmd") t.Log("Path:", _path) - // WriteFMDtoHTMLFile(_path) + // WriteFMDToHTMLFile(_path, "/home/weetat/projects/miki/README.md") - _input, _err := os.ReadFile(_path) - if _err != nil { - t.Error("_ERROR\tcannot open file:", _err.Error()) - return - } + // _input, _err := os.ReadFile(_path) + // if _err != nil { + // t.Error("_ERROR\tcannot open file:", _err.Error()) + // return + // } - _l := MakeLexer(_input) - _tokens := _l.Exec() + // _l := MakeLexer(_input) + // _tokens := _l.Exec() // t.Log("Tokens:", _tokens) - _p := MakeParser(_tokens) - _ast := _p.Exec() + // _p := MakeParser(_tokens) + // _ast := _p.Exec() // t.Log("AST:", _ast) - t.Log("HTML:\n", interpret(_ast)) + // t.Log("HTML:\n", interpret(_ast)) } diff --git a/src/fmd/interpreter.go b/src/fmd/interpreter.go @@ -62,7 +62,11 @@ func interpret(n node) string { case nSpacing: return n.value case nNewline: - return "<br>\n" + if n.pNode.nType != nNewline { + return "<br>\n" + } else { + return "\n" + } case nWord: if slices.Contains(invalidHTML, n.value) { return "" diff --git a/src/fmd/lexer.go b/src/fmd/lexer.go @@ -38,7 +38,7 @@ type token struct { } var operatorSymbols = []string{"\\", ":", "{", "}", "(", ")"} -var spacingSymbols = []string{" ", "\n", "\t"} +var spacingSymbols = []string{" ", "\n", "\t", ","} var keywords = []string{ "b", // bold "i", // italic @@ -93,6 +93,9 @@ func (l *lexer) Exec() []token { case _currentSymbol == ')': l.tokens = append(l.tokens, token{tRParen, ")"}) l.pos++ + case _currentSymbol == ',': + l.tokens = append(l.tokens, token{tWord, ","}) + l.pos++ default: { // NOTE: inlined check until good reason to abstract arrives. _start := l.pos diff --git a/src/fmd/parser.go b/src/fmd/parser.go @@ -25,6 +25,7 @@ const ( type node struct { nType nodeType value string + pNode *node children []node } @@ -32,6 +33,7 @@ type parser struct { tokens []token pos int depth int + pNode *node errorNodes []node } @@ -123,6 +125,10 @@ func (p *parser) parseBody() node { _body.children = append(_body.children, p.makeNode(nSpacing, p.consume(tTab))) case tNewline: _body.children = append(_body.children, p.makeNode(nNewline, p.consume(tNewline))) + case tLParen: + _body.children = append(_body.children, p.makeNode(nWord, p.consume(tLParen))) + case tRParen: + _body.children = append(_body.children, p.makeNode(nWord, p.consume(tRParen))) case tEscape: p.consume(tEscape) case tColon: @@ -137,7 +143,7 @@ func (p *parser) parseBody() node { } else { _body.children = append(_body.children, p.makeNode(nError, token{tType: tError, Value: "unknown token;"})) p.pos += 1 - log.Printf("INFO:block:error:%s", _body.children[len(_body.children)-1]) + log.Printf("INFO:block:error:%v", _body.children[len(_body.children)-1]) } } } @@ -148,12 +154,15 @@ func (p *parser) parseBody() node { //// UTILITY FUNCTIONS func (p *parser) makeNode(nType nodeType, iToken token) node { + _n := node{nType: nType, value: iToken.Value} if iToken.tType == tError { - return p.errorNode(iToken.Value) + _n = p.errorNode(iToken.Value) } - _n := node{nType: nType, value: iToken.Value} + _n.pNode = p.pNode + p.pNode = &_n + return _n }