package tagc import ( "bufio" "fmt" "os" "path/filepath" "regexp" "strings" ) var ( commentRegexps []*regexp.Regexp sectionRegexps []*regexp.Regexp continuationRegexps []*regexp.Regexp ) // !MAN: Node Style getter/setter // Option 1: (2 args) .Style("background","yellow") -> "" -- Sets the inline value of background // Option 2: (1 args) .Style("background") -> "" -- Gets the inline value of background // Option 3: (0 args) .Style("background") -> "" -- Returns all inline styles as a string // [!DEVMAN]Note: Contains all user inputed styles, all inline styles over ride stylesheet styles func init() { commentPatterns := []string{ `^\s*//\s*!(\w+(?:,\w+)*):\s*(.*)$`, `^\s*# !(\w+):\s*(.*)$`, `^\s*; !(\w+):\s*(.*)$`, `^\s*% !(\w+):\s*(.*)$`, `^\s*-- !(\w+):\s*(.*)$`, `^\s*/\* !(\w+):\s*(.*)\*/`, `^\s*`, } sectionPatterns := []string{ `^\s*//\s*(?:\+\s*(?:\[([!?\w,]+)\](\w+)|(\w+))):\s*(.*)$`, `^\s*# \+\s*(\w+):\s*(.*)$`, `^\s*; +\s*(\w+):\s*(.*)$`, `^\s*% \+\s*(\w+):\s*(.*)$`, `^\s*-- \+\s*(\w+):\s*(.*)$`, `^\s*/\* \+\s*(\w+):\s*(.*)\*/`, `^\s*`, } continuationPatterns := []string{ `^\s*// \+\s*(.*)$`, `^\s*# \+\s*(.*)$`, `^\s*; \+\s*(.*)$`, `^\s*% \+\s*(.*)$`, `^\s*-- \+\s*(.*)$`, `^\s*/\* \+\s*(.*)\*/`, `^\s*`, } for i := range commentPatterns { commentRegexps = append(commentRegexps, regexp.MustCompile(commentPatterns[i])) sectionRegexps = append(sectionRegexps, regexp.MustCompile(sectionPatterns[i])) continuationRegexps = append(continuationRegexps, regexp.MustCompile(continuationPatterns[i])) } } type Comment struct { Tag string `json:"tag,omitempty" xml:"tag,omitempty" text:"Tag,omitempty"` File string `json:"file,omitempty" xml:"file,omitempty" text:"File,omitempty"` Line int `json:"line,omitempty" xml:"line,omitempty" text:"Line,omitempty"` Length int `json:"length,omitempty" xml:"length,omitempty" text:"Length,omitempty"` Data []string `json:"data,omitempty" xml:"data>item,omitempty" text:"Body,omitempty"` } func fileParser(path string) []Comment { file, err := os.Open(path) if err != nil { fmt.Println("Error opening file:", path, err) return []Comment{} } defer file.Close() scanner := bufio.NewScanner(file) lines := []string{} for scanner.Scan() { lines = append(lines, scanner.Text()) } return parse(path, lines) } func parse(path string, lines []string) []Comment { comments := []Comment{} var currentComment *Comment for lineNumber, line := range lines { for i := range commentRegexps { if matches := commentRegexps[i].FindStringSubmatch(line); matches != nil { if currentComment != nil { comments = append(comments, *currentComment) } currentComment = &Comment{ File: path, Line: lineNumber + 1, Length: 1, Tag: strings.Split(strings.TrimSpace(matches[1]), ",")[0], Data: []string{strings.TrimSpace(matches[2])}, } break } else if matches := sectionRegexps[i].FindStringSubmatch(line); matches != nil { if currentComment != nil { label := matches[2] if label == "" { label = matches[3] } if label == "" { label = "[" + matches[1] + "]" + matches[2] } // this is sjda test currentComment.Tag = label currentComment.Data = append(currentComment.Data, matches[4]) currentComment.Length += 1 } break } else if matches := continuationRegexps[i].FindStringSubmatch(line); matches != nil { if currentComment != nil { currentComment.Data[len(currentComment.Data)-1] += "\n" + matches[1] currentComment.Length += 1 } break } else if currentComment != nil { comments = append(comments, *currentComment) currentComment = nil } } } return comments } func loadPaths(root string) ([]string, error) { paths := []string{} err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error { if err != nil { return err } if strings.Contains(path, ".git") { return nil } if !info.IsDir() { paths = append(paths, path) } return nil }) return paths, err } func Read(path string, handle func(interface{})) error { file, err := os.Open(path) if err != nil { return err } fileInfo, err := file.Stat() if err != nil { return err } paths := []string{} if fileInfo.IsDir() { paths, err = loadPaths(path) if err != nil { return err } } else { paths = append(paths, path) } for _, v := range paths { p := fileParser(v) for _, c := range p { handle(c) } } return nil }