obsidian flavored markdown support
This commit is contained in:
		
							parent
							
								
									3636c052eb
								
							
						
					
					
						commit
						c1c46ad67e
					
				
					 6 changed files with 348 additions and 2301 deletions
				
			
		| 
						 | 
				
			
			@ -13,9 +13,11 @@ title: "CJK + Latex Support (测试)"
 | 
			
		|||
 | 
			
		||||
Block math works with two dollar signs `$$...$$`
 | 
			
		||||
 | 
			
		||||
$$f(x) = \int_{-\infty}^\infty
 | 
			
		||||
$$
 | 
			
		||||
f(x) = \int_{-\infty}^\infty
 | 
			
		||||
    f\hat(\xi),e^{2 \pi i \xi x}
 | 
			
		||||
    \,d\xi$$
 | 
			
		||||
    \,d\xi
 | 
			
		||||
$$
 | 
			
		||||
	
 | 
			
		||||
Inline math also works with single dollar signs `$...$`. For example, Euler's identity but inline: $e^{i\pi} = -1$
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2540
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										2540
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -10,8 +10,7 @@
 | 
			
		|||
    "url": "https://github.com/jackyzha0/quartz.git"
 | 
			
		||||
  },
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "typecheck": "tsc --noEmit",
 | 
			
		||||
    "cycle-detect": "madge --circular --extensions ts quartz/index.ts"
 | 
			
		||||
    "typecheck": "tsc --noEmit"
 | 
			
		||||
  },
 | 
			
		||||
  "keywords": [
 | 
			
		||||
    "site generator",
 | 
			
		||||
| 
						 | 
				
			
			@ -25,7 +24,6 @@
 | 
			
		|||
    "quartz": "./quartz/bootstrap.mjs"
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@flowershow/remark-wiki-link": "^1.2.0",
 | 
			
		||||
    "@inquirer/prompts": "^1.0.3",
 | 
			
		||||
    "@napi-rs/simple-git": "^0.1.8",
 | 
			
		||||
    "chalk": "^4.1.2",
 | 
			
		||||
| 
						 | 
				
			
			@ -35,10 +33,12 @@
 | 
			
		|||
    "hast-util-to-jsx-runtime": "^1.2.0",
 | 
			
		||||
    "hast-util-to-string": "^2.0.0",
 | 
			
		||||
    "is-absolute-url": "^4.0.1",
 | 
			
		||||
    "mdast-util-find-and-replace": "^2.2.2",
 | 
			
		||||
    "preact": "^10.14.1",
 | 
			
		||||
    "preact-render-to-string": "^6.0.3",
 | 
			
		||||
    "pretty-time": "^1.1.0",
 | 
			
		||||
    "rehype-katex": "^6.0.3",
 | 
			
		||||
    "rehype-raw": "^6.1.1",
 | 
			
		||||
    "remark": "^14.0.2",
 | 
			
		||||
    "remark-frontmatter": "^4.0.1",
 | 
			
		||||
    "remark-gfm": "^3.0.1",
 | 
			
		||||
| 
						 | 
				
			
			@ -64,7 +64,6 @@
 | 
			
		|||
    "@types/serve-handler": "^6.1.1",
 | 
			
		||||
    "@types/yargs": "^17.0.24",
 | 
			
		||||
    "esbuild": "^0.17.18",
 | 
			
		||||
    "madge": "^6.0.0",
 | 
			
		||||
    "typescript": "^5.0.4"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,8 @@
 | 
			
		|||
import { buildQuartz } from "./quartz"
 | 
			
		||||
import Head from "./quartz/components/Head"
 | 
			
		||||
import { ContentPage, CreatedModifiedDate, Description, FrontMatter, GitHubFlavoredMarkdown, Katex, RemoveDrafts } from "./quartz/plugins"
 | 
			
		||||
import { LinkProcessing } from "./quartz/plugins/transformers/links"
 | 
			
		||||
import { ResolveLinks } from "./quartz/plugins/transformers/links"
 | 
			
		||||
import { ObsidianFlavoredMarkdown } from "./quartz/plugins/transformers/ofm"
 | 
			
		||||
 | 
			
		||||
export default buildQuartz({
 | 
			
		||||
  configuration: {
 | 
			
		||||
| 
						 | 
				
			
			@ -11,14 +12,15 @@ export default buildQuartz({
 | 
			
		|||
  },
 | 
			
		||||
  plugins: {
 | 
			
		||||
    transformers: [
 | 
			
		||||
      new LinkProcessing(),
 | 
			
		||||
      new FrontMatter(),
 | 
			
		||||
      new GitHubFlavoredMarkdown(),
 | 
			
		||||
      new Katex(),
 | 
			
		||||
      new Description(),
 | 
			
		||||
      new CreatedModifiedDate({
 | 
			
		||||
        priority: ['frontmatter', 'filesystem'] // you can add 'git' here for last modified from Git but this makes the build slower
 | 
			
		||||
      }),
 | 
			
		||||
      new GitHubFlavoredMarkdown(),
 | 
			
		||||
      new ObsidianFlavoredMarkdown(),
 | 
			
		||||
      new ResolveLinks(),
 | 
			
		||||
    ],
 | 
			
		||||
    filters: [
 | 
			
		||||
      new RemoveDrafts()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,5 @@
 | 
			
		|||
import { PluggableList } from "unified"
 | 
			
		||||
import { QuartzTransformerPlugin } from "../types"
 | 
			
		||||
import { remarkWikiLink } from "@flowershow/remark-wiki-link"
 | 
			
		||||
import { relative, relativeToRoot, slugify } from "../../path"
 | 
			
		||||
import path from "path"
 | 
			
		||||
import { visit } from 'unist-util-visit'
 | 
			
		||||
| 
						 | 
				
			
			@ -18,7 +17,7 @@ const defaultOptions: Options = {
 | 
			
		|||
  prettyLinks: true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class LinkProcessing extends QuartzTransformerPlugin {
 | 
			
		||||
export class ResolveLinks extends QuartzTransformerPlugin {
 | 
			
		||||
  name = "LinkProcessing"
 | 
			
		||||
  opts: Options
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -28,9 +27,7 @@ export class LinkProcessing extends QuartzTransformerPlugin {
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  markdownPlugins(): PluggableList {
 | 
			
		||||
    return [[remarkWikiLink, {
 | 
			
		||||
      pathFormat: this.opts.markdownLinkResolution === "absolute" ? 'obsidian-absolute' : 'raw',
 | 
			
		||||
    }]]
 | 
			
		||||
    return []
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  htmlPlugins(): PluggableList {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										81
									
								
								quartz/plugins/transformers/ofm.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								quartz/plugins/transformers/ofm.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,81 @@
 | 
			
		|||
import { PluggableList } from "unified"
 | 
			
		||||
import { QuartzTransformerPlugin } from "../types"
 | 
			
		||||
import { Root } from 'mdast'
 | 
			
		||||
import { findAndReplace } from "mdast-util-find-and-replace"
 | 
			
		||||
import { slugify } from "../../path"
 | 
			
		||||
import rehypeRaw from "rehype-raw"
 | 
			
		||||
 | 
			
		||||
export interface Options {
 | 
			
		||||
  highlight: boolean
 | 
			
		||||
  wikilinks: boolean
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const defaultOptions: Options = {
 | 
			
		||||
  highlight: true,
 | 
			
		||||
  wikilinks: true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class ObsidianFlavoredMarkdown extends QuartzTransformerPlugin {
 | 
			
		||||
  name = "ObsidianFlavoredMarkdown"
 | 
			
		||||
  opts: Options
 | 
			
		||||
 | 
			
		||||
  constructor(opts?: Options) {
 | 
			
		||||
    super()
 | 
			
		||||
    this.opts = { ...defaultOptions, ...opts }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  markdownPlugins(): PluggableList {
 | 
			
		||||
    const plugins: PluggableList = []
 | 
			
		||||
 | 
			
		||||
    if (this.opts.wikilinks) {
 | 
			
		||||
      plugins.push(() => {
 | 
			
		||||
        // Match wikilinks 
 | 
			
		||||
        // !?               -> optional embedding
 | 
			
		||||
        // \[\[             -> open brace
 | 
			
		||||
        // ([^\[\]\|\#]+)   -> one or more non-special characters ([,],|, or #) (name)
 | 
			
		||||
        // (#[^\[\]\|\#]+)? -> # then one or more non-special characters (heading link)
 | 
			
		||||
        // (|[^\[\]\|\#]+)? -> | then one or more non-special characters (alias)
 | 
			
		||||
        const backlinkRegex = new RegExp(/!?\[\[([^\[\]\|\#]+)(#[^\[\]\|\#]+)?(\|[^\[\]\|\#]+)?\]\]/, "g")
 | 
			
		||||
        return (tree: Root, _file) => {
 | 
			
		||||
          findAndReplace(tree, backlinkRegex, (value: string, ...capture: string[]) => {
 | 
			
		||||
            const [path, rawHeader, rawAlias] = capture
 | 
			
		||||
            const header = rawHeader?.slice(1).trim() ?? ""
 | 
			
		||||
            const alias = rawAlias?.slice(1).trim() ?? value 
 | 
			
		||||
            const url = slugify(path.trim() + header)
 | 
			
		||||
            return {
 | 
			
		||||
              type: 'link',
 | 
			
		||||
              url,
 | 
			
		||||
              children: [{
 | 
			
		||||
                type: 'text',
 | 
			
		||||
                value: alias
 | 
			
		||||
              }]
 | 
			
		||||
            }
 | 
			
		||||
          })
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (this.opts.highlight) {
 | 
			
		||||
      plugins.push(() => {
 | 
			
		||||
        // Match highlights 
 | 
			
		||||
        const highlightRegex = new RegExp(/==(.+)==/, "g")
 | 
			
		||||
        return (tree: Root, _file) => {
 | 
			
		||||
          findAndReplace(tree, highlightRegex, (_value: string, ...capture: string[]) => {
 | 
			
		||||
            const [inner] = capture
 | 
			
		||||
            return {
 | 
			
		||||
              type: 'html',
 | 
			
		||||
              value: `<span class="text-highlight">${inner}</span>`
 | 
			
		||||
            }
 | 
			
		||||
          })
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return plugins
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  htmlPlugins(): PluggableList {
 | 
			
		||||
    return [rehypeRaw]
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue