From 9ab6bdad53b328a02a0b40fe0497fe9ad40f114a Mon Sep 17 00:00:00 2001 From: Charles Toller Date: Tue, 28 Jan 2025 22:26:52 -0800 Subject: [PATCH] Refactor frontmatter location parsing to util function --- src/renderer/renderer.ts | 50 +++++++--------------------------------- src/utils/frontmatter.ts | 43 ++++++++++++++++++++++++++++++++++ src/utils/watcher.ts | 40 ++++++-------------------------- 3 files changed, 58 insertions(+), 75 deletions(-) create mode 100644 src/utils/frontmatter.ts diff --git a/src/renderer/renderer.ts b/src/renderer/renderer.ts index 916b482..e104746 100644 --- a/src/renderer/renderer.ts +++ b/src/renderer/renderer.ts @@ -43,6 +43,7 @@ import t from "../l10n/locale"; import { LeafletMapView } from "src/map/view"; import { Marker, Overlay } from "src/layer"; import { promisify } from "util"; +import {parseFrontmatterLocation} from "../utils/frontmatter"; declare module "leaflet" { interface Map { @@ -1105,40 +1106,12 @@ export class LeafletRenderer extends MarkdownRenderChild { const id = getId(); - if (frontmatter.location) { - let locations = frontmatter.location; - if ( - locations.length && - !(locations[0] instanceof Array) - ) { - locations = [locations]; - } - for (const location of locations) { - let err = false, - [lat, long] = location; - - try { - lat = - typeof lat === "number" - ? lat - : Number(lat?.split("%").shift()); - long = - typeof long === "number" - ? long - : Number(long?.split("%").shift()); - } catch (e) { - err = true; - } + let parsedLocations = frontmatter.location ? parseFrontmatterLocation(frontmatter.location, file.basename) : null; - if (err || isNaN(lat) || isNaN(long)) { - new Notice( - t( - "Could not parse location in %1", - file.basename - ) - ); - continue; - } + if (parsedLocations != null) { + let locations = parsedLocations; + for (const location of locations) { + let [lat, long] = location; let min, max; if (frontmatter.mapzoom) { @@ -1267,17 +1240,10 @@ export class LeafletRenderer extends MarkdownRenderChild { continue; } - let location = frontmatter.location; - if (!location) continue; - if ( - location instanceof Array && - !(location[0] instanceof Array) - ) { - location = [location]; - } + if (!parsedLocations) continue; overlaysToReturn.push([ overlayColor, - location[0], + parsedLocations[0], frontmatter[overlayTag], `${file.basename}: ${overlayTag}`, id diff --git a/src/utils/frontmatter.ts b/src/utils/frontmatter.ts new file mode 100644 index 0000000..4442fd6 --- /dev/null +++ b/src/utils/frontmatter.ts @@ -0,0 +1,43 @@ +import {Notice} from "obsidian"; +import t from "../l10n/locale"; + +export function parseFrontmatterLocation(frontmatterLocationField: unknown, fileBasename: string): Array<[number, number]> { + if (typeof frontmatterLocationField === "string") { + // Try parsing as a number pair + const parseResult = /(?:\[|^)([+-]?\d+(?:\.\d+)?)%?\s*,\s*([+-]?\d+(?:\.\d+)?)%?(?:]|$)/.exec(frontmatterLocationField); + if (parseResult != null) { + const lat = Number(parseResult[1]), long = Number(parseResult[2]); + if (!isNaN(lat) && !isNaN(long)) { + return [[lat, long]]; + } + } + } + if (typeof frontmatterLocationField === "object" && Array.isArray(frontmatterLocationField)) { + let twoDLocationsArray: Array>; + if (!Array.isArray(frontmatterLocationField[0])) { + twoDLocationsArray = [frontmatterLocationField]; + } else { + twoDLocationsArray = frontmatterLocationField; + } + const outputArray: Array<[number, number]> = []; + for (const location of twoDLocationsArray) { + let [lat, long] = location.map((value) => { + if (typeof value === "number") return value; + if (typeof value === "string") return Number(value.split("%").shift()); + return Number.NaN; + }); + if (isNaN(lat) || isNaN(long)) { + new Notice( + t( + "Could not parse location in %1", + fileBasename + ) + ); + } else { + outputArray.push([lat, long]); + } + } + return outputArray; + } + return []; +} \ No newline at end of file diff --git a/src/utils/watcher.ts b/src/utils/watcher.ts index 9964e81..9dcce91 100644 --- a/src/utils/watcher.ts +++ b/src/utils/watcher.ts @@ -16,6 +16,7 @@ import { LeafletSymbol } from "src/utils/leaflet-import"; import { LeafletRenderer } from "src/renderer/renderer"; import t from "src/l10n/locale"; import { Marker, Overlay } from "src/layer"; +import {parseFrontmatterLocation} from "./frontmatter"; const L = window[LeafletSymbol]; export class Watcher extends Component { @@ -65,23 +66,10 @@ export class Watcher extends Component { this.type = this.parseMarkerType(this.frontmatter); if ("location" in this.frontmatter) { - let locations = this.frontmatter.location; - if ( - locations instanceof Array && - !(locations[0] instanceof Array) - ) { - locations = [locations]; - } + let locations = parseFrontmatterLocation(this.frontmatter.location, this.file.basename); this.ids.set("location", getId()); for (let index in locations) { const location = locations[index]; - if ( - !( - location.length == 2 && - location.every((v: any) => typeof v == "number") - ) - ) - continue; this.markers.push( new Marker(this.renderer.map, { id: this.ids.get("location"), @@ -231,21 +219,14 @@ export default class OldWatcher extends Events { let overlays = []; const markers = this.map.getMarkersById(this.fileIds.get("marker")); + const parsedLocations = this.frontmatter.location ? parseFrontmatterLocation(this.frontmatter.location, this.file.basename) : null; + if ( markers && - this.frontmatter.location && - this.frontmatter.location instanceof Array + parsedLocations != null ) { try { - let locations = this.frontmatter.location; - if ( - locations && - locations instanceof Array && - !(locations[0] instanceof Array) - ) { - locations = [locations]; - } - + let locations = parsedLocations; for (let index in locations) { const location = locations[index]; const marker = markers[index]; @@ -370,14 +351,7 @@ export default class OldWatcher extends Events { return id != this.fileIds.get("overlayTag"); } ); - let locations = this.frontmatter.location ?? [0, 0]; - if ( - locations && - locations instanceof Array && - !(locations[0] instanceof Array) - ) { - locations = [locations]; - } + let locations = parsedLocations; overlays.push([ this.map.options.overlayColor ?? "blue", locations[0],