Fix: better support for complicated regex tags

This commit is contained in:
Pieter Vander Vennet 2024-10-31 10:49:30 +01:00
parent 4ff50fd92b
commit b4817f7a7f
3 changed files with 45 additions and 52 deletions

View file

@ -1,42 +1,14 @@
import { Utils } from "../../Utils" import { Utils } from "../../Utils"
/** This code is autogenerated - do not edit. Edit ./assets/layers/usersettings/usersettings.json instead */ /** This code is autogenerated - do not edit. Edit ./assets/layers/usersettings/usersettings.json instead */
export class ThemeMetaTagging { export class ThemeMetaTagging {
public static readonly themeName = "usersettings" public static readonly themeName = "usersettings"
public metaTaggging_for_usersettings(feat: { properties: Record<string, string> }) { public metaTaggging_for_usersettings(feat: {properties: Record<string, string>}) {
Utils.AddLazyProperty(feat.properties, "_mastodon_candidate_md", () => Utils.AddLazyProperty(feat.properties, '_mastodon_candidate_md', () => feat.properties._description.match(/\[[^\]]*\]\((.*(mastodon|en.osm.town).*)\).*/)?.at(1) )
feat.properties._description Utils.AddLazyProperty(feat.properties, '_d', () => feat.properties._description?.replace(/&lt;/g,'<')?.replace(/&gt;/g,'>') ?? '' )
.match(/\[[^\]]*\]\((.*(mastodon|en.osm.town).*)\).*/) Utils.AddLazyProperty(feat.properties, '_mastodon_candidate_a', () => (feat => {const e = document.createElement('div');e.innerHTML = feat.properties._d;return Array.from(e.getElementsByTagName("a")).filter(a => a.href.match(/mastodon|en.osm.town/) !== null)[0]?.href }) (feat) )
?.at(1) Utils.AddLazyProperty(feat.properties, '_mastodon_link', () => (feat => {const e = document.createElement('div');e.innerHTML = feat.properties._d;return Array.from(e.getElementsByTagName("a")).filter(a => a.getAttribute("rel")?.indexOf('me') >= 0)[0]?.href})(feat) )
) Utils.AddLazyProperty(feat.properties, '_mastodon_candidate', () => feat.properties._mastodon_candidate_md ?? feat.properties._mastodon_candidate_a )
Utils.AddLazyProperty( feat.properties['__current_backgroun'] = 'initial_value'
feat.properties, }
"_d", }
() => feat.properties._description?.replace(/&lt;/g, "<")?.replace(/&gt;/g, ">") ?? ""
)
Utils.AddLazyProperty(feat.properties, "_mastodon_candidate_a", () =>
((feat) => {
const e = document.createElement("div")
e.innerHTML = feat.properties._d
return Array.from(e.getElementsByTagName("a")).filter(
(a) => a.href.match(/mastodon|en.osm.town/) !== null
)[0]?.href
})(feat)
)
Utils.AddLazyProperty(feat.properties, "_mastodon_link", () =>
((feat) => {
const e = document.createElement("div")
e.innerHTML = feat.properties._d
return Array.from(e.getElementsByTagName("a")).filter(
(a) => a.getAttribute("rel")?.indexOf("me") >= 0
)[0]?.href
})(feat)
)
Utils.AddLazyProperty(
feat.properties,
"_mastodon_candidate",
() => feat.properties._mastodon_candidate_md ?? feat.properties._mastodon_candidate_a
)
feat.properties["__current_backgroun"] = "initial_value"
}
}

View file

@ -109,19 +109,29 @@ export class RegexTag extends TagsFilter {
* *
* const t = TagUtils.Tag("a~i~b") * const t = TagUtils.Tag("a~i~b")
* t.asJson() // => "a~i~b" * t.asJson() // => "a~i~b"
*
* const t = TagUtils.Tag("service:bicycle:.*~~*")
* t.asJson() // => "service:bicycle:.*~~.+"
*/ */
asJson(): TagConfigJson { asJson(): TagConfigJson {
const v = RegexTag.source(this.value, false) const v = RegexTag.source(this.value, false)
const valueIsString = typeof this.value === "string" const valueIsString = typeof this.value === "string"
if(typeof this.key === "string" && valueIsString){
return `${this.key}${this.invert ? "!" : ""}=${v}`
}
const caseInvariant = typeof this.value !== "string" && this.value.ignoreCase const caseInvariant = typeof this.value !== "string" && this.value.ignoreCase
if (typeof this.key === "string" && !caseInvariant) { const invert = this.invert ? "!" : ""
return `${this.key}${this.invert ? "!" : ""}~${v}` if (typeof this.key === "string") {
if (valueIsString) {
return `${this.key}${invert}=${v}`
}
if (!caseInvariant) {
return `${this.key}${invert}~${v}`
}
return `${this.key}${invert}~i~${v}`
} }
const k = typeof this.key === "string" ? this.key : this.key.source
return `${k}${this.invert ? "!" : ""}~${caseInvariant ? "i": ""}~${v}` const key :string = RegexTag.source(this.key, false)
return `${key}${invert}~${caseInvariant ? "i~" : ""}~${v}`
} }
isUsableAsAnswer(): boolean { isUsableAsAnswer(): boolean {

View file

@ -99,6 +99,16 @@ export class TagUtils {
overpassSupport: true, overpassSupport: true,
docs: "Both the `key` and `value` part of this specification are interpreted as regexes, both the key and value musth completely match their respective regexes", docs: "Both the `key` and `value` part of this specification are interpreted as regexes, both the key and value musth completely match their respective regexes",
}, },
"~i~~": {
name: "Key and value should match a given regex; value is case-invariant",
overpassSupport: true,
docs: "Similar to ~~, except that the value is case-invariant"
},
"!~i~~": {
name: "Key and value should match a given regex; value is case-invariant",
overpassSupport: true,
docs: "Similar to !~~, except that the value is case-invariant"
},
":=": { ":=": {
name: "Substitute `... {some_key} ...` and match `key`", name: "Substitute `... {some_key} ...` and match `key`",
overpassSupport: false, overpassSupport: false,
@ -469,7 +479,7 @@ export class TagUtils {
* TagUtils.Tag("survey:date:={_date:now}") // => new SubstitutingTag("survey:date", "{_date:now}") * TagUtils.Tag("survey:date:={_date:now}") // => new SubstitutingTag("survey:date", "{_date:now}")
* TagUtils.Tag("xyz!~\\[\\]") // => new RegexTag("xyz", /^(\[\])$/s, true) * TagUtils.Tag("xyz!~\\[\\]") // => new RegexTag("xyz", /^(\[\])$/s, true)
* TagUtils.Tag("tags~(.*;)?amenity=public_bookcase(;.*)?") // => new RegexTag("tags", /^((.*;)?amenity=public_bookcase(;.*)?)$/s) * TagUtils.Tag("tags~(.*;)?amenity=public_bookcase(;.*)?") // => new RegexTag("tags", /^((.*;)?amenity=public_bookcase(;.*)?)$/s)
* TagUtils.Tag("service:bicycle:.*~~*") // => new RegexTag(/^(service:bicycle:.*)$/, /.+/si) * TagUtils.Tag("service:bicycle:.*~i~~*") // => new RegexTag(/^(service:bicycle:.*)$/, /.+/s)
* TagUtils.Tag("_first_comment~.*{search}.*") // => new RegexTag('_first_comment', /^(.*{search}.*)$/s) * TagUtils.Tag("_first_comment~.*{search}.*") // => new RegexTag('_first_comment', /^(.*{search}.*)$/s)
* *
* TagUtils.Tag("xyz<5").matchesProperties({xyz: 4}) // => true * TagUtils.Tag("xyz<5").matchesProperties({xyz: 4}) // => true
@ -572,7 +582,7 @@ export class TagUtils {
} }
/** /**
* Parses the various parts of a regex tag * Parses the various parts of a regex tag. The key is never considered a regex
* *
* TagUtils.parseRegexOperator("key~value") // => {invert: false, key: "key", value: "value", modifier: ""} * TagUtils.parseRegexOperator("key~value") // => {invert: false, key: "key", value: "value", modifier: ""}
* TagUtils.parseRegexOperator("key!~value") // => {invert: true, key: "key", value: "value", modifier: ""} * TagUtils.parseRegexOperator("key!~value") // => {invert: true, key: "key", value: "value", modifier: ""}
@ -590,7 +600,7 @@ export class TagUtils {
value: string value: string
modifier: "i" | "" modifier: "i" | ""
} | null { } | null {
const match = tag.match(/^([_|a-zA-Z0-9: -]+)(!)?~([i]~)?(.*)$/) const match = tag.match(/^([_|a-zA-Z0-9.: -]+)(!)?~([i]~)?(.*)$/)
if (match == null) { if (match == null) {
return null return null
} }
@ -790,8 +800,9 @@ export class TagUtils {
} }
} }
if (tag.indexOf("~~") >= 0) { if (tag.indexOf("~~") >= 0 || tag.indexOf("~i~~") >= 0) {
const split = Utils.SplitFirst(tag, "~~") const caseInvariant = tag.indexOf("~i~~") >= 0
const split = Utils.SplitFirst(tag, caseInvariant ? "~i~~" : "~~")
let keyRegex: RegExp let keyRegex: RegExp
if (split[0] === "*") { if (split[0] === "*") {
keyRegex = new RegExp(".+", "i") keyRegex = new RegExp(".+", "i")
@ -800,9 +811,9 @@ export class TagUtils {
} }
let valueRegex: RegExp let valueRegex: RegExp
if (split[1] === "*") { if (split[1] === "*") {
valueRegex = new RegExp(".+", "si") valueRegex = new RegExp(".+", "s")
} else { } else {
valueRegex = new RegExp("^(" + split[1] + ")$", "s") valueRegex = new RegExp("^(" + split[1] + ")$",caseInvariant ? "si": "s" )
} }
return new RegexTag(keyRegex, valueRegex) return new RegexTag(keyRegex, valueRegex)
} }