md2gmi/main.go

145 lines
2.2 KiB
Go
Raw Normal View History

2021-07-03 18:26:27 +03:00
package main
import (
"bufio"
2021-07-04 15:31:45 +03:00
"bytes"
"encoding/gob"
2021-07-03 18:26:27 +03:00
"flag"
"fmt"
"io"
"os"
)
2021-07-04 15:31:45 +03:00
type WorkItem struct {
index int
payload []byte
}
func New(index int, payload []byte) WorkItem {
w := WorkItem{index: index}
var indexBuffer bytes.Buffer
encoder := gob.NewEncoder(&indexBuffer)
if err := encoder.Encode(payload); err != nil {
panic(err)
}
w.payload = indexBuffer.Bytes()
return w
}
func (w *WorkItem) Index() int {
return w.index
}
func (w *WorkItem) Payload() []byte {
buf := bytes.NewReader(w.payload)
decoder := gob.NewDecoder(buf)
var tmp []byte
if err := decoder.Decode(&tmp); err != nil {
panic(err)
}
return tmp
}
2021-07-04 07:43:13 +03:00
func reader(in string) (io.Reader, error) {
2021-07-03 18:26:27 +03:00
if in != "" {
file, err := os.Open(in)
if err != nil {
2021-07-04 07:43:13 +03:00
return nil, err
2021-07-03 18:26:27 +03:00
}
2021-07-04 07:43:13 +03:00
return file, nil
2021-07-03 18:26:27 +03:00
}
2021-07-04 07:43:13 +03:00
return os.Stdin, nil
2021-07-03 18:26:27 +03:00
}
func writer(out string) (io.Writer, error) {
if out != "" {
2021-07-04 09:16:55 +03:00
file, err := os.Create(out)
2021-07-03 18:26:27 +03:00
if err != nil {
return nil, err
}
return file, nil
}
return os.Stdout, nil
}
2021-07-04 07:31:51 +03:00
func write(w io.Writer, b []byte) {
2021-07-04 08:26:30 +03:00
fmt.Fprint(w, string(b))
2021-07-04 07:31:51 +03:00
}
2021-07-04 07:43:13 +03:00
type ir struct {
2021-07-04 08:26:30 +03:00
r io.Reader
2021-07-04 07:43:13 +03:00
}
2021-07-04 09:16:55 +03:00
func InputStream(r io.Reader) *ir {
2021-07-04 08:26:30 +03:00
return &ir{r: r}
2021-07-04 07:43:13 +03:00
}
2021-07-04 15:31:45 +03:00
func (m *ir) Output() chan WorkItem {
data := make(chan WorkItem)
2021-07-04 07:43:13 +03:00
s := bufio.NewScanner(m.r)
go func() {
2021-07-04 15:31:45 +03:00
i := 0
2021-07-04 07:43:13 +03:00
for s.Scan() {
2021-07-04 15:31:45 +03:00
data <- New(i, s.Bytes())
i += 1
2021-07-04 07:43:13 +03:00
}
2021-07-04 08:26:30 +03:00
close(data)
2021-07-04 07:43:13 +03:00
}()
return data
}
2021-07-04 07:31:51 +03:00
type ow struct {
2021-07-04 08:26:30 +03:00
w io.Writer
2021-07-04 07:31:51 +03:00
}
2021-07-04 09:16:55 +03:00
func OutputStream(w io.Writer) *ow {
2021-07-04 08:26:30 +03:00
return &ow{w: w}
2021-07-04 07:31:51 +03:00
}
2021-07-04 15:31:45 +03:00
func (m *ow) Input(data chan WorkItem) {
2021-07-04 08:26:30 +03:00
for b := range data {
2021-07-04 15:31:45 +03:00
write(m.w, b.Payload())
2021-07-04 07:31:51 +03:00
}
}
2021-07-03 18:26:27 +03:00
func main() {
var in, out string
2021-07-04 09:16:55 +03:00
flag.StringVar(&in, "f", "", "specify a .md (Markdown) file to read from, otherwise stdin (default)")
flag.StringVar(&out, "o", "", "specify a .gmi (gemtext) file to write to, otherwise stdout (default)")
2021-07-03 18:26:27 +03:00
flag.Parse()
2021-07-04 07:43:13 +03:00
r, err := reader(in)
if err != nil {
fmt.Fprint(os.Stderr, err.Error())
os.Exit(1)
}
2021-07-03 18:26:27 +03:00
2021-07-04 07:43:13 +03:00
w, err := writer(out)
if err != nil {
fmt.Fprint(os.Stderr, err.Error())
os.Exit(1)
2021-07-03 18:26:27 +03:00
}
2021-07-04 07:43:13 +03:00
2021-07-04 09:16:55 +03:00
source := InputStream(r)
sink := OutputStream(w)
preproc := NewPreproc()
2021-07-04 07:43:13 +03:00
2021-07-04 09:16:55 +03:00
//sink.Input(preproc.Process(source.Output()))
2021-07-04 10:50:08 +03:00
sink.Input(
2021-07-04 15:31:45 +03:00
FormatLinks(
2021-07-04 10:50:08 +03:00
FormatHeadings(
2021-07-04 15:31:45 +03:00
RemoveComments(
RemoveFrontMatter(
preproc.Process(source.Output()),
),
2021-07-04 10:50:08 +03:00
),
),
),
)
2021-07-03 18:26:27 +03:00
}