Skip to main content
Glama
search.go2.92 kB
package search import ( "fmt" "regexp" "strings" "github.com/mholzen/workflowy/pkg/workflowy" ) type Result struct { ID string `json:"id"` Name string `json:"name"` HighlightedName string `json:"highlighted_name"` URL string `json:"url"` MatchPositions []MatchPosition `json:"match_positions"` } func (r Result) String() string { return fmt.Sprintf("- [%s](%s)", r.HighlightedName, r.URL) } type MatchPosition struct { Start int `json:"start"` End int `json:"end"` } func SearchItems(items []*workflowy.Item, pattern string, useRegexp, ignoreCase bool) []Result { var results []Result for _, item := range items { collectSearchResults(item, pattern, useRegexp, ignoreCase, &results) } return results } func collectSearchResults(item *workflowy.Item, pattern string, useRegexp, ignoreCase bool, results *[]Result) { name := item.Name matchPositions := FindMatches(name, pattern, useRegexp, ignoreCase) if len(matchPositions) > 0 { highlightedName := HighlightMatches(name, matchPositions) *results = append(*results, Result{ ID: item.ID, Name: name, HighlightedName: highlightedName, URL: fmt.Sprintf("https://workflowy.com/#/%s", item.ID), MatchPositions: matchPositions, }) } for _, child := range item.Children { collectSearchResults(child, pattern, useRegexp, ignoreCase, results) } } func FindMatches(text, pattern string, useRegexp, ignoreCase bool) []MatchPosition { var positions []MatchPosition if useRegexp { re, err := CompileRegexp(pattern, ignoreCase) if err != nil { return positions } matches := re.FindAllStringIndex(text, -1) for _, match := range matches { positions = append(positions, MatchPosition{Start: match[0], End: match[1]}) } } else { searchText := text searchPattern := pattern if ignoreCase { searchText = strings.ToLower(text) searchPattern = strings.ToLower(pattern) } start := 0 for { index := strings.Index(searchText[start:], searchPattern) if index == -1 { break } absIndex := start + index positions = append(positions, MatchPosition{ Start: absIndex, End: absIndex + len(pattern), }) start = absIndex + len(pattern) } } return positions } func CompileRegexp(pattern string, ignoreCase bool) (*regexp.Regexp, error) { if ignoreCase { pattern = "(?i)" + pattern } return regexp.Compile(pattern) } func HighlightMatches(text string, positions []MatchPosition) string { if len(positions) == 0 { return text } var result strings.Builder lastEnd := 0 for _, pos := range positions { result.WriteString(text[lastEnd:pos.Start]) result.WriteString("**") result.WriteString(text[pos.Start:pos.End]) result.WriteString("**") lastEnd = pos.End } result.WriteString(text[lastEnd:]) return result.String() }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mholzen/workflowy'

If you have feedback or need assistance with the MCP directory API, please join our Discord server