| 256 | const TITLE_SOURCE_TAGS = ["p", "h1", "h2", "h3", "h4", "h5", "h6"]; |
| 257 | |
| 258 | export function extractTitle(html: string, characterLimit: number) { |
| 259 | let text = ""; |
| 260 | let rootTag: string | undefined = undefined; |
| 261 | const parser = new Parser( |
| 262 | { |
| 263 | onopentag: (name) => { |
| 264 | if (!rootTag && TITLE_SOURCE_TAGS.includes(name)) { |
| 265 | rootTag = name; |
| 266 | } |
| 267 | }, |
| 268 | onclosetag: (name) => { |
| 269 | if (name === rootTag) { |
| 270 | if (text) { |
| 271 | parser.pause(); |
| 272 | parser.end(); |
| 273 | } else { |
| 274 | rootTag = undefined; |
| 275 | } |
| 276 | } |
| 277 | }, |
| 278 | ontext: (data) => { |
| 279 | if (!rootTag) return; |
| 280 | |
| 281 | text += data; |
| 282 | if (text.length > characterLimit) { |
| 283 | text = text.slice(0, characterLimit); |
| 284 | parser.pause(); |
| 285 | parser.end(); |
| 286 | } |
| 287 | } |
| 288 | }, |
| 289 | { |
| 290 | lowerCaseTags: false, |
| 291 | decodeEntities: true |
| 292 | } |
| 293 | ); |
| 294 | parser.end(html); |
| 295 | return text; |
| 296 | } |
| 297 | |
| 298 | type OnTagHandler = ( |
| 299 | name: string, |