Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nested custom entries that reuse existing entries have prefixing side effects #37

Open
kgar opened this issue Aug 14, 2022 · 0 comments

Comments

@kgar
Copy link
Owner

kgar commented Aug 14, 2022

Given this Obsidian Callout custom entry:

export type ObsidianCalloutEntry = {
  callout: {
    type: string;
    title?: InlineTypes[] | InlineTypes;
    content: MarkdownEntry | MarkdownEntry[];
    initialState?: 'expanded' | 'collapsed';
  };
};

export const calloutRenderer: MarkdownRenderer = (
  entry: ObsidianCalloutEntry,
  options: RenderOptions
) => {
  let titleContent = getTitleContent(entry);

  let content = Array.isArray(entry.callout.content)
    ? entry.callout.content
    : [entry.callout.content];

  let initialState =
    entry.callout.initialState === 'collapsed'
      ? '-'
      : entry.callout.initialState === 'expanded'
      ? '+'
      : '';

  const blockquote: BlockquoteEntry = {
    blockquote: [
      { p: [`[!${entry.callout.type}]${initialState}`, ...titleContent] },
      ...content,
    ],
  };

  return {
    markdown: renderEntries([blockquote], { ...options),
    blockLevel: true,
  };
};

function getTitleContent(entry: ObsidianCalloutEntry): InlineTypes[] {
  if (!entry.callout.title) {
    return [];
  }

  const title = entry.callout.title;
  let normalizedTitle = Array.isArray(title) ? title : [title];

  return [' ', ...normalizedTitle];
}

The expected format of nested callouts is to append one additional layer of blockquote. So, a callout within a callout should look like this:

> [!info]+ Some Title Here
> 
> > [!quote]+ 
> > 
> > Here's a quote.

Instead, it looks like this:

> [!info]+ Some Title Here
> 
> > > [!quote]+ 
> > > 
> > > Here's a quote.

In general, this is because the callout implementation is calling renderEnties(), which is the established example in the docs.

The workaround is to update the callout renderer as follows:

  return {
    markdown: renderEntries([blockquote], { ...options, prefix: '' }),
    blockLevel: true,
  };

This works, but it feels awkward to do, and it's not obvious to an implementer of custom renderers which reuse existing renderers.

I'm not sure yet on a solution for this that will prevent headaches for custom entry authors, but I'm putting the issue here for now so it can be explored later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant