Skip to content

Commit

Permalink
feat: test + refactor embedded header
Browse files Browse the repository at this point in the history
  • Loading branch information
fnumatic committed Nov 15, 2022
1 parent d3760a0 commit 8f8c207
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 40 deletions.
18 changes: 10 additions & 8 deletions src/renderers/code-block-renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
WorkspaceLeaf,
} from "obsidian";
import { mergeSettings } from "../utils/config";
import { extractHeadings, mergeEmbeds } from "../utils/extract-headings";
import { extractHeadings, embeddedHeadings, mergeHeadings, processableHeadings } from "../utils/extract-headings";
import { DynamicTOCSettings, TableOptions } from "../types";
import { TABLE_CLASS_NAME } from "src/constants";

Expand Down Expand Up @@ -57,17 +57,19 @@ export class CodeBlockRenderer extends MarkdownRenderChild {
async render(configOverride?: TableOptions) {
this.container.empty();
this.container.classList.add(TABLE_CLASS_NAME);
const mergedMetaData = mergeEmbeds(
this.app.metadataCache,
this.filePath,
configOverride || this.config
)
const headings = extractHeadings(
const fileMetaData = this.app.metadataCache.getCache(this.filePath)
const { headings, embeds } = fileMetaData;
const embbedHeadings = embeddedHeadings(this.app.metadataCache, embeds)

//if (not embeds parsing allowed in options ) return fileMetaData;
const mergedMetaData = embbedHeadings ? mergeHeadings(headings, embbedHeadings ) : fileMetaData;

const headings_ = extractHeadings(
mergedMetaData,
configOverride || this.config
);
await MarkdownRenderer.renderMarkdown(
headings,
headings_,
this.container,
this.filePath,
this
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Extract embedded headings build markdown text should match snapshot 1`] = `
"- [[#foo]]
- [[#bar emb]]
- [[#bar emb L2]]
- [[#bar emb L3]]"
`;

exports[`Extract headings build markdown text should match snapshot 1`] = `
"1. [[#foo]]
1. [[#bar]]
Expand Down
39 changes: 37 additions & 2 deletions src/utils/__tests__/extract-headings.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { CachedMetadata } from "obsidian";
import { CachedMetadata,HeadingCache } from "obsidian";
import { TableOptions } from "src/types";
import { extractHeadings } from "../extract-headings";
import { extractHeadings, mergeHeadings, EmbeddedHeadings } from "../extract-headings";

jest.mock('obsidian');

Expand Down Expand Up @@ -164,3 +164,38 @@ describe("Extract headings", () => {
});
});
});

describe("Extract embedded headings", () => {
describe("build markdown text", () => {
const defaultHeadings = [
{
heading: "foo",
level: 2,
},
{
heading: "![[bar emb]]",
level: 2,
},
] as HeadingCache[];
const embeddedHeadings = {
"![[bar emb]]": [
{
heading: "bar emb L2",
level: 2,
},
{
heading: "bar emb L3",
level: 3,
},
] as HeadingCache[] ,
} as EmbeddedHeadings ;
it("should match snapshot", () => {
const options = {
max_depth: 4,
min_depth: 1,
style: "bullet",
} as TableOptions;
expect(extractHeadings(mergeHeadings(defaultHeadings,embeddedHeadings), options)).toMatchSnapshot();
});
});
})
59 changes: 29 additions & 30 deletions src/utils/extract-headings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { CachedMetadata, MetadataCache, parseLinktext,HeadingCache, EmbedCache }
import { Heading } from "../models/heading";
import { TableOptions } from "../types";

export type EmbeddedHeadings = {[key:string]:HeadingCache[]}

export function extractHeadings(
fileMetaData: CachedMetadata,
options: TableOptions
Expand All @@ -21,51 +23,48 @@ export function extractHeadings(
return buildMarkdownText(headingInstances, options);
}

export function mergeEmbeds(metadataCache: MetadataCache, filePath: string, options: TableOptions) {
const fileMetaData = metadataCache.getCache(filePath)
//if (not embeds parsing allowed in options ) return fileMetaData;
if (!fileMetaData?.headings || !fileMetaData?.embeds) return fileMetaData;
const { headings, embeds } = fileMetaData;
const processableHeadings = headings.filter(
export function processableHeadings (options:TableOptions, headings:HeadingCache[]){
return headings.filter(
(h) => !!h && h.level >= options.min_depth && h.level <= options.max_depth
);
if (!processableHeadings.length) return fileMetaData;

//[h1,h2,...] -> {h1.heading: h1, h2.heading: h2, ...}
const headingsDb = processableHeadings
.reduce((agg,h) => ({...agg, [h.heading]: h }), {})

const grabEmbeddedHeadings = (agg:Object, e:EmbedCache) => {
const offset = headingsDb[e.original].level;
const eheadings =
linkToCachedMetadata(e.link, metadataCache)
.headings
.filter(h => h.level > 1)
.map(tweakOffset(offset));
return {...agg, [e.original]: eheadings };
}

export function embeddedHeadings(metadataCache: MetadataCache, embeds:EmbedCache[]) : EmbeddedHeadings {
if (!embeds) return undefined

const grabEmbeddedHeadings = (agg:{}, e:EmbedCache) => {
const embeddedHeadings = linkToCachedMetadata(e.link, metadataCache).headings;
return {...agg, [e.original]: embeddedHeadings };
}

//[e1,e2,...] -> {e1.original: e1.headings, ...}
const embeddedHeadingsDb = embeds
.filter( (e) => e.original in headingsDb)
.reduce(grabEmbeddedHeadings,{});

const patchedHeadings = headings.flatMap(h => {
const eheadings = embeddedHeadingsDb[h.heading];
return (eheadings) ? [h,...eheadings] : [h];
});
return embeds
.reduce(grabEmbeddedHeadings,{} ) ;
}

export function mergeHeadings(headings:HeadingCache[], embeddedHeadings:EmbeddedHeadings) {
const insertHeadings = (h: HeadingCache): HeadingCache []=> {
const offset = h.level;
const eheadings = embeddedHeadings[h.heading]
?.filter((h:HeadingCache) => h.level > 0)
.map(tweakOffset(offset));
return (eheadings) ? [h, ...eheadings] : [h];
};

const patchedHeadings = headings.flatMap(insertHeadings);
return {headings:patchedHeadings} as CachedMetadata;
}

function tweakOffset(offset: number) {
return (h: HeadingCache) => ({ ...h, level: h.level + offset - 1 });
function tweakOffset(offset: number) {
return (h: HeadingCache) => ({ ...h, level: h.level + offset - 1 } as HeadingCache);
}

function linkToCachedMetadata(link:string, metadataCache: MetadataCache) {
const {path,subpath}= parseLinktext(link)
const f = metadataCache.getFirstLinkpathDest(path,subpath)
return metadataCache.getCache(f.path)
}

function getIndicator(
heading: Heading,
firstLevel: number,
Expand Down

0 comments on commit 8f8c207

Please sign in to comment.