/goswf.go

https://bitbucket.org/jrick/goswf · Go · 157 lines · 155 code · 2 blank · 0 comment · 0 complexity · 6939281ca214b71531a567347061a2ac MD5 · raw file

  1. package main
  2. import (
  3. "bufio"
  4. "bytes"
  5. "flag"
  6. "fmt"
  7. "github.com/knieriem/markdown"
  8. "html/template"
  9. "io"
  10. "os"
  11. "path/filepath"
  12. "regexp"
  13. "strings"
  14. )
  15. var (
  16. titleFlag = flag.String(`title`, `goswf`, `site title`)
  17. subtitleFlag = flag.String(`subtitle`, ``, `site subtitle`)
  18. dirFlag = flag.String(`in`, ``, `markdown file tree`)
  19. ignoreRegExp = flag.String(`ignore`, ``, `ignore regexp`)
  20. tmplFlag = flag.String(`tmpl`, ``, `template file`)
  21. mdParser = markdown.NewParser(&markdown.Extensions{Smart: true})
  22. mdExtMatch = regexp.MustCompile(`\.md$`)
  23. tmplParser *template.Template
  24. )
  25. type Navigation struct {
  26. Name string
  27. Link string
  28. }
  29. type PageItems struct {
  30. Title string
  31. SubTitle string
  32. Favicon string
  33. CSS string
  34. NavItems []Navigation
  35. Main template.HTML
  36. }
  37. func main() {
  38. flag.Parse()
  39. fi, err := os.Stat(*dirFlag)
  40. if err != nil || !fi.IsDir() {
  41. fmt.Fprintln(os.Stderr, `Fatal: -in flag unset or not a directory`)
  42. flag.Usage()
  43. os.Exit(1)
  44. }
  45. if *tmplFlag == "" {
  46. fmt.Fprintln(os.Stderr, `Fatal: -tmpl flag unset or not a file`)
  47. flag.Usage()
  48. os.Exit(1)
  49. }
  50. abs, _ := filepath.Abs(*dirFlag)
  51. dir, inDir := filepath.Split(abs)
  52. outDir := filepath.Join(dir, inDir+`.static`)
  53. if err = os.Chdir(dir); err != nil {
  54. panic(err)
  55. }
  56. if fi, err = os.Stat(outDir); err == nil {
  57. if err = os.RemoveAll(outDir); err != nil {
  58. panic(err)
  59. }
  60. }
  61. tmplParser, err = template.ParseFiles(*tmplFlag)
  62. if err != nil {
  63. panic(err)
  64. }
  65. filepath.Walk(filepath.Base(*dirFlag), mkPage)
  66. os.Exit(0)
  67. }
  68. func mkPage(srcPath string, info os.FileInfo, err error) error {
  69. if skip, err := regexp.MatchString(*ignoreRegExp, filepath.Base(srcPath)); err != nil {
  70. panic(err)
  71. } else if skip {
  72. return filepath.SkipDir
  73. }
  74. src, err := os.Open(srcPath)
  75. if err != nil {
  76. panic(err)
  77. }
  78. var writer *bufio.Writer
  79. if destPath, dest := getDest(srcPath); dest != nil {
  80. writer = bufio.NewWriter(dest)
  81. // writer flushes before dest closes
  82. defer dest.Close()
  83. defer func() {
  84. if writer != nil && err == nil {
  85. err = writer.Flush()
  86. if err != nil {
  87. panic(err)
  88. }
  89. }
  90. }()
  91. } else { // dest will be null if we're iterating over a directory
  92. if err = os.Mkdir(destPath, 0755); err != nil {
  93. panic(err)
  94. }
  95. return nil
  96. }
  97. pageElems := PageItems{
  98. Title: *titleFlag,
  99. SubTitle: *subtitleFlag,
  100. CSS: `/style.css`,
  101. }
  102. /* XXX: index and navitems
  103. dir, err := os.Open(filepath.Dir(srcPath))
  104. if err != nil {
  105. return err
  106. } else {
  107. defer dir.Close()
  108. }
  109. names, err := dir.Readdirnames(0)
  110. if err != nil {
  111. fmt.Println(err)
  112. }
  113. */
  114. switch filepath.Ext(srcPath) {
  115. case `.md`:
  116. buf := new(bytes.Buffer)
  117. mdParser.Markdown(src, markdown.ToHTML(buf))
  118. pageElems.Main = template.HTML(buf.String())
  119. if err = tmplParser.Execute(writer, pageElems); err != nil {
  120. panic(err)
  121. }
  122. default:
  123. io.Copy(writer, src)
  124. }
  125. return nil
  126. }
  127. func getDest(path string) (destPath string, dest *os.File) {
  128. parts := strings.Split(path, string(filepath.Separator))
  129. parts[0] = parts[0] + `.static`
  130. last := &parts[len(parts)-1]
  131. *last = mdExtMatch.ReplaceAllLiteralString(*last, `.html`)
  132. destPath = strings.Join(parts, string(filepath.Separator))
  133. fi, err := os.Stat(path)
  134. if err == nil && !fi.IsDir() {
  135. if dest, err = os.Create(destPath); err != nil {
  136. panic(err)
  137. }
  138. }
  139. return destPath, dest
  140. }