remove quit channels

This commit is contained in:
dre 2021-07-04 13:26:30 +08:00
parent f2b7adba1f
commit 45d7c25206
2 changed files with 44 additions and 63 deletions

38
main.go
View file

@ -35,16 +35,15 @@ func writer(out string) (io.Writer, error) {
}
func write(w io.Writer, b []byte) {
fmt.Fprintf(w, string(b))
fmt.Fprint(w, string(b))
}
type ir struct {
r io.Reader
quit chan struct{}
r io.Reader
}
func NewIr(r io.Reader, quit chan struct{}) *ir {
return &ir{r: r, quit: quit}
func NewIr(r io.Reader) *ir {
return &ir{r: r}
}
func (m *ir) Output() chan []byte {
@ -54,28 +53,22 @@ func (m *ir) Output() chan []byte {
for s.Scan() {
data <- s.Bytes()
}
close(m.quit)
close(data)
}()
return data
}
type ow struct {
w io.Writer
quit chan struct{}
w io.Writer
}
func NewOw(w io.Writer, quit chan struct{}) *ow {
return &ow{w: w, quit: quit}
func NewOw(w io.Writer) *ow {
return &ow{w: w}
}
func (m *ow) Input(data chan []byte) {
for {
select {
case <-m.quit:
return
case b := <-data:
write(m.w, b)
}
for b := range data {
write(m.w, b)
}
}
@ -86,8 +79,6 @@ func main() {
flag.StringVar(&out, "out", "", "specify a .gmi (gemtext) file to write to, otherwise stdout (default)")
flag.Parse()
quit := make(chan struct{})
r, err := reader(in)
if err != nil {
fmt.Fprint(os.Stderr, err.Error())
@ -100,10 +91,9 @@ func main() {
os.Exit(1)
}
source := NewIr(r, quit)
sink := NewOw(w, quit)
source := NewIr(r)
sink := NewOw(w)
preproc := NewParser()
sink.Input(source.Output())
//NewParser(data, w, quit).Parse()
sink.Input(preproc.Parse(source.Output()))
}

View file

@ -1,51 +1,43 @@
package main
import (
"fmt"
"io"
)
// state function
type stateFn func(*fsm, []byte) stateFn
// state machine
type fsm struct {
state stateFn
buffer []byte
out io.Writer
quit chan struct{}
data <-chan []byte
state stateFn
out chan []byte
// if we have a nested state, e.g. a link inside a paragraph
returnState stateFn
// combining multiple input lines
buffer []byte
// if we have a termination rule to abide, e.g. implied code fences
pending []byte
}
func NewParser(data <-chan []byte, writer io.Writer, quit chan struct{}) *fsm {
return &fsm{
out: writer,
data: data,
quit: quit,
}
func NewParser() *fsm {
return &fsm{}
}
func (m *fsm) Parse() {
var line []byte
for m.state = normal; m.state != nil; {
select {
case <-m.quit:
m.flush()
m.state = nil
case line = <-m.data:
m.state = m.state(m, line)
func (m *fsm) Parse(in chan []byte) chan []byte {
m.out = make(chan []byte)
go func() {
for m.state = normal; m.state != nil; {
b, ok := <-in
if !ok {
m.flush()
close(m.out)
m.state = nil
continue
}
m.state = m.state(m, b)
}
}
}()
return m.out
}
func (m *fsm) flush() {
if len(m.pending) > 0 {
fmt.Fprintf(m.out, string(m.pending)+"\n")
m.out <- append(m.pending, '\n')
m.pending = m.pending[:0]
}
}
@ -74,21 +66,21 @@ func normal(m *fsm, data []byte) stateFn {
m.flush()
// blank line
if isBlank(data) {
fmt.Fprintf(m.out, "\n")
m.out <- []byte("\n")
return normal
}
// header
if isHeader(data) {
fmt.Fprintf(m.out, string(data)+"\n")
m.out <- append(data, '\n')
return normal
}
if isFence(data) {
fmt.Fprintf(m.out, string(data)+"\n")
m.out <- append(data, '\n')
return fence
}
if needsFence(data) {
fmt.Fprintf(m.out, string("```")+"\n")
fmt.Fprintf(m.out, string(data)+"\n")
m.out <- []byte("```\n")
m.out <- append(data, '\n')
m.pending = []byte("```")
return toFence
}
@ -99,13 +91,13 @@ func normal(m *fsm, data []byte) stateFn {
// TODO
// find links
// collapse lists
fmt.Fprintf(m.out, string(data)+"\n")
m.out <- append(data, '\n')
return normal
}
func fence(m *fsm, data []byte) stateFn {
fmt.Fprintf(m.out, string(data)+"\n")
m.out <- append(data, '\n')
if isFence(data) {
return normal
}
@ -113,18 +105,17 @@ func fence(m *fsm, data []byte) stateFn {
}
func toFence(m *fsm, data []byte) stateFn {
m.out <- append(data, '\n')
if needsFence(data) {
fmt.Fprintf(m.out, string(data)+"\n")
return toFence
}
fmt.Fprintf(m.out, string(data)+"\n")
return normal
}
func paragraph(m *fsm, data []byte) stateFn {
if triggerBreak(data) {
m.buffer = append(m.buffer, data...)
fmt.Fprintf(m.out, string(m.buffer)+"\n")
m.out <- append(m.buffer, '\n')
m.buffer = m.buffer[:0]
return normal
}