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

@ -3,40 +3,12 @@ import { Utils } from "../../Utils"
export class ThemeMetaTagging {
public static readonly themeName = "usersettings"
public metaTaggging_for_usersettings(feat: { properties: Record<string, string> }) {
Utils.AddLazyProperty(feat.properties, "_mastodon_candidate_md", () =>
feat.properties._description
.match(/\[[^\]]*\]\((.*(mastodon|en.osm.town).*)\).*/)
?.at(1)
)
Utils.AddLazyProperty(
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"
public metaTaggging_for_usersettings(feat: {properties: Record<string, string>}) {
Utils.AddLazyProperty(feat.properties, '_mastodon_candidate_md', () => feat.properties._description.match(/\[[^\]]*\]\((.*(mastodon|en.osm.town).*)\).*/)?.at(1) )
Utils.AddLazyProperty(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")
* t.asJson() // => "a~i~b"
*
* const t = TagUtils.Tag("service:bicycle:.*~~*")
* t.asJson() // => "service:bicycle:.*~~.+"
*/
asJson(): TagConfigJson {
const v = RegexTag.source(this.value, false)
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
if (typeof this.key === "string" && !caseInvariant) {
return `${this.key}${this.invert ? "!" : ""}~${v}`
const invert = this.invert ? "!" : ""
if (typeof this.key === "string") {
if (valueIsString) {
return `${this.key}${invert}=${v}`
}
const k = typeof this.key === "string" ? this.key : this.key.source
return `${k}${this.invert ? "!" : ""}~${caseInvariant ? "i": ""}~${v}`
if (!caseInvariant) {
return `${this.key}${invert}~${v}`
}
return `${this.key}${invert}~i~${v}`
}
const key :string = RegexTag.source(this.key, false)
return `${key}${invert}~${caseInvariant ? "i~" : ""}~${v}`
}
isUsableAsAnswer(): boolean {

View file

@ -99,6 +99,16 @@ export class TagUtils {
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",
},
"~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`",
overpassSupport: false,
@ -469,7 +479,7 @@ export class TagUtils {
* TagUtils.Tag("survey:date:={_date:now}") // => new SubstitutingTag("survey:date", "{_date:now}")
* TagUtils.Tag("xyz!~\\[\\]") // => new RegexTag("xyz", /^(\[\])$/s, true)
* 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("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: true, key: "key", value: "value", modifier: ""}
@ -590,7 +600,7 @@ export class TagUtils {
value: string
modifier: "i" | ""
} | null {
const match = tag.match(/^([_|a-zA-Z0-9: -]+)(!)?~([i]~)?(.*)$/)
const match = tag.match(/^([_|a-zA-Z0-9.: -]+)(!)?~([i]~)?(.*)$/)
if (match == null) {
return null
}
@ -790,8 +800,9 @@ export class TagUtils {
}
}
if (tag.indexOf("~~") >= 0) {
const split = Utils.SplitFirst(tag, "~~")
if (tag.indexOf("~~") >= 0 || tag.indexOf("~i~~") >= 0) {
const caseInvariant = tag.indexOf("~i~~") >= 0
const split = Utils.SplitFirst(tag, caseInvariant ? "~i~~" : "~~")
let keyRegex: RegExp
if (split[0] === "*") {
keyRegex = new RegExp(".+", "i")
@ -800,9 +811,9 @@ export class TagUtils {
}
let valueRegex: RegExp
if (split[1] === "*") {
valueRegex = new RegExp(".+", "si")
valueRegex = new RegExp(".+", "s")
} else {
valueRegex = new RegExp("^(" + split[1] + ")$", "s")
valueRegex = new RegExp("^(" + split[1] + ")$",caseInvariant ? "si": "s" )
}
return new RegexTag(keyRegex, valueRegex)
}