How could I source a paragraph underneath a specific header in a dataview table?

What I’m trying to do

Get the text from a paragraph underneath a specific header and display it in a column in a dataview table.
If this isn’t possible with dataview, is it possible with datacore? (And if so how?)

Things I have tried

Searching the web for:
“obsidian how to display text block in dataview table”
“how to display body text in dataview table”

But that wasn’t very helpful.

With Dataview, it is not possible, but with his stronger brother DataviewJS, it can be achieved. It’s funny, as I have been playing with similar things the last few weeks but am still polishing to put a post out confidently.

But here is the starting point for your request …

```dataviewjs
const noteName = "path/to/the/note"; // Change to your note
const headerToFind = "header"; // Change to your exact header (case-sensitive!)

const page = dv.page(noteName);

if (page?.file?.path) {
    const fileContent = await app.vault.read(app.vault.getAbstractFileByPath(page.file.path));
    const lines = fileContent.split("\n");

    let startIndex = -1;
    let headerLevel = 0;

    // Find header
    for (let i = 0; i < lines.length; i++) {
        const match = lines[i].match(/^(#+)\s+(.*)$/);
        if (match && match[2].trim() === headerToFind) {
            startIndex = i + 1;
            headerLevel = match[1].length;
            break;
        }
    }

    if (startIndex === -1) {
        dv.table(["Note", "Header", "Content"], [[noteName, headerToFind, "❌ Header not found"]]);
    } else {
        let endIndex = lines.length;

        // Find where this section ends
        for (let i = startIndex; i < lines.length; i++) {
            const match = lines[i].match(/^(#+)\s+/);
            if (match && match[1].length <= headerLevel) {
                endIndex = i;
                break;
            }
        }

        // Extract paragraph
        const paragraphLines = lines.slice(startIndex, endIndex)
            .filter(line => line.trim() !== "" && !line.trim().startsWith("#"));

        const paragraph = paragraphLines.join("\n").trim() || "(No content found)";
        
        // Output table
        dv.table(["Note", "Header", "Content"], [[noteName, headerToFind, paragraph]]);
    }
}
```

Hope it helps you achieve what you are looking for.

Cheers, Marko :nerd_face:

1 Like

Dataview doesn’t extract text from the note of a body by default, but it can extract text from list and task items, and inline fields. All of these are available in the normal DQL query. If you want to, you can also as @DiCaver says, switch to dataviewjs and read the file by your self.

Here is a brief breakdown of the various options using Dataview to extract text from a file:

  • Use dataviewjs utilising something like app.vault.read() to read the full content of a file
  • Switch to using list items, and then extract the text of the list item under that specific heading
  • Switch to using a task item with a custom format, and then extract the task with that custom status character. This can be beautifully styled as well
  • Define an inline field to hold the text you want to extract from that file

The last three can somewhat easily be used in a DQL query and be presented in a table. The first requires some javascript coding skills.


I’m not sure how this would be done in datacore, or if/when that kind of functionality will be available. Most likely you can already now do something similar to the dataviewjs solution.

1 Like