|
| 1 | +import fs from 'fs' |
| 2 | + |
| 3 | +const classes = [] |
| 4 | +const attributes = [] |
| 5 | +const events = [] |
| 6 | + |
| 7 | +const rootPath = fs.existsSync('./www') ? './' : '../' |
| 8 | + |
| 9 | +for (const file of fs.readdirSync(rootPath + 'www/content/attributes').sort()) { |
| 10 | + if (file.startsWith('hx-') && file.endsWith('.md')) { |
| 11 | + const name = file.slice(0, -3) |
| 12 | + const info = readAttributeInfo(name, rootPath + 'www/content/attributes/' + file) |
| 13 | + attributes.push({ |
| 14 | + name, |
| 15 | + ...info, |
| 16 | + 'doc-url': 'https://htmx.org/attributes/' + name + '/' |
| 17 | + }) |
| 18 | + } |
| 19 | +} |
| 20 | + |
| 21 | +readClassInfo() |
| 22 | +readEventInfo() |
| 23 | + |
| 24 | +const pkg = JSON.parse(fs.readFileSync(rootPath + 'package.json', { encoding: 'utf8' })) |
| 25 | + |
| 26 | +const webTypes = { |
| 27 | + $schema: 'https://json.schemastore.org/web-types', |
| 28 | + name: 'htmx', |
| 29 | + version: pkg.version, |
| 30 | + 'default-icon': './htmx.svg', |
| 31 | + 'js-types-syntax': 'typescript', |
| 32 | + 'description-markup': 'markdown', |
| 33 | + contributions: { |
| 34 | + html: { |
| 35 | + attributes |
| 36 | + }, |
| 37 | + css: { |
| 38 | + classes |
| 39 | + }, |
| 40 | + js: { |
| 41 | + events: [ |
| 42 | + { |
| 43 | + name: 'HTMX event', |
| 44 | + pattern: { |
| 45 | + items: ['/js/htmx-events'], |
| 46 | + template: ['htmx:', '$...', '#item:HTMX event'] |
| 47 | + } |
| 48 | + } |
| 49 | + ], |
| 50 | + 'htmx-events': events |
| 51 | + } |
| 52 | + } |
| 53 | +} |
| 54 | + |
| 55 | +fs.writeFileSync(rootPath + 'editors/jetbrains/htmx.web-types.json', JSON.stringify(webTypes, null, 2)) |
| 56 | + |
| 57 | +function readAttributeInfo(name, file) { |
| 58 | + const content = fs.readFileSync(file, { encoding: 'utf8' }) |
| 59 | + |
| 60 | + const isInherited = content.indexOf('`' + name + '` is inherited') !== -1 |
| 61 | + const isNotInherited = content.indexOf('`' + name + '` is not inherited') !== -1 |
| 62 | + |
| 63 | + const deprecated = content.indexOf('`' + name + '` has been deprecated') !== -1 |
| 64 | + |
| 65 | + const sections = {} |
| 66 | + |
| 67 | + if (isInherited) { |
| 68 | + sections.Inherited = '' |
| 69 | + } else if (isNotInherited) { |
| 70 | + sections['Not Inherited'] = '' |
| 71 | + } |
| 72 | + |
| 73 | + const descSections = /\+\+\+\n(?:[^\n]*\n)+\+\+\+\n\n((?:[^\n]+\n)+)(?:\n((?:[^\n]+\n)+))?(?:\n((?:[^\n]+\n)+))?/mg.exec(content) |
| 74 | + const para1 = descSections[1].trim() |
| 75 | + const para2 = descSections[2]?.trim() |
| 76 | + const para3 = descSections[3]?.trim() |
| 77 | + |
| 78 | + let description = para1 |
| 79 | + if (para2) { |
| 80 | + description += '\n\n' + para2 |
| 81 | + } |
| 82 | + if (para2 && para2.endsWith(':') && para3) { |
| 83 | + description += '\n\n' + para3 |
| 84 | + } |
| 85 | + |
| 86 | + let pattern |
| 87 | + if (name === 'hx-on') { |
| 88 | + pattern = { |
| 89 | + or: [ |
| 90 | + { |
| 91 | + items: ['/js/events'], |
| 92 | + template: ['hx-on:', '#...', '#item:JS event'] |
| 93 | + }, |
| 94 | + { |
| 95 | + items: ['/js/htmx-events'], |
| 96 | + template: ['hx-on::', '#...', '#item:HTMX event'] |
| 97 | + } |
| 98 | + ] |
| 99 | + } |
| 100 | + } |
| 101 | + |
| 102 | + return { |
| 103 | + pattern, |
| 104 | + description, |
| 105 | + 'description-sections': sections, |
| 106 | + deprecated: deprecated ? true : undefined |
| 107 | + } |
| 108 | +} |
| 109 | + |
| 110 | +function readClassInfo() { |
| 111 | + const content = fs.readFileSync(rootPath + 'www/content/reference.md', { encoding: 'utf8' }) |
| 112 | + const start = content.indexOf('| Class | Description |') |
| 113 | + const cssTable = content.slice(start, content.indexOf('</div>', start)) |
| 114 | + const expr = /\| `([^`]+)` \| ([^\n]+)/mg |
| 115 | + let match = expr.exec(cssTable) |
| 116 | + while (match) { |
| 117 | + const name = match[1] |
| 118 | + if (name && name.startsWith('htmx-')) { |
| 119 | + classes.push({ |
| 120 | + name, |
| 121 | + description: match[2].trim(), |
| 122 | + 'doc-url': 'https://htmx.org/reference/#classes' |
| 123 | + }) |
| 124 | + } |
| 125 | + match = expr.exec(cssTable) |
| 126 | + } |
| 127 | +} |
| 128 | + |
| 129 | +function readEventInfo() { |
| 130 | + const content = fs.readFileSync(rootPath + 'www/content/events.md', { encoding: 'utf8' }) |
| 131 | + const expr = /### Event - `([^`]+)`[^\n]*\n+((?:(?:[^#\n]|#####)[^\n]*\n+)+)/mg |
| 132 | + let match = expr.exec(content) |
| 133 | + while (match) { |
| 134 | + let name = match[1] |
| 135 | + if (name && name.startsWith('htmx:')) { |
| 136 | + name = name.slice(5) |
| 137 | + events.push({ |
| 138 | + name, |
| 139 | + description: match[2], |
| 140 | + 'doc-url': 'https://htmx.org/events/#htmx:' + name |
| 141 | + }) |
| 142 | + } |
| 143 | + match = expr.exec(content) |
| 144 | + } |
| 145 | +} |
0 commit comments