summaryrefslogtreecommitdiffstatshomepage
path: root/scripts/generate-web-types.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/generate-web-types.mjs')
-rw-r--r--scripts/generate-web-types.mjs145
1 files changed, 145 insertions, 0 deletions
diff --git a/scripts/generate-web-types.mjs b/scripts/generate-web-types.mjs
new file mode 100644
index 00000000..34b4b661
--- /dev/null
+++ b/scripts/generate-web-types.mjs
@@ -0,0 +1,145 @@
+import fs from 'fs'
+
+const classes = []
+const attributes = []
+const events = []
+
+const rootPath = fs.existsSync('./www') ? './' : '../'
+
+for (const file of fs.readdirSync(rootPath + 'www/content/attributes').sort()) {
+ if (file.startsWith('hx-') && file.endsWith('.md')) {
+ const name = file.slice(0, -3)
+ const info = readAttributeInfo(name, rootPath + 'www/content/attributes/' + file)
+ attributes.push({
+ name,
+ ...info,
+ 'doc-url': 'https://htmx.org/attributes/' + name + '/'
+ })
+ }
+}
+
+readClassInfo()
+readEventInfo()
+
+const pkg = JSON.parse(fs.readFileSync(rootPath + 'package.json', { encoding: 'utf8' }))
+
+const webTypes = {
+ $schema: 'https://json.schemastore.org/web-types',
+ name: 'htmx',
+ version: pkg.version,
+ 'default-icon': './htmx.svg',
+ 'js-types-syntax': 'typescript',
+ 'description-markup': 'markdown',
+ contributions: {
+ html: {
+ attributes
+ },
+ css: {
+ classes
+ },
+ js: {
+ events: [
+ {
+ name: 'HTMX event',
+ pattern: {
+ items: ['/js/htmx-events'],
+ template: ['htmx:', '$...', '#item:HTMX event']
+ }
+ }
+ ],
+ 'htmx-events': events
+ }
+ }
+}
+
+fs.writeFileSync(rootPath + 'editors/jetbrains/htmx.web-types.json', JSON.stringify(webTypes, null, 2))
+
+function readAttributeInfo(name, file) {
+ const content = fs.readFileSync(file, { encoding: 'utf8' })
+
+ const isInherited = content.indexOf('`' + name + '` is inherited') !== -1
+ const isNotInherited = content.indexOf('`' + name + '` is not inherited') !== -1
+
+ const deprecated = content.indexOf('`' + name + '` has been deprecated') !== -1
+
+ const sections = {}
+
+ if (isInherited) {
+ sections.Inherited = ''
+ } else if (isNotInherited) {
+ sections['Not Inherited'] = ''
+ }
+
+ const descSections = /\+\+\+\n(?:[^\n]*\n)+\+\+\+\n\n((?:[^\n]+\n)+)(?:\n((?:[^\n]+\n)+))?(?:\n((?:[^\n]+\n)+))?/mg.exec(content)
+ const para1 = descSections[1].trim()
+ const para2 = descSections[2]?.trim()
+ const para3 = descSections[3]?.trim()
+
+ let description = para1
+ if (para2) {
+ description += '\n\n' + para2
+ }
+ if (para2 && para2.endsWith(':') && para3) {
+ description += '\n\n' + para3
+ }
+
+ let pattern
+ if (name === 'hx-on') {
+ pattern = {
+ or: [
+ {
+ items: ['/js/events'],
+ template: ['hx-on:', '#...', '#item:JS event']
+ },
+ {
+ items: ['/js/htmx-events'],
+ template: ['hx-on::', '#...', '#item:HTMX event']
+ }
+ ]
+ }
+ }
+
+ return {
+ pattern,
+ description,
+ 'description-sections': sections,
+ deprecated: deprecated ? true : undefined
+ }
+}
+
+function readClassInfo() {
+ const content = fs.readFileSync(rootPath + 'www/content/reference.md', { encoding: 'utf8' })
+ const start = content.indexOf('| Class | Description |')
+ const cssTable = content.slice(start, content.indexOf('</div>', start))
+ const expr = /\| `([^`]+)` \| ([^\n]+)/mg
+ let match = expr.exec(cssTable)
+ while (match) {
+ const name = match[1]
+ if (name && name.startsWith('htmx-')) {
+ classes.push({
+ name,
+ description: match[2].trim(),
+ 'doc-url': 'https://htmx.org/reference/#classes'
+ })
+ }
+ match = expr.exec(cssTable)
+ }
+}
+
+function readEventInfo() {
+ const content = fs.readFileSync(rootPath + 'www/content/events.md', { encoding: 'utf8' })
+ const expr = /### Event - `([^`]+)`[^\n]*\n+((?:(?:[^#\n]|#####)[^\n]*\n+)+)/mg
+ let match = expr.exec(content)
+ while (match) {
+ let name = match[1]
+ if (name && name.startsWith('htmx:')) {
+ name = name.slice(5)
+ events.push({
+ name,
+ description: match[2],
+ 'doc-url': 'https://htmx.org/events/#htmx:' + name
+ })
+ }
+ match = expr.exec(content)
+ }
+}