header.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. package goorgeous
  2. import (
  3. "bufio"
  4. "bytes"
  5. "regexp"
  6. "strings"
  7. )
  8. // ExtractOrgHeaders finds and returns all of the headers
  9. // from a bufio.Reader and returns them as their own byte slice
  10. func ExtractOrgHeaders(r *bufio.Reader) (fm []byte, err error) {
  11. var out bytes.Buffer
  12. endOfHeaders := true
  13. for endOfHeaders {
  14. p, err := r.Peek(2)
  15. if err != nil {
  16. return nil, err
  17. }
  18. if !charMatches(p[0], '#') && !charMatches(p[1], '+') {
  19. endOfHeaders = false
  20. break
  21. }
  22. line, _, err := r.ReadLine()
  23. if err != nil {
  24. return nil, err
  25. }
  26. out.Write(line)
  27. out.WriteByte('\n')
  28. }
  29. return out.Bytes(), nil
  30. }
  31. var reHeader = regexp.MustCompile(`^#\+(\w+?): (.*)`)
  32. // OrgHeaders find all of the headers from a byte slice and returns
  33. // them as a map of string interface
  34. func OrgHeaders(input []byte) (map[string]interface{}, error) {
  35. out := make(map[string]interface{})
  36. scanner := bufio.NewScanner(bytes.NewReader(input))
  37. for scanner.Scan() {
  38. data := scanner.Bytes()
  39. if !charMatches(data[0], '#') && !charMatches(data[1], '+') {
  40. return out, nil
  41. }
  42. matches := reHeader.FindSubmatch(data)
  43. if len(matches) < 3 {
  44. continue
  45. }
  46. key := string(matches[1])
  47. val := matches[2]
  48. switch {
  49. case strings.ToLower(key) == "tags" || strings.ToLower(key) == "categories" || strings.ToLower(key) == "aliases":
  50. bTags := bytes.Split(val, []byte(" "))
  51. tags := make([]string, len(bTags))
  52. for idx, tag := range bTags {
  53. tags[idx] = string(tag)
  54. }
  55. out[key] = tags
  56. default:
  57. out[key] = string(val)
  58. }
  59. }
  60. return out, nil
  61. }