This commit is contained in:
thecodexapp 2025-09-18 02:17:09 +01:00
parent b00f0fdc02
commit 51ec340a75
3 changed files with 195 additions and 0 deletions

101
main.js Normal file
View file

@ -0,0 +1,101 @@
const { Plugin, MarkdownView, WorkspaceLeaf, Component } = require('obsidian');
module.exports = class SyncEmbedPlugin extends Plugin {
async onload() {
console.log('Loading Sync Embeds Plugin');
// Add the command to insert a sync block.
this.addCommand({
id: 'insert-synced-embed',
name: 'Insert synced embed',
editorCallback: (editor, view) => {
const selection = editor.getSelection();
// If the user has selected text, use it as the note name.
const noteName = selection || ' ';
const textToInsert = `\`\`\`sync\n![[${noteName}]]\n\`\`\``;
editor.replaceSelection(textToInsert);
}
});
// Register the main code block processor.
this.registerMarkdownCodeBlockProcessor('sync', (source, el, ctx) => {
this.processSyncBlock(source, el, ctx);
});
}
onunload() {
console.log('Unloading Sync Embeds Plugin');
}
async processSyncBlock(source, el, ctx) {
el.empty();
const syncContainer = el.createDiv('sync-container');
const embedLines = source.split('\n')
.map(line => line.trim())
.filter(line => line.startsWith('![[') && line.endsWith(']]'));
if (embedLines.length === 0) {
syncContainer.createDiv('sync-empty').setText('No embeds found in sync block');
return;
}
for (let i = 0; i < embedLines.length; i++) {
const embedLine = embedLines[i];
await this.processEmbed(embedLine, syncContainer, ctx, i > 0);
}
}
async processEmbed(embedLine, container, ctx, addGap = false) {
try {
const match = embedLine.match(/!\[\[([^\]]+)\]\]/);
if (!match) return;
const linkText = match[1];
const notePath = linkText.split('#')[0];
const file = this.app.metadataCache.getFirstLinkpathDest(notePath, ctx.sourcePath);
if (!file) {
this.renderError(container, `Note not found: ${notePath}`, addGap);
return;
}
const embedContainer = container.createDiv('sync-embed');
if (addGap) embedContainer.addClass('sync-embed-gap');
const component = new Component();
const leaf = new WorkspaceLeaf(this.app);
component.load();
component.addChild(new (class extends Component {
async onunload() {
leaf.detach();
}
})());
await leaf.openFile(file, { state: { mode: "source" } });
const view = leaf.view;
if (!(view instanceof MarkdownView)) {
this.renderError(embedContainer, 'Failed to load a markdown view.', addGap);
leaf.detach();
return;
}
embedContainer.appendChild(view.containerEl);
embedContainer.style.height = 'auto';
ctx.addChild(component);
} catch (error) {
console.error('Sync Embeds: Error processing embed:', error);
this.renderError(container, `Error loading: ${error.message}`, addGap);
}
}
renderError(container, message, addGap) {
const errorDiv = container.createDiv('sync-embed-error');
if (addGap) errorDiv.addClass('sync-embed-gap');
errorDiv.setText(message);
}
};

10
manifest.json Normal file
View file

@ -0,0 +1,10 @@
{
"id": "sync-embeds",
"name": "Sync Embeds",
"version": "1.0.0",
"minAppVersion": "0.15.0",
"description": "Create fully editable, live-synced note embeds.",
"author": "uthvah",
"authorUrl": "https://github.com/uthvah",
"isDesktopOnly": false
}

84
styles.css Normal file
View file

@ -0,0 +1,84 @@
/* Main container for the sync block */
.sync-container {
border: 1px solid var(--background-modifier-border);
border-radius: 8px;
padding: 16px;
background: var(--background-primary);
margin: 12px 0;
display: flex;
flex-direction: column;
gap: 16px;
}
/* Individual embed container */
.sync-embed {
border: none !important;
margin: 0 !important;
padding: 0 !important;
background: transparent !important;
box-shadow: none !important;
}
/* --- SEAMLESS STYLING FOR EMBEDDED EDITOR --- */
/* Hide the view's header (title bar, icons) completely */
.sync-embed .view-header {
display: none !important;
}
/* Make the main content area and editor background transparent */
.sync-embed .view-content,
.sync-embed .markdown-source-view,
.sync-embed .cm-editor,
.sync-embed .cm-scroller {
background-color: transparent !important;
padding: 0 !important;
margin: 0 !important;
}
/* Ensure the editor itself takes up the full width */
.sync-embed .markdown-source-view.mod-cm6 .cm-editor {
width: 100%;
}
/* Remove padding from the view content area */
.sync-embed .view-content {
padding: 0 var(--file-margins) !important;
}
/* Remove extra vertical padding from CodeMirror */
.sync-embed .cm-s-obsidian .cm-gutters,
.sync-embed .cm-s-obsidian .cm-content {
padding-top: 0 !important;
padding-bottom: 0 !important;
}
/* Optional: remove line numbers */
.sync-embed .cm-gutters {
display: none;
}
.sync-embed .cm-content {
padding-left: 0 !important;
}
/* --- UTILITY & ERROR STYLING --- */
.sync-embed-gap {
padding-top: 16px;
border-top: 1px solid var(--background-modifier-border-hover);
}
.sync-empty {
padding: 20px;
text-align: center;
color: var(--text-muted);
font-style: italic;
}
.sync-embed-error {
padding: 8px 12px;
background: var(--background-modifier-error);
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
color: var(--text-error);
}