Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"@types/leaflet": "^1.7.2",
"@types/leaflet.markercluster": "^1.4.5",
"@types/node": "^14.14.37",
"@types/yawn-yaml": "^1.4.0",
"obsidian": "^0.12.5",
"postcss-less": "^4.0.1",
"postcss-url": "^10.1.3",
Expand All @@ -41,6 +42,7 @@
"leaflet.markercluster": "^1.5.3",
"moment": "^2.29.1",
"open": "^8.2.1",
"wildcard": "^2.0.0"
"wildcard": "^2.0.0",
"yawn-yaml": "^1.5.0"
}
}
48 changes: 46 additions & 2 deletions src/mapView.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {
App,
TAbstractFile,
Loc,
Editor,
Expand All @@ -9,7 +8,6 @@ import {
TFile,
WorkspaceLeaf,
Notice,
ViewState,
} from 'obsidian';
import * as leaflet from 'leaflet';
// Ugly hack for obsidian-leaflet compatability, see https://github.com/esm7/obsidian-map-view/issues/6
Expand Down Expand Up @@ -74,6 +72,8 @@ export class MapView extends ItemView {
/** Is the view currently open */
private isOpen: boolean = false;

private editable: boolean = false;

/**
* Construct a new map instance
* @param leaf The leaf the map should be put in
Expand Down Expand Up @@ -577,6 +577,36 @@ export class MapView extends ItemView {
newMarker.on('mouseout', (event: leaflet.LeafletMouseEvent) => {
newMarker.closePopup();
});
newMarker.on('add', (event: leaflet.LeafletEvent) => {
if (this.editable) {
newMarker.dragging.enable();
}
});
newMarker.on('dragstart', async (event: leaflet.LeafletEvent) => {
// if dragging the balloons are quite irritating
newMarker.closePopup();
});
newMarker.on('dragend', async (event: leaflet.DragEndEvent) => {
const latlng = newMarker.getLatLng();
if (marker.fileLocation === undefined) {
// is a front matter location
await utils.vaultFrontMatterSet(
this.app.vault,
marker.file,
'location',
[latlng.lat, latlng.lng]
);
} else {
// is an inline location
const location = `${latlng.lat},${latlng.lng}`;
const old_file = await this.app.vault.cachedRead(marker.file);
const new_file =
old_file.slice(0, marker.fileLocation) +
`[](geo:${location})` +
old_file.slice(marker.fileLocation + marker.fileLength);
await this.app.vault.modify(marker.file, new_file);
}
});
newMarker.on('add', (event: leaflet.LeafletEvent) => {
newMarker
.getElement()
Expand Down Expand Up @@ -733,4 +763,18 @@ export class MapView extends ItemView {
);
this.updateMapMarkers(newMarkers);
}

/** Set the markers edit state. */
setEditable(editable: boolean) {
this.editable = editable;
for (let [markerId, fileMarker] of this.display.markers) {
if (fileMarker.mapMarker.dragging) {
if (editable) {
fileMarker.mapMarker.dragging.enable();
} else {
fileMarker.mapMarker.dragging.disable();
}
}
}
}
}
2 changes: 2 additions & 0 deletions src/markers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export class FileMarker {
file: TFile;
/** In the case of an inline location, the position within the file where the location was found */
fileLocation?: number;
fileLength?: number;
/** In case of an inline location, the line within the file where the geolocation was found */
fileLine?: number;
location: leaflet.LatLng;
Expand Down Expand Up @@ -249,6 +250,7 @@ async function getMarkersFromFileContent(
if (tag[1]) marker.tags.push('#' + tag[1]);
}
marker.fileLocation = match.index;
marker.fileLength = match[0].length;
marker.fileLine =
content.substring(0, marker.fileLocation).split('\n').length -
1;
Expand Down
62 changes: 62 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import {
TFile,
Menu,
MenuItem,
Vault,
stringifyYaml,
parseYaml,
} from 'obsidian';

import * as moment_ from 'moment';
Expand All @@ -15,6 +18,8 @@ import * as settings from './settings';
import * as consts from './consts';
import { MapView } from './mapView';

// import YAWN from 'yawn-yaml';

export function formatWithTemplates(s: string, query = '') {
const datePattern = /{{date:([a-zA-Z\-\/\.\:]*)}}/g;
const queryPattern = /{{query}}/g;
Expand All @@ -31,6 +36,7 @@ export function formatWithTemplates(s: string, query = '') {
type NewNoteType = 'singleLocation' | 'multiLocation';

const CURSOR = '$CURSOR$';
const FRONT_MATTER_PATTERN = /\s*^---\r?\n(?<yaml>.*?)^---/ms;

function sanitizeFileName(s: string) {
const illegalChars = /[\?<>\\:\*\|":]/g;
Expand Down Expand Up @@ -108,6 +114,62 @@ export async function handleNewNoteCursorMarker(editor: Editor) {
}
}

// Set/setdefault a top level YAML value in a file content string
// If the YAML front matter does not exist it will be created
export function stringFrontMatterSet(
content: string,
fieldName: string,
fieldValue: any,
set_default: boolean = false
): string {
const frontMatterMatch = content.match(FRONT_MATTER_PATTERN);
if (frontMatterMatch !== null) {
let frontMatterYaml = frontMatterMatch.groups.yaml;
content = content.slice(frontMatterMatch[0].length);

// this works but modifies formatting
let yaml = parseYaml(frontMatterYaml);
if (set_default ? !yaml.hasOwnProperty(fieldName) : true) {
yaml[fieldName] = fieldValue;
frontMatterYaml = stringifyYaml(yaml);
}

// this is a better way to do it if we can get yawn-yaml to work
// let yawn = new YAWN(frontMatterYaml);
// if (set_default ? !yawn.json.hasOwnProperty(fieldName) : true) {
// yawn.json[fieldName] = fieldValue;
// return `---\n${yawn.yaml}\n---` + content;
// }

// this does not have a trailing newline to preserve the formatting. If it had one, a new one would be added each time
return `---\n${frontMatterYaml}---` + content;
} else {
const frontMatterYaml = stringifyYaml({ [fieldName]: fieldValue });
// this has a trailing newline to shift the old first line down below the front matter
return `---\n${frontMatterYaml}---\n` + content;
}
}

// Set/setdefault a top level value in the front matter of a file.
export async function vaultFrontMatterSet(
vault: Vault,
file: TFile,
fieldName: string,
fieldValue: any,
set_default: boolean = false
) {
const old_file = await vault.cachedRead(file);
const new_file = stringFrontMatterSet(
old_file,
fieldName,
fieldValue,
set_default
);
if (old_file != new_file) {
await vault.modify(file, new_file);
}
}

// Creates or modifies a front matter that has the field `fieldName: fieldValue`.
// Returns true if a change to the note was made.
export function verifyOrAddFrontMatter(
Expand Down
16 changes: 16 additions & 0 deletions src/viewControls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,22 @@ export class ViewControls {
};
this.refreshPresets();

// this could probably be better but I don't know what I am doing
const editMarkers = this.controlsDiv.createDiv({
cls: 'graph-control-div',
});
editMarkers.innerHTML = `
<input id="editMarkers" class="toggle" type="checkbox">
<label for="editMarkers" class="lbl-toggle">Edit Markers</label>
`;
const editMarkersButton = editMarkers.getElementsByClassName(
'toggle'
)[0] as HTMLInputElement;
editMarkersButton.checked = false;
editMarkersButton.onclick = async () => {
this.view.setEditable(editMarkersButton.checked);
};

this.parentElement.append(this.controlsDiv);
}

Expand Down