diff --git a/src/data-import/markdown-file.ts b/src/data-import/markdown-file.ts index e223da88..86902dd1 100644 --- a/src/data-import/markdown-file.ts +++ b/src/data-import/markdown-file.ts @@ -216,7 +216,27 @@ export function parseLists( ); // Find the section we belong to as well. - let sectionName = findPreviousHeader(rawElement.position.start.line, metadata.headings || []); + let sectionName = undefined; + var headers = Array.from(metadata.headings || []); + let headings = new Array(); + let headingIndex = findPreviousHeader(rawElement.position.start.line, headers); + if (headingIndex >= 0) { + let section = metadata.headings![headingIndex]; + sectionName = section.heading; + headings.push(section); + let level = section.level; + while (--headingIndex >= 0) { + let section = metadata.headings![headingIndex]; + if (level > section.level) { + level = section.level; + headings.push(section); + if (level <= 1) { + break; + } + } + } + } + headings.reverse(); //sort in ascending order, so you can group by e.g. the Top Heading let sectionLink = sectionName === undefined ? Link.file(path) : Link.header(path, sectionName); let closestLink = rawElement.id === undefined ? sectionLink : Link.block(path, rawElement.id); @@ -232,6 +252,7 @@ export function parseLists( link: closestLink, links: links, section: sectionLink, + headings: headings, text: textWithNewline, tags: common.extractTags(textNoNewline), line: rawElement.position.start.line, @@ -415,12 +436,9 @@ export function mergeFieldGroups(target: Map, source: Map line) return undefined; - +export function findPreviousHeader(line: number, headers: HeadingCache[]): number { let index = headers.length - 1; while (index >= 0 && headers[index].position.start.line > line) index--; - return headers[index].heading; + return index; } diff --git a/src/data-model/markdown.ts b/src/data-model/markdown.ts index eb9ebffe..37486ce1 100644 --- a/src/data-model/markdown.ts +++ b/src/data-model/markdown.ts @@ -5,6 +5,7 @@ import { Literal, Link, Values } from "data-model/value"; import { DataObject } from "index"; import { SListItem, SMarkdownPage } from "data-model/serialized/markdown"; import { Pos } from "obsidian"; +import { HeadingCache } from "obsidian"; /** All extracted markdown file metadata obtained from a file. */ export class PageMetadata { @@ -168,6 +169,8 @@ export class ListItem { link: Link; /** A link to the section that contains this list element; could be a file if this is not in a section. */ section: Link; + /** List of all Headings 'above' this one in ascending Order, to be able to properly group List Items */ + headings: HeadingCache[]; /** The text of this list item. This may be multiple lines of markdown. */ text: string; /** The line that this list item starts on in the file. */ @@ -256,6 +259,14 @@ export class ListItem { symbol: this.symbol, link: this.link, section: this.section, + headings: this.headings.map(h => "#".repeat(h.level) + " " + h.heading), /*{ + const heading: HeadingCache = { + heading: h.heading, + level: h.level, + position: h.position + } + return heading; + }),*/ text: this.text, tags: Array.from(this.tags), line: this.line, diff --git a/test-vault/tasks/Tasks in a specific section.md b/test-vault/tasks/Tasks in a specific section.md index b808f274..9b41cdbe 100644 --- a/test-vault/tasks/Tasks in a specific section.md +++ b/test-vault/tasks/Tasks in a specific section.md @@ -2,6 +2,6 @@ ```dataview task -where meta(section).subpath = "Section" -group by section +where meta(section).subpath +group by headings ```