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

Obsidian themes integration approach #1451

Open
saberzero1 opened this issue Sep 27, 2024 · 6 comments
Open

Obsidian themes integration approach #1451

saberzero1 opened this issue Sep 27, 2024 · 6 comments
Labels
enhancement New feature or request

Comments

@saberzero1
Copy link
Collaborator

I noticed there have been frequent requests for Obsidian theme support for a long time now.

As mentioned in the Discord server, I had an idea and didn't stop having that idea. The results is Quartz Themes. The project is rather bare bones, but being worked on.

I was wondering if this is something we (eventually) want to integrate in the Quartz repository?

Could be integrated as:

  • Just a documentation page with integration instructions.
  • Integrating it in the npx quartz commands, but not in the Quartz repository.
  • Integrating it in the Quartz repository as git submodule.
  • Probably some other ways

@jackyzha0 @aarnphm what do you guys think? Any idea/opinion/feedback is welcome.

@saberzero1 saberzero1 added the enhancement New feature or request label Sep 27, 2024
@aarnphm
Copy link
Collaborator

aarnphm commented Sep 27, 2024

I would like to hear from Jacky as well, but we can create a quartz-community where projects like this can live. Collaborators who want to work on these plugins will have more agency to own the plugin instead of waiting to merge into Quartz. This will also make Quartz a lot lighter.

I think it might be worth thinking about plugin system #804 again

but will def involve a bit of design work

@aarnphm
Copy link
Collaborator

aarnphm commented Sep 27, 2024

But then again, it is an opinionated SSG, so plugins might also be a premature optimisation

@saberzero1
Copy link
Collaborator Author

saberzero1 commented Sep 27, 2024

I would like to hear from Jacky as well, but we can create a quartz-community where projects like this can live. Collaborators who want to work on these plugins will have more agency to own the plugin instead of waiting to merge into Quartz. This will also make Quartz a lot lighter.

I think it might be worth thinking about plugin system #804 again

but will def involve a bit of design work

Apologies for the wall of text...

Fair point. I do think a plugin system within Quartz should be split in two or three components, if we want to pursue that option:

  • Components: Small parts that essentially create the parts that make up the page. For example:
    • Plugin that shows the 5 most recent posts
    • Plugin that embeds somethings, like the most recent tweets of a person, the current weather, or a calendar.
    • Plugin that transforms code blocks into small interactive components that evaluate the code, kinda like Jupyter.
    • Plugin that creates a button to toggle a high-contrast filter to make text more readable.
    • Plugin that shows a light tint on top of recent revision to the page's content.
  • Processors: What we currently call plugins. Things that transform markdown files into the web pages we know and love. For example:
    • Plugin that parses Base64-encoded strings to images.
    • Plugin that filters out all pages older than 6 months.
    • Plugin that creates a reading-mode friendly version.
    • Plugin that imitates a specific Obsidian plugin, like Dataview or Meta-Bind.
  • Styles: How the sites look and feel. For example:
    • Plugin that allows users to easily set a theme.
    • Plugin that add animations to components, like displaying skeleton text or a throbber while page content loads.
    • Plugin that add visual effects to components, like making them a little transparent or glow when hovered.

In my opinion, the above three things require three different approaches.

  • Components are about layout. Components should be relatively simple and self-contained. They should be a small inline.ts file with the logic, a small inline.scss file with the styling, and a small tsx file with the layout in DOM. User should be able to configure them inside quartz.layout.ts.
  • Processors are about parsing, Processors turn source files (markdown or otherwise) into HTML/CSS/JavaScript that can be rendered in the browser. Processors should be as simple as possible, but they can be complicated if needed, as they only run during compilation and are never shown to users in the browser.
  • Styles are about aesthetics. The only concern the resulting web pages.

My first thought to implement above would be roughly this:

For Components:

  • Relatively simple in scope.
  • Only adds a single functionality to the resulting web pages.
  • Configurable in quartz.layout.ts.
  • Only has a few possible options to set, if any at all.

For Processors:

  • Anything from very simple to extremely complicated.
  • Can add or change a lot of functionality, but only for processing source files into web page content.
  • Configurable in quartz.config.ts.
  • Can have many options to set.

For Styles:

  • Should only contain style options
  • Adds no functionality.
  • Configurable in a new file: quartz.themes.ts
  • Should have very limited option. Nothing more than setting a specific theme for light mode or dark mode with maybe a specific flavor (like mocha, macchiato, or frappe for catppuccin dark mode).

Processors would be the most sophisticated, adding a lot of functionality, but remaining limited to the parsing process. This is similar to a plugin like Dataview, where it adds a lot of functionality when in use inside Obsidian, but is nothing more than a fancy code block in markdown outside of Obsidian.

Components would be like simple plugins, like the calendar plugin in Obsidian. Very self-contained.

Styles would be like themes. Single click install with no options other than the variant/flavor of a theme. Settings are sometimes available with the use of a plugin.

To conclude

  • Processors can be very complicated. I am not fully sure how to approach them yet. I'm still exploring this, but I feel like my Markdown parser rework might ultimately not be the best approach.
  • Components can be require a bit more configuration from the user. I feel like something similar to how Lazy.nvim handles configuration of plugins for Neovim could be feasible.
  • Styles should be extremely simple to use, just pick and choose and be done with it, as this is likely the most important customization feature for non-developer or inexperienced user of Quartz. I feel like it should be extremely easy to configure.

@saberzero1
Copy link
Collaborator Author

I also realize that I might be effectively ushering Quartz v5 into life with above ambitions.

@aarnphm
Copy link
Collaborator

aarnphm commented Sep 28, 2024

IDK how I feel about the cardinality of components, given that current components/processors/styles are considered in total order.

@saberzero1
Copy link
Collaborator Author

IDK how I feel about the cardinality of components, given that current components/processors/styles are considered in total order.

Okay. I have an idea for themes. It is probably easiest if I change my Quartz Themes project to compile the styles to CSS and create a small plugin in Quartz to pull the desired theme into the bundle during the esbuild step. The source repo URL should probably be configurable to allow users to grab additional CSS from other sources, or to specify another theme source beside my project. Something like that at least. Not entirely sure about the specifics yet.

After giving the current plugins ecosystem some more thought, I feel like the current parser system should be turned 90 degrees.

Currently, many parser have one or more of the following:

  • Text to text parser
  • Markdown to markdown parser
  • HTML to HTML parser
  • External resources (js, CSS)

If feel like we should have 4 parsers instead:

  • Text parsers
  • Markdown parsers
  • HTML parsers
  • External resource parsers.

Intuitively, if I place the GitHub parser before the Obsidian parser, I expect the GitHub parser to execute all its operations (text, markdown, HTML, external resources) before the Obsidian parser even starts its text parsing. This is not the case. Currently, all text parsers are run, then markdown, then HTML, then external resources.

I know at least one long-standing bug that currently is caused by this: GitHub style callouts inside markdown codeblocks are parsed by the Obsidian parser as callouts. The GitHub parser runs after Obsidian, but in this specific case, the codeblock part in the GitHub markdown parser should run before the callout part of the Obsidian markdown parser. Currently this is impossible without running all of the GitHub parser before the Obsidian parser.

By turning the parsers like this, it becomes a lot easier to break up parsers into many small parser steps (text to text, markdown to markdown, HTML to HTML, external resources).

A change akin to above would effectively implement a plugin system for the parsing part. There are some small caveats, especially related to the vfile data that is passed on to the filters/emitters, that I'll have to figure out.

Lastly, I feel like the emitters should probably be the place to incorporate default and custom components. I have not given it enough thought yet to give a clear direction. I'll focus on the parsers for now and try out my above idea to see if it holds up. I'll keep you posted.

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

No branches or pull requests

2 participants