/** * Update mapping blocks for specific links without prompting for all links. * Used when user changes specific links (single-link, selection-links, create-link). */ import { App, TFile } from "obsidian"; import type { MindnetSettings } from "../settings"; import { splitIntoSections, type NoteSection } from "./sectionParser"; import { parseEdgesFromCallouts } from "../parser/parseEdgesFromCallouts"; import { extractExistingMappings, removeWrapperBlock, type SectionMappingState, } from "./mappingExtractor"; import { buildMappingBlock, insertMappingBlock, type MappingBuilderOptions, } from "./mappingBuilder"; import { convertRelLinksToEdges } from "../parser/parseRelLinks"; /** * Update mapping blocks for sections containing rel: links, without prompting. * Only processes links that are already in [[rel:type|link]] format. */ export async function updateMappingBlocksForRelLinks( app: App, file: TFile, settings: MindnetSettings ): Promise { let content = await app.vault.read(file); const lines = content.split(/\r?\n/); // Convert [[rel:type|link]] links to normal [[link]] and extract edge mappings const { convertedContent, edgeMappings: relLinkMappings } = convertRelLinksToEdges(content); content = convertedContent; if (relLinkMappings.size === 0) { // No rel: links to process return; } console.log(`[UpdateMappingBlocks] Converting ${relLinkMappings.size} rel: links to edge mappings`); // Split into sections const sections = splitIntoSections(content); // Process sections in reverse order (to preserve line indices when modifying) const modifiedSections: Array<{ section: NoteSection; newContent: string }> = []; for (const section of sections) { if (section.links.length === 0) { // No links, skip modifiedSections.push({ section, newContent: section.content, }); continue; } // Extract existing mappings const mappingState = extractExistingMappings( section.content, settings.mappingWrapperCalloutType, settings.mappingWrapperTitle ); // Merge rel: link mappings (from [[rel:type|link]] format) into existing mappings // Key = Section-Link (mit #Abschnitt), damit Edge-Block >> [[Note#Abschnitt]] ausgibt for (const [linkBasename, edgeType] of relLinkMappings.entries()) { const matchingLink = section.links.find( link => link === linkBasename || (link.split("|")[0]?.trim() === linkBasename.split("|")[0]?.trim()) ); if (matchingLink !== undefined) { mappingState.existingMappings.set(matchingLink, edgeType); console.log(`[UpdateMappingBlocks] Updated rel: link mapping: ${matchingLink} -> ${edgeType}`); } } // Remove wrapper block if exists let sectionContentWithoutWrapper = section.content; if (mappingState.wrapperBlockStartLine !== null && mappingState.wrapperBlockEndLine !== null) { sectionContentWithoutWrapper = removeWrapperBlock( section.content, mappingState.wrapperBlockStartLine, mappingState.wrapperBlockEndLine ); } // Build mapping block with updated mappings const mappingOptions: MappingBuilderOptions = { wrapperCalloutType: settings.mappingWrapperCalloutType, wrapperTitle: settings.mappingWrapperTitle, wrapperFolded: settings.mappingWrapperFolded, defaultEdgeType: settings.defaultEdgeType, assignUnmapped: "none", // Don't assign unmapped links, just use existing mappings }; const mappingBlock = buildMappingBlock( section.links, mappingState.existingMappings, mappingOptions ); if (mappingBlock) { const newContent = insertMappingBlock(sectionContentWithoutWrapper, mappingBlock); modifiedSections.push({ section, newContent, }); } else { // No mapping block needed modifiedSections.push({ section, newContent: sectionContentWithoutWrapper, }); } } // Reconstruct file content with modified sections let newContent = ""; let currentLine = 0; for (let i = 0; i < modifiedSections.length; i++) { const { section, newContent: sectionNewContent } = modifiedSections[i]!; // Add lines before this section if (currentLine < section.startLine) { newContent += lines.slice(currentLine, section.startLine).join("\n"); if (currentLine < section.startLine) { newContent += "\n"; } } // Add modified section content newContent += sectionNewContent; currentLine = section.endLine; // Add newline between sections (except for last section) if (i < modifiedSections.length - 1) { newContent += "\n"; } } // Add remaining lines after last section if (currentLine < lines.length) { newContent += "\n" + lines.slice(currentLine).join("\n"); } // Write back to file await app.vault.modify(file, newContent); console.log(`[UpdateMappingBlocks] Updated mapping blocks for ${modifiedSections.length} sections`); }