diff --git a/class.go b/class.go index 8881e8e..6f33fa2 100644 --- a/class.go +++ b/class.go @@ -132,7 +132,29 @@ func ParseClass(file string) (*Class, error) { } res.Description = classDescription - spew.Dump(res) + constructor, err := getConstructor(dataContainer) + if err != nil { + return nil, fmt.Errorf("error getting constructor: %w", err) + } + constructor = constructor + + // Doing div+div specifically skips only the constructor which is usually the first div + // So the constructor would then be located at h1 + p + div OR h1 + div if there is no description (no p) + dataElements := dataContainer.ChildrenFiltered("div + div") + if dataElements.Length() == 0 { + return nil, fmt.Errorf("no data elements found") + } + + dataElements.Each(func(i int, s *goquery.Selection) { + id, ok := s.Attr("id") + if !ok { + return + } + if id == "Properties" { + // TODO: Implement parsing properties + } + }) + return &res, nil } @@ -152,14 +174,91 @@ func getClassDescription(dataContainer *goquery.Selection) (string, error) { if class.Length() == 0 { return "", fmt.Errorf("no class description found") } - res := strings.TrimSpace(class.Text()) - res = strings.ReplaceAll(res, "\t", " ") - res = strings.ReplaceAll(res, "\n", "") - res = manySpaceRe.ReplaceAllString(res, " ") - res = strings.ReplaceAll(res, ". ", "\n--") + res := CleanUp(class.Text()) return res, nil } +func getConstructor(dataContainer *goquery.Selection) (Constructor, error) { + resConstructor := Constructor{} + + constructorBlock := dataContainer.Find("h1 + p + div") + if constructorBlock.Length() == 0 { + constructorBlock = dataContainer.Find("h1 + div") + if constructorBlock.Length() == 0 { + return resConstructor, fmt.Errorf("no constructor found") + } + } + + types := constructorBlock.Find("div.function span.type") + if types.Length() == 0 { + return resConstructor, fmt.Errorf("no types found") + } + params := constructorBlock.Find("div.function span.parameter") + if params.Length() == 0 { + return resConstructor, fmt.Errorf("no params found") + } + + types.Each(func(i int, s *goquery.Selection) { + resConstructor.Params = append(resConstructor.Params, Param{ + Name: strings.TrimSpace(params.Eq(i).Text()), + Type: strings.TrimSpace(types.Eq(i).Text()), + Comment: "", + }) + }) + + descriptor := constructorBlock.Find("div:not(.function)") + if descriptor.Length() == 0 { + return resConstructor, fmt.Errorf("no descriptor found") + } + + // 0 nothing + // 1 parameters + // 2 returns + state := 0 + children := descriptor.Children() + childrenLength := children.Length() + children.Each(func(i int, s *goquery.Selection) { + if i == childrenLength-1 { + // For some stupid reason the last child is always a mispalced

tag that does not close any open

+ // I assume this is a bug with their documentation generator + // So we just ignore it + return + } + text := strings.TrimSpace(s.Text()) + if text == "" { + return + } + if s.Is("p") { + switch text { + case "Parameters": + state = 1 + return + case "Returns": + state = 2 + return + } + } else { + switch state { + case 0: + return + case 1: + param := s.ChildrenFiltered("span.parameter").Text() + paramTrimmed := strings.TrimSpace(param) + for i := range resConstructor.Params { + cparam := &resConstructor.Params[i] + if paramTrimmed == cparam.Name { + cleanText := strings.TrimPrefix(text, param) + cparam.Comment = CleanUp(cleanText) + } + } + } + } + }) + + spew.Dump(resConstructor) + return resConstructor, nil +} + // TODO: Implement parsing comments for return values // Something like "---returns (something) -> comment" // Where "-> comment" is only shown if there's a comment @@ -257,3 +356,12 @@ func getMethods(doc *goquery.Document) ([]Method, error) { return res, nil } + +func CleanUp(s string) string { + s = strings.TrimSpace(s) + s = strings.ReplaceAll(s, "\t", " ") + s = strings.ReplaceAll(s, "\n", "") + s = manySpaceRe.ReplaceAllString(s, " ") + s = strings.ReplaceAll(s, ". ", "\n--") + return s +} diff --git a/test.html b/test.html index db1bd54..9401a33 100644 --- a/test.html +++ b/test.html @@ -207,7 +207,7 @@

Parameters

- id + name The id of the entity this component belongs to, or the entity itself, must be an id of an existing entity or nil for the entity in the current script context