toy with some ideas
This commit is contained in:
parent
8cf2d4eb73
commit
2cc007629d
4 changed files with 63 additions and 6 deletions
15
README.md
15
README.md
|
@ -1,11 +1,20 @@
|
|||
## md2gmi
|
||||
|
||||
Convert Markdown to Gemini Gemini [gemtext](https://gemini.circumlunar.space/docs/gemtext.gmi)
|
||||
markup with Go. Working with streams and pipes for UNIX like behavior utilizing Go channels.
|
||||
Convert Markdown to Gemini [gemtext](https://gemini.circumlunar.space/docs/gemtext.gmi) markup with
|
||||
Go. Working with streams and pipes for UNIX like behavior utilizing Go channels. Processing streams
|
||||
line by line is deliberately slightly more challenging than it needs to be to play around with go
|
||||
state machines.
|
||||
|
||||
<!-- testing markdown, this should be deleted, below merged -->
|
||||
See the [gemini
|
||||
protocol](https://gemini.circumlunar.space/).
|
||||
|
||||
Internally md2gmi does a 1st pass that constructs the core layout for gemtext. This is then streamed
|
||||
to the 2nd pass line by line. The 2nd pass will convert links and stream line by line to the output.
|
||||
|
||||
### Usage
|
||||
|
||||
```
|
||||
```plain
|
||||
Usage of ./md2gmi:
|
||||
-in string
|
||||
specify a .md (Markdown) file to read from, otherwise stdin (default)
|
||||
|
|
33
main.go
33
main.go
|
@ -45,13 +45,40 @@ func writer(out string) (io.Writer, error) {
|
|||
return os.Stdout, nil
|
||||
}
|
||||
|
||||
func write(out string, data <-chan []byte, quit chan struct{}) error {
|
||||
func write(w io.Writer, b []byte) {
|
||||
fmt.Fprintf(w, string(b))
|
||||
}
|
||||
|
||||
type ow struct {
|
||||
w io.Writer
|
||||
quit chan struct{}
|
||||
}
|
||||
|
||||
func NewOw(w io.Writer, quit chan struct{}) *ow {
|
||||
return &ow{w: w, quit: quit}
|
||||
}
|
||||
|
||||
func (m *ow) Input(data <-chan []byte) {
|
||||
for {
|
||||
select {
|
||||
case <-m.quit:
|
||||
return
|
||||
case b := <-data:
|
||||
write(m.w, b)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func writesetup(out string, data <-chan []byte, quit chan struct{}) error {
|
||||
w, err := writer(out)
|
||||
if err != nil {
|
||||
return fmt.Errorf("writer: %w", err)
|
||||
}
|
||||
|
||||
NewParser(data, w, quit).Parse()
|
||||
sink := NewOw(w, quit)
|
||||
sink.Input(data)
|
||||
|
||||
//NewParser(data, w, quit).Parse()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -73,7 +100,7 @@ func main() {
|
|||
close(quit)
|
||||
}()
|
||||
|
||||
if err := write(out, data, quit); err != nil {
|
||||
if err := writesetup(out, data, quit); err != nil {
|
||||
fmt.Fprintf(os.Stderr, err.Error())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,9 @@ type fsm struct {
|
|||
quit chan struct{}
|
||||
data <-chan []byte
|
||||
|
||||
// if we have a nested state, e.g. a link inside a paragraph
|
||||
returnState stateFn
|
||||
// if we have a termination rule to abide, e.g. implied code fences
|
||||
pending []byte
|
||||
}
|
||||
|
||||
|
@ -128,3 +131,8 @@ func paragraph(m *fsm, data []byte) stateFn {
|
|||
m.buffer = append(m.buffer, data...)
|
||||
return paragraph
|
||||
}
|
||||
|
||||
func link(m *fsm, data []byte) stateFn {
|
||||
|
||||
return link
|
||||
}
|
||||
|
|
13
pipeline.go
Normal file
13
pipeline.go
Normal file
|
@ -0,0 +1,13 @@
|
|||
package main
|
||||
|
||||
type Node interface {
|
||||
Pipeline(<-chan []byte) <-chan []byte
|
||||
}
|
||||
|
||||
type Source interface {
|
||||
Input() <-chan []byte
|
||||
}
|
||||
|
||||
type Sink interface {
|
||||
Output(<-chan []byte)
|
||||
}
|
Loading…
Reference in a new issue