- Introduced a wide two-column layout for the Chain Workbench modal, improving user experience and accessibility. - Added new styles for workbench components, including headers, filters, and main containers, to enhance visual organization. - Updated chain templates to allow for multiple distinct matches per template, improving flexibility in template matching. - Enhanced documentation to clarify the new settings and commands related to the Chain Workbench and edge detection features. - Implemented logging for better tracking of missing configurations, ensuring users are informed about any loading issues.
156 lines
5.0 KiB
TypeScript
156 lines
5.0 KiB
TypeScript
/**
|
|
* 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<void> {
|
|
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`);
|
|
}
|