mirror of
https://github.com/alamion/obsidian-jira-sync.git
synced 2026-07-22 05:43:04 +00:00
feat: add adfToMarkdown for bidirectional description sync
Implement adfToMarkdown, adfInlineToMarkdown, and adfBlockToMarkdown so that pulling a Jira issue back into Obsidian converts the ADF description to clean markdown rather than clobbering the note with raw HTML or wiki markup. Export adfToMarkdown and register it in SAFE_GLOBALS / context so field mapping expressions can call it directly.
This commit is contained in:
parent
1a14ac37c7
commit
75f9277387
2 changed files with 59 additions and 1 deletions
|
|
@ -5,7 +5,7 @@ import {debugLog} from "./debugLogging";
|
|||
import {FieldMapping} from "../default/obsidianJiraFieldsMapping";
|
||||
import {defaultIssue} from "../default/defaultIssue";
|
||||
import {jiraToMarkdown, markdownToJira} from "./markdownHtml";
|
||||
import {markdownToAdf} from "./markdownToAdf";
|
||||
import {markdownToAdf, adfToMarkdown} from "./markdownToAdf";
|
||||
|
||||
// Constants for validation and error messages
|
||||
const FORBIDDEN_PATTERNS = ["document", "window", "eval", "Function", "fetch", "setTimeout", "globalThis"];
|
||||
|
|
@ -14,6 +14,7 @@ const SAFE_GLOBALS = {
|
|||
jiraToMarkdown,
|
||||
markdownToJira,
|
||||
markdownToAdf,
|
||||
adfToMarkdown,
|
||||
JSON: {
|
||||
parse: JSON.parse,
|
||||
stringify: JSON.stringify
|
||||
|
|
@ -178,6 +179,7 @@ export async function safeStringToFunction(
|
|||
jiraToMarkdown,
|
||||
markdownToJira,
|
||||
markdownToAdf,
|
||||
adfToMarkdown,
|
||||
JSON,
|
||||
Math,
|
||||
Date,
|
||||
|
|
|
|||
|
|
@ -197,3 +197,59 @@ export function markdownToAdf(markdown: string): AdfDoc | null {
|
|||
|
||||
return content.length > 0 ? { version: 1, type: 'doc', content } : null;
|
||||
}
|
||||
|
||||
function adfInlineToMarkdown(nodes: any[]): string {
|
||||
if (!nodes) return '';
|
||||
return nodes.map(node => {
|
||||
if (node.type === 'hardBreak') return '\n';
|
||||
if (node.type !== 'text') return '';
|
||||
const text = node.text || '';
|
||||
const marks: string[] = (node.marks || []).map((m: any) => m.type);
|
||||
let result = text;
|
||||
if (marks.includes('code')) return `\`${result}\``;
|
||||
if (marks.includes('strong')) result = `**${result}**`;
|
||||
if (marks.includes('em')) result = `*${result}*`;
|
||||
return result;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
function adfBlockToMarkdown(node: any): string {
|
||||
if (!node) return '';
|
||||
|
||||
switch (node.type) {
|
||||
case 'heading': {
|
||||
const level = node.attrs?.level || 1;
|
||||
const text = adfInlineToMarkdown(node.content || []);
|
||||
return `${'#'.repeat(level)} ${text}`;
|
||||
}
|
||||
case 'paragraph': {
|
||||
const text = adfInlineToMarkdown(node.content || []);
|
||||
return text;
|
||||
}
|
||||
case 'codeBlock': {
|
||||
const lang = node.attrs?.language || '';
|
||||
const code = (node.content || []).map((n: any) => n.text || '').join('');
|
||||
return `\`\`\`${lang}\n${code}\n\`\`\``;
|
||||
}
|
||||
case 'bulletList': {
|
||||
return (node.content || []).map((item: any) =>
|
||||
`- ${(item.content || []).map((block: any) => adfBlockToMarkdown(block)).join('\n')}`
|
||||
).join('\n');
|
||||
}
|
||||
case 'orderedList': {
|
||||
return (node.content || []).map((item: any, i: number) =>
|
||||
`${i + 1}. ${(item.content || []).map((block: any) => adfBlockToMarkdown(block)).join('\n')}`
|
||||
).join('\n');
|
||||
}
|
||||
case 'rule':
|
||||
return '---';
|
||||
default:
|
||||
return (node.content || []).map((n: any) => adfBlockToMarkdown(n)).join('\n');
|
||||
}
|
||||
}
|
||||
|
||||
export function adfToMarkdown(adf: any): string {
|
||||
if (!adf || typeof adf !== 'object') return '';
|
||||
const blocks: string[] = (adf.content || []).map((node: any) => adfBlockToMarkdown(node));
|
||||
return blocks.filter(b => b !== '').join('\n\n');
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue