@@ -141,6 +141,65 @@ func resolveReadme(client *hfapi.Client, modelID string, hfTags []string) (strin
141141 return cleanTextContent (content ), nil
142142}
143143
144+ // extractDescription turns a raw HuggingFace README into a concise plain-text
145+ // description suitable for embedding in gallery/index.yaml: strips YAML
146+ // frontmatter, HTML tags/comments, markdown images, link URLs (keeping the
147+ // link text), markdown tables, and then truncates at a paragraph boundary
148+ // around ~1200 characters. Raw README should still be used for icon
149+ // extraction — call this only for the `description:` field.
150+ func extractDescription (readme string ) string {
151+ s := readme
152+
153+ // Strip leading YAML frontmatter: `---\n...\n---\n` at start of file.
154+ if strings .HasPrefix (strings .TrimLeft (s , " \t \n " ), "---" ) {
155+ trimmed := strings .TrimLeft (s , " \t \n " )
156+ rest := strings .TrimPrefix (trimmed , "---" )
157+ if idx := strings .Index (rest , "\n ---" ); idx >= 0 {
158+ after := rest [idx + len ("\n ---" ):]
159+ after = strings .TrimPrefix (after , "\n " )
160+ s = after
161+ }
162+ }
163+
164+ // Strip HTML comments and tags.
165+ s = regexp .MustCompile (`(?s)<!--.*?-->` ).ReplaceAllString (s , "" )
166+ s = regexp .MustCompile (`(?is)<[^>]+>` ).ReplaceAllString (s , "" )
167+
168+ // Strip markdown images entirely.
169+ s = regexp .MustCompile (`!\[[^\]]*\]\([^)]*\)` ).ReplaceAllString (s , "" )
170+ // Replace markdown links `[text](url)` with just `text`.
171+ s = regexp .MustCompile (`\[([^\]]+)\]\([^)]+\)` ).ReplaceAllString (s , "$1" )
172+
173+ // Drop table lines and horizontal rules.
174+ var kept []string
175+ for _ , line := range strings .Split (s , "\n " ) {
176+ t := strings .TrimSpace (line )
177+ if strings .HasPrefix (t , "|" ) {
178+ continue
179+ }
180+ if strings .HasPrefix (t , ":--" ) || strings .HasPrefix (t , "---" ) || strings .HasPrefix (t , "===" ) {
181+ continue
182+ }
183+ kept = append (kept , line )
184+ }
185+ s = strings .Join (kept , "\n " )
186+
187+ // Normalise whitespace.
188+ s = cleanTextContent (s )
189+
190+ // Truncate at a paragraph boundary around maxLen chars.
191+ const maxLen = 1200
192+ if len (s ) > maxLen {
193+ cut := strings .LastIndex (s [:maxLen ], "\n \n " )
194+ if cut < maxLen / 3 {
195+ cut = maxLen
196+ }
197+ s = strings .TrimRight (s [:cut ], " \t \n " ) + "\n \n ..."
198+ }
199+
200+ return s
201+ }
202+
144203// cleanTextContent removes trailing spaces/tabs and collapses multiple empty
145204// lines so README content embeds cleanly into YAML without lint noise.
146205func cleanTextContent (text string ) string {
0 commit comments