|
${stack.at(-1)}
- ${sxpr(stack[2],3)}`)
+ | ${sxpr(stack[width ?? 2], depth ?? 3)}`)
}
- visitor.wander(mods,doit)
- res.send(style+`${JSON.stringify(req.query,null,2)}${list.join(" ")}`)
+ visitor.walk(mods,doit)
+ list.sort((a,b) => vis(a)>vis(b) ? 1 : -1)
+ const q = (id,delta) => Object.entries(req.query)
+ .map(([k,v]) => k == id ? `${k}=${+v+delta}` : `${k}=${v}`)
+ .join('&')
+ const p = id => ` + `
+ const m = id => ` − `
+ const d = id => `${id} ${p(id)} ${m(id)}`
+ res.send(style('usage',key)+`
+ ${files.total()} uses in ${files.size()} files
+ ${files.tally().map(([k,v]) => `| ${v} | ${k}`).join("\n")} |
+
â ${d('width')} ${d('depth')} â
+ `)
})
app.get('/nesting', (req,res) => {
- const {file,type,start,end} = req.query
+ const {file,type,key,start,end} = req.query
const result = []
const doit = (branch,stack) => {
if(stack.at(-1)==file && branch.type==type && branch.start==start && branch.end==end) {
- const file = stack.at(-1)
const path = stack.slice(0,-1).map((n,i) => `
- |
+ | ${n.type}:
| ${sxpr(n,3,null,stack[i-1])}`).reverse()
const hit = stack[1]
result.push(`
-
\n
- ${escape(JSON.stringify(hit,omit,2))}`)
+
+ ${escape(JSON.stringify(hit,omit,2))}`)
}
}
- visitor.wander(mods,doit)
- res.send(style+`${JSON.stringify(req.query,null,2)}${result.join(" ")}`)
+ visitor.walk(mods,doit)
+ res.send(style('nesting',key)+`${result.join(" ")}`)
+})
+
+app.get('/similar', (req,res) => {
+ const {file,type,key,start,end,nest} = req.query
+ let nested
+ visitor.walk(mods,(branch,stack) => {
+ if(stack.at(-1)==file && branch.type==type && branch.start==start && branch.end==end)
+ nested = stack[nest]
+ })
+ const norm = node => vis(`\n\n\n${sxpr(node,3,null)}`)
+ const source = (file,node) => mods.find(mod => mod.file == file).text.substring(+node.start,+node.end)
+ const want = norm(nested)
+ const result = []
+ visitor.walk(mods,(branch,stack) => {
+ if(norm(branch) == want) result.push(`${escape(source(stack.at(-1),branch))} `)
+ })
+ res.send(style('similar',key)+
+ `${want} ` +
+ result.join("\n")
+ )
})
@@ -106,6 +144,7 @@ function counter() {
counts.set(item, counts.get(item)+1)
else
counts.set(item,1)
+ return item
},
size() {
return counts.size
@@ -165,4 +204,17 @@ function elipsis(obj) {
return `(${dots})`
}
+function vis(row) {
+ return row.split(/\n/)[3].trim()
+ .replaceAll(/<.*?>/g,'')
+ .replaceAll(/\.\.+/g,'..')
+}
+
+
+function query(obj,adj={}) {
+ return Object.entries(obj)
+ .map(([k,v]) => k in adj ? `${k}=${adj[k](v)}` : `${k}=${v}`)
+ .join('&')
+}
+
app.listen(1954)
\ No newline at end of file
|