* fix(flex): respect DesktopOnly and MobileOnly components
* Use classNames util function
* fix(ofm): allow wikilink alias to be empty (#1984)
This is in line with Obsidian's behavior.
* fix(style): Katex adding scrollbars on non-overflowing content (#1989)
* feat(i18n): Bahasa Indonesia translations (#1981)
* fix(a11y): increased content-meta text contrast (#1980)
* fix(analytics): streamline posthog script loading and event capturing (#1974)
* css: adjust color blend for search bg
* feat(links): added ofm option to style unresolved or broken links differently (#1992)
* feat: add option to disable broken wikilinks
* fix(style): update hover color for broken links and introduce new class
* feat: add "disableBrokenWikilinks" option to ObsidianFlavoredMarkdown
* chore(deps): replace `chalk` and `rimraf` with builtin functions (#1879)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* chore(deps): bump the production-dependencies group across 1 directory with 9 updates (#1996)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Node 22 (#1997)
* docs: showcase housekeeping
* docs: fix explorernode references (closes#1985)
* fix: tz-less date parse in local tz instead of utc (closes#1615)
* docs: added note to not forget to add https:// to the plausible-host (for #1337) (#2000)
* docs: added note to not forget to add https:// to the plausible-host (for #1337)
* Update docs/configuration.md
---------
Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
* Updated documentation
---------
Co-authored-by: Nizav <106657905+Ni-zav@users.noreply.github.com>
Co-authored-by: Aswanth <aswanth366@gmail.com>
Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
Co-authored-by: Keisuke ANDO <g.kei0429@gmail.com>
Co-authored-by: fl0werpowers <47599466+fl0werpowers@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Sebastian Moser <64004956+c2vi@users.noreply.github.com>
* docs: added note to not forget to add https:// to the plausible-host (for #1337)
* Update docs/configuration.md
---------
Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
* feat: add option to disable broken wikilinks
* fix(style): update hover color for broken links and introduce new class
* feat: add "disableBrokenWikilinks" option to ObsidianFlavoredMarkdown
* doc(favicon): add documentation of favicon plugin
* doc(favicon): add missing link to configuration page
* fix(favicon): build on public folder don't created
* fix(popover): automatically position heading links at heading
* Impement linking of blockreferences
* Popover fixes
* id mapping
* Remove excess regexes
* Updated blockref
* Remove linker element
* Restore the docs to their former glory
* Move the hash out of the loop
* Redundant
* Redundant
* Restore docs
* Remove log
* Let it const
* Fix(RecentNotes): Prevent folder pages from always appearing first
Pass prioritizeFolders=false to byDateAndAlphabetical in RecentNotes to sort strictly by date/alphabetical order, fixing issue #1901.
* refactor: split sorting functions for clarity
- Split byDateAndAlphabetical into two separate functions\n- byDateAndAlphabetical: sorts strictly by date and alphabetically\n- byDateAndAlphabeticalFolderFirst: sorts with folders first\n- Updated RecentNotes to use date-only sorting
* Fix(PageList): keep byDateAndAlphabeticalFolderFirst as the default sorting order for PageList
* fix(ogImage): update socialImage path to include base URL if defined
* feat(path): add function to check if a file path is absolute
* fix(ogImage): handle absolute paths for user defined og image paths
* docs(CustomOgImages): update socialImage property to accept full URLs
* fix(ogImage): typo
* fix(ogImage): improve user-defined OG image path handling
* Update docs/plugins/CustomOgImages.md
Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
* Update quartz/plugins/emitters/ogImage.tsx
Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
* refactor(path): remove isAbsoluteFilePath function
* fix(ogImage): update user-defined OG image path handling to support relative URLs
* feat(ogImage): enhance user-defined OG image path handling with absolute URL support
* refactor(ogImage): remove debug log for ogImagePath
* feat(path): add isAbsoluteURL function and corresponding tests
* refactor(path): remove unused URL import for isomorphic compatibility
---------
Co-authored-by: Karim H <karimh96@hotmail.com>
Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
* fix(transformer): find last modified date form commit on submodule
when the content folder has a submodule git, the relative path start in content folder and not root folder of quartz
* fix(transformer): use path.relative for improved path handling in last modified date calculation
* fix(transformer): keep find file from relative path of repo workdir
* fix(transformer): use variable for repository workdir
use default value if repo.workdir is undefined to user fullFp value
* fix(explorer): vertically center the Explorer toggle under mobile view
* Added a separate title font configuration
* Added googleSubFontHref function
* Applied --titleFont to PageTitle
* Made googleFontHref return array of URLs
* Dealing with empty and undefined title
* Minor update
* Dealing with empty and undefined title
* Refined font inclusion logic
* Adopted the googleFontHref + googleFontSubsetHref method
* Adaptively include font subset for PageTitle
* Restored default config
* Minor changes on configuration docs
* Formatted source code
* checkpoint
* make emitters async generators
* fix
* custom font spec
* replace spinner, use disk cache for fonts
* use readline instead
* make og images look nice
* start work on client side explorer
* fix tests
* fmt
* generic test flag
* add prenav hook
* add highlight class
* make flex more consistent, remove transition
* open folders that are prefixes of current path
* make mobile look nice
* more style fixes
* Added to the documentation which values of frontmatter are referenced.
* The source code I was looking at seemed to be out of date and the wrong listings were corrected.
* The list of frontmatter was moved to Frontmatter.md and a link was added.
On the surface it seems that only google and plausible scripts handle
the SPA correctly - but I don't know if maybe others handle
window.history API themselves somehow or something like that.
However, I am trying out goatcounter and in it's docs I see that it
does no special SPA handling, so this has to be fixed.
Just doing the dynamic script thing on every nav seems to do the trick.
The script is not "spa-preserve" so they wouldn't accumulate - and when
I tried the "spa-preserve" + call goatcounter api route it didn't quite
work, they actually did accumulate
With markdownLinkResolution: "shortest", aka "+/- how Obsidian does it"
and given pages A and nested/B which has an alias Z, if you try to link
from A using [[Z]] it wouldn't work and get 404.
This is caused by alias slugs (nested/Z in this case, emitted by
AliasRedirects) not being present in the `allSlugs` list which is used
by the link transformer.
The fix is to compute the alias slugs in the frontmatter transformer
and add them to `allSlugs` there.
Also we store them in file data to avoid recomputing them when emitting
alias redirect pages.
Fixes#904
Note: given how currently the markdown/html transformers are ordered
this doesn't really work.
Given pages A and nested/B which has an alias Z, here's the order which
currently happens:
md-transformers(A) => html-transformers(A) =>
md-transformers(B) => html-transformers(B)
Since the nested/Z slug will get added when md-transformers(B) are run,
but the slugs are used by html-transformers(A) when resolving it's
links - the link [[Z]] in A will still 404
A fix for this is to split the parser into two stages - first apply the
md-transformers to all files, and only then apply html-transformers to
all files.
I did just that in a different commit, which is needed for this one to
work correctly.
A final breadcrumb has an empty href, linking to the current page, but
the relative url normalization method missed those, making the link
appear broken in search previews and popovers.
Fixes#1690
If there is no `npm.exe` on the system, but
instead an `npm.cmd`, then node won't find
the `npm` executable when calling `spawnSync`.
This occurs frequently when using node package
managers on Windows.
See the node documentation for `.bat` and `.cmd`
files here.
<https://nodejs.org/api/child_process.html#spawning-bat-and-cmd-files-on-windows>.
* [OFM] Allow for dashes in custom callout label
For compatibility with Obsidian's behavior, a custom callout like
[!see-also] is possible. Previously, this was parsed by Quartz as a
callout “see” with metadata “-also”. Instead, this is should be a
callout “see-also” with title “See also” (capitalization + replace
dashes by spaces).
* prettier
* feat: add a config option for a pageTitleSuffix
* Run Prettier on Head.tsx
* Make pageTitleSuffix optional
Co-authored-by: Aaron Pham <Aaronpham0103@gmail.com>
---------
Co-authored-by: Aaron Pham <Aaronpham0103@gmail.com>
* Responsive design grid
* Addressed PR feedback
* Bump Quartz version 4.3.1 => 4.4.0
* Moved page-header into center
* Updated docs with new layouts
* Sync updated version number with package-lock
* Table of Content scrollbar auto
* Reset node_modules
* Updated layout images
* Fixed tablet layout
* Finilazed layout images
* FIX: Reload graph after a theme change
* FIX: Reload graph after a theme change - comment updated
* FIX: Reload graph after a theme change - comment updated
* FIX: Reload graph after a theme change
* fix: Reload graph after a theme change
* Use a `<button>` for theme toggle
* docs: Adds back Xinyang's cs garden to showcase (#1323)
adding back my garden which was deleted from the cleanup showcase
* feat(toc,explorer): add accessibility for toggle (#1327)
* Restore focus highlight on explorer toggle button.
Remove `unset: all` declaration causing `outline`
property to be unset. This allows the default
browser focus highlight to be shown.
* Fix semantics of expandable sections (explorer, toc).
This adds the appropriate aria attributes for the [disclosure pattern](https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/examples/disclosure-image-description/#javascriptandcsssourcecode) and uses `visibility: hidden` to remove the hidden elements from the focus order without disrupting the animations. Further work is needed on the tree view nodes.
* Run prettier for SCSS files.
* feat: custom global latex macros (closes#1325)
* chore: ts fixes
* docs: recommend at least node 20 in gh
* fix: unmemoize explorer on rebuild (closes#1077)
* fix: pass buildId to worker
* Fix theme button DOM hierarchy and styles
* Restore functionality of theme button
* `aria-label` on theme svgs so their accessible labels are included in button content
---------
Co-authored-by: Xinyang Yu <47915643+xy-241@users.noreply.github.com>
Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
* Add a wrapper span to dates in PageList.
This means there is a placeholder when date is not specified, so the values in grid-template-columns always line up correctly.
* Use a <div> instead -- better practice to stick to block elements.
* Use a `<button>` for search
* Fix search button styles to match preexisting styling
* Remove additional native button properties.
* Invoke search button on click or keyboard.
* Reorganize search button DOM hierarchy
* Restore focus to the search button when exiting the search overlay
* Run prettier on Search.tsx
* Restore focus highlight on explorer toggle button.
Remove `unset: all` declaration causing `outline`
property to be unset. This allows the default
browser focus highlight to be shown.
* Fix semantics of expandable sections (explorer, toc).
This adds the appropriate aria attributes for the [disclosure pattern](https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/examples/disclosure-image-description/#javascriptandcsssourcecode) and uses `visibility: hidden` to remove the hidden elements from the focus order without disrupting the animations. Further work is needed on the tree view nodes.
* Run prettier for SCSS files.
- [Major] Changed `hash` passed to `querySelector` to `decodeURIComponent(hash)` to fix the issue where non-English anchors were not correctly positioning the popover content to the corresponding title.
- [Minor] Updated the type hint from `HTMLLinkElement` to `HTMLAnchorElement` as the passed element is an `<a>` element, not a `<link>` element (reference: https://developer.mozilla.org/en-US/docs/Web/API/HTMLLinkElement).
* replace .gitlab-ci.yml example with more reliable and faster ci job
* literally removing 1 space, inside a code block, in docs, just to make prettier not cry
simplifies slug from FullSlug to SimpleSlug before storing it in the visited pages list in memory
this leads to "index" page and "folder/index", "tags/tag/index" being stored a "/", "folder/" and "tags/tag/" respectively in the list of visited pages.
this ensures that the homepage is rightfully coloured as a visited page in the "color" function of the graph
* Tags appear as hollow circles on the graph
Added a few lines to make tags appear as hollow circles on the graph, as opposed to pages which are plain circles, for better visual separation.
* Applied Prettier code style
* fix: change callout metadata regex to include non-letter characters
* fix: make metadata regex non-greedy
This allows for users to have callouts such as
> [!NOTE|left foo-bar 123] a ]+ title with square brackets [s] a
> Contents
* Add homepage link with internationalization
* Construct pathname from baseUrl config value
* More robust URL manipulation
* Add Farsi (#1133)
* Fix bad rebase
2024-05-22 16:44:54 -04:00
286 changed files with 15148 additions and 30619 deletions
newimport_obsidian.Setting(containerEl).setName("Open everything outside of Obsidian").setDesc(
"Enable to open all obsidian supported extensions with system viewer instead. Disable for default behavior (open within Obsidian). Defaults supported extensions are 'png', 'webp', 'jpg', 'jpeg', 'gif', 'bmp', 'svg', 'mp3', 'webm', 'wav', 'm4a', 'ogg','3gp', 'flac', 'mp4', 'ogv', 'mov', 'mkv'."
newimport_obsidian.Setting(containerEl).setName("Open Outside Obsidian: Manual List").setDesc("This shouldn't be necessary, but you can manually enable custom extensions here.").addToggle(
newimport_obsidian.Setting(containerEl).setName("Manual List").setDesc("Enter extension names (without the dot, ie, just docx separated by newlines).").addTextArea((textArea)=>{
{"id":"obsidian-opener","name":"Opener","minAppVersion":"0.15.9","description":"Open links in new/existing tabs by default. Open PDFs in System App by default. Can open other file formats in System Apps if desired.","author":"Aidan Gibson","authorUrl":"https://github.com/aidan-gibson","isDesktopOnly":false,"version":"2.1.2"}
The most basic function of the Te-Form: form connection between **verbs**.
> [!info] Example
> 食べ==て=={寝|ね}る。
> To eat, then sleep.
This also works with **いA**, **なA**, and **nouns**.
> [!info] Example
> あの{自転車|じてんしゃ}は{便利|べんり}==で=={軽|かる}い。
> That bicycle is useful and light.
### Reasons
Used primarily for reasons beyond control of the speaker.
> [!info] Example
> 大雨==で==バスが止まりました。
> The bus stopped with rain. (the reason is the rain)
### Manners
Highlights something being used, whether a tool, a circumstance, a situation, etc.
> [!info] Examples
> 私はご{飯|はん}を{急|いそ}い==で==食べる。
> I eat food in a hurry.
>
> ハサミ==で=={野菜|やさい}を{切|き}ります。
> I cut my vegetables using scissors.
## Sequence and non-sequence
Only for **verbs**.
### て sequence
Used to list a sequence of events that happen one after another. Must be used for ordered sequence of what is being said!
> [!info] Example
> パンを買==って==、食べた。
> I bought some bread, then ate it.
### て non-sequence
The particle can also contrast things that have some sort of relationship. It can mean something like "and" or "while", but is not really similar to "but": it always has the same weight in the sentence, as opposed to expressions like けど・のに, etc.
> [!info] Examples
> 朝は雨が{降|ふ}==って=={夕方|ゆう|がた}は{晴|は}れた。
> It rained this morning, **and** then it cleared up in the afternoon. (there is no particular emphasis on either event).
>
> 朝は雨が降った==けど==夕方は晴れた。
> It rained this morning, **but then** it cleared up in the afternoon. (there is emphasis on the fact that it stopped raining).
### てから
Used to say that something will happen after something else : "after doing (A), (B)".
Only for **verbs**.
> [!info] Example
> {洗濯|せん|たく}をし==てから==、出かける。
> After doing the laundry, I will go out.
⚠ Simple present (るから) and past (たから) have a meaning closer to "because" or "since".
## States
### ている form
| Plain | Polite |
| ----- | ------ |
| ている | ています |
| てる | てます |
ている is often shortened to てる. This applies to all tenses, including てる, てて, てた, and even てます.
Only for **verbs**.
Sometimes ている can become しとる (like in manga).
#### 1/ State of existence: is being done
Used to convey a constant state of the verb being done, executed, etc. It is continuing to exist in a specific state.
> [!info] Example
>今ラーメンを食べ==ています==。
>I am eating ramen now.
#### 2/ State of existence: has been done
Expresses "existing in a of state of having been done".
In English, a different tense would have been used, but in Japanese it is also Te-form.
> [!info] Examples
> お前はもう死==んでいる==。
> You are already dead.
>
> クラスは始ま==っている==。
> The class has already started. (existing in the state of having started)
>
> お母さんは今買い物に行==っています==。
> My mom went out to go shopping. (existing in the state of having gone)
>
> 先生がめちゃ{怒|おこ}==っている==。
> My teacher is very angry. (existing in the state of having gotten angry)
Then, how to differentiate from the past form? Think about if the action can happen twice. For example, something cannot start twice, so it will use ている. The same applies for dying. This will not work for all verbs, but for the majority.
> [!info] Example
> ピアノが{落|お}ち==ている==。
> The piano has fallen. (existing in the state of having fallen)
> Something has fallen and is already on the ground, so it cannot fall again. ている will be used.
#### 3/ State of existence: frequent and repeated action
Used for the repetition of common activities. They are not continuing per se, but are occurring at such a frequency that they are considered to be continuous.
For example: going to work, having a hobby, doing sports, etc.
You can see it as "continuing to exist in a specific state".
Expression of time are often used with this meaning.
> [!info] Examples
> 私は毎日ギターを{弾|ひ}い==ている==。
> I play my guitar everyday (hobby).
>
> {毎晩|まい|ばん}9時に{寝|ね}==ている==。
> I sleep at 9 every night (habit).
>
> {彼|かれ}は学校で{働|はたら}い==ている==。
> He works at a school (regular activity).
### ていた・ていました
Means that something was happening, someone was doing something. If an object has changed state and is still in the state, it can also be used, for example a broken window.
Only for **verbs**.
ていた can be shortened to てた, and ていました to てました.
> [!info] Example
> {勉強|べんきょう}をし==ていた==けど、今は{休|やす}んでいる。
> I was studying but am taking a break right now.
### てある
Shares with ている the meaning of being in an ongoing state, meaning that something has been done. It is also similar to a simple past form. However, the nuance is that this form is only used with transitive verbs on inanimate objects, meaning either:
* the action has been done intentionally (focuses on a person's intention),
* the focus is the resulting state of the action.
> [!info] Examples
> 明日の{弁当|べん|とう}はもう作==ってある==。
> Tomorrow's lunch has already been prepared.
>
> ドアが{開|あ}け==てある==。
> The door has been left open (intentionally).
Only for **transitive verbs**.
### ておく
Means to do something in advance, to complete something in preparation for something.
If used in past form ておいた, means that the completed action was in preparation for the current situation.
Only for **verbs**.
Can be shortened as とく.
> [!info] Example
> メロンパンを買==っておく==。
> I'll buy a melon pan (in preparation for a something, for example a picnic).
The goal of this website is to be a synthesis of useful resources for my Japanese learning adventure. I want to have grammar points next to each other, independently of any "difficulty level", set up in a logical and consistent form. I don't want to have to open 5 pages to compare information, and I don't want a deep dive into a notion. The goal is to be a reminder of the things I learn, rather than a way to learn. I want a few examples to grasp it, but I do not want to have ten of the same kind. And nothing quite fits for me!
## Sources
Of course, since I'm _learning_ the language, I need to borrow what I write from different sources. So this website uses data from the websites listed here. I don't want any recognition of what is here! It's mostly a compilation of what people who are way better in this language have made before.
Means "if" when a result is known or assumed to be true, aka a logical cause-effect relationship. Cannot be used if the result is uncertain. So it cannot be an intention, a request, a desire, an order, etc.
> [!info] Example
> {急|いそ}いでない==と==、{遅刻|ちこく}に{着|つ}きます。
> If you don't hurry, you'll arrive late.
## なら
<divclass="usage">
<divclass="left">
<p><spanclass="box">V (casual) + (の)</span></p>
<p><spanclass="box">い-Adj + (の)</span></p>
<p><spanclass="box">な-Adj + (の)</span></p>
<p><spanclass="box">N</span></p>
</div>
<pclass="right">+ なら</p>
</div>
Means "in the case that/of". The second part of the sentence is generally an opinion, a request or a suggestion.
Means "if" or "when". Describes a condition (the first action must be completed before the second action). Usually used for hypothetical situations. It is the main word used for conditional.
> [!info] Example
> 安==かったら==、買う。
> (If / When) it's cheap, I'll buy it.
## 場合
<divclass="usage">
<divclass="left">
<p><spanclass="box">V (casual)</span></p>
<p><spanclass="box">い-Adj</span></p>
<p><spanclass="box">な-Adj + な</span></p>
<p><spanclass="box">N + の</span></p>
</div>
<pclass="right">+ 場合は</p>
</div>
{場合|ば|あい} means "in the case of". The second part explains what to do in the situation (instructions, advices, etc). More formal than たら.
> [!info] Example
> {地震|じ|しん}==の場合は==、エレベーターを使わないでください。
> In case of an earthquake, please don't use the elevators.
Means that something doesn't change state, stays as it is.
> [!info] Examples
> {開|あ}けた==まま==。
> To be left open.
>
> {熱|あつ}い==まま==。
> Still hot.
>
> {昔|むかし}の==まま==。
> As it always been.
>
> その==まま==でいい。
> It is fine as it is.
## がする
This means to experience a sense (except visual): to smell, to hear, to taste, etc, depending on the noun.
> [!info] Example
> いい{匂|にお}い==がする==。
> It smells good.
>
> 今日は{最悪|さいあく}日{気|き}==がする==。
> I feel like today is the worst.
## から作る・で作る
Means "made from".
> [!info] Example
> チーズは{牛乳|ぎゅうにゅう}==から作る==。
> Cheese is made from milk.
## のが「好き・上手・下手」
のが({好|すき}き・{上手|じょうず}・{下手|へた}) means "to (like/be good/be bad)" at an action.
Used with a verb in dictionary form.
> [!info] Example
> テレビでサッカーを見る==のが好き==です。
> I like watching soccer on the television.
>
> 彼女は料理を作る==のが上手==と思います。
> I think she is a good cook.
>
> {絵|え}を{塗|ぬる}る==のが下手==です。
> I'm not good at painting.
## くらい・ぐらい
<divclass="usage">
<divclass="left">
<p><spanclass="box">V (ない)</span></p>
<p><spanclass="box">い-Adj</span></p>
<p><spanclass="box">な-Adj + な</span></p>
<p><spanclass="box">N + の</span></p>
</div>
<pclass="right">+ くらい・ぐらい</p>
</div>
Means "about" or "approximately" when talking about numbers or counter words. ぐらい is more common in conversations, but can change depending on the preceding word.
> [!info] Example
> {電車|でんしゃ}はどの==くらい==で{到着|とうちゃく}しますか。
> About how much time will the train take to arrive?
>
> {医者|いしゃ}に1時間==ぐらい==を{待|ま}ってました。
> I waited approximately an hour for the doctor.
Also used to compare things as being similar.
> [!info] Example
> {友達|ともだち}と{試験|しけん}の{結果|けっか}は{同|おな}じ==ぐらい==です。
> My friend and I have about the same results at the test.
Also means "to the extent of".
> [!info] Example
> 食べなくて{寝|ね}たい==ぐらい=={疲|つか}れています。
> I'm tired to the extent of not eating and going to sleep.
This conjunction means "and". It implies a cause-effect relationship between the two sentences. There's an interconnection, where the order of the actions cannot be changed.
> [!info] Examples
> バスケットボールをした。==そして==水を{飲|の}んだ。
> I played basketball. Then, I drank water.
### それから
This conjunction means "and" or "after that". It implies a chronological order to the events. Since there's no interconnection, the order of actions could be changed.
> [!info] Examples
> スーパーに行きました。==それから=={弁当|べんとう}を食べました。
> I went to the supermarket. After that, I ate my bento.
### それに
This conjunction means "and", "besides" or "in addition". Implies a new information in relation to the precedent one. It is not used to add a negative information to a positive one, and vice-versa.
> [!info] Examples
> 昨日、{病気|びょうき}になった。==それに==パソコンも{壊|こわ}れた。
> I got sick yesterday. Beside, my computer broke.
### それで
Means "because of that", "therefore". Substitutes the first sentence happening before by それ, highlighting information from it.
> When I was a child, I took the train to school every day. Because of that, I wanted to be a train driver.
## Exhaustive listing
### と
This particles means "and" or "with". Used for a list that is exhaustive. Connects sentences.
> [!info] Examples
> 犬==と=={住|す}んでいます。
> I live with my dog.
>
> フランス語==と==スペイン語を習っています。
> I am learning French and Spanish.
### て connecting
Used for a list that is exhaustive. Connects verbs.
See [[TeF (1) - basics#て sequence]].
## Unexhaustive listing
### や
Used for a list that is unexhaustive. Translates to "among other things". Formal.
Used only with nouns. Cannot be repeated!
> [!info] Example
> フランス==や==スペインに{旅行|りょこう}しました。
> I travelled to France and Spain (among others).
### など
Means "things as". Can be used with や for a meaning like "etc".
Used with nouns. Cannot be repeated!
> [!info] Example
> お金がないのでカフェ**や**レストラン==など=={払|はら}えない。
> I can't pay things like cafes or restaurant (etc.) because I have no money.
### とか~とか
Used for a list that is unexhaustive. Translates to "among other things". More casual than や or たり~たり. Ending a sentence with とか can soften the meaning. Can also be used to quote someone.
Only used with verbs and nouns. Can be repeated.
> [!info] Examples
> {果物|くだもの}はバナナ==とか==リンゴ==とか==が好きです。
> I like fruits like bananas and apples.
>
> 明日{野球|やきゅう}==とか==しようか。
> Do you want to play baseball (or something) tomorrow?
>
> もう{諦|あきら}めよう==とか==言わないで。
> Don't say (things like) we should already give up.
が{必要|ひつよう} is used mainly with nouns (can be used with verbs by appending こと before).
{必要|ひつよう}がある is used with verbs.
> [!info] Example
> {今時|いまどき}、{携帯電話|けいたいでんわ}==が必要です==。
> Nowadays, a cell phone is necessary.
>
> 今日はパン{屋|や}に行く==必要がない==。
> No need to go to the bakery today.
## Must
### なくちゃ・なきゃ
Only used on casual spoken conversations.
This form is used with the negative form of a verb (ない), and adding なくちゃ and optionally one of the following ending: だめ, いけない, いけません, ならない, なりません.
なくちゃ is the shortened form of なくては.
なきゃ is the shortened form of なければ.
> [!info] Example
> {歯|は}を{磨|みが}か==なくちゃいけない==。
> I must brush my teeth.
### なくては「いけない・ならない」
Also formed with the negative form of a verb.
> [!info] Example
> 今{遅|おそ}いね。{寝|ね}に行か==なくてはいけない==。
> It's late now. I have to go to sleep.
### なければ「いけない・ならない」
Also formed with the negative form of a verb.
> [!info] Example
> {事務所|じむしょ}では{静|しず}かにし==なければならない==。
> You have to be quiet in the office.
### ないといけない
Also formed with the negative form of a verb.
In casual contexts, can be shortened as ないと.
> [!info] Example
> 今日は{勉強|べんきょう}し==ないといけない==。
> I have to study today.
### Comparing いけない and ならない
* ==いけない== is the standardly used form. It implies a subjective view, that it would be better to do something, to avoid negative consequences (eg: brushing one's teeth, eating well, etc).
* ==ならない== is usually more formal or in written form. It implies a is more objective view, something that has to be done because there's no other way (eg: respecting the law, paying taxes, etc).
### Comparing なくては, なければ and ないと
なくては and なければ are generally interchangeable in speech. However:
* ==なくては== is generally used when there is _no penalty_ for not complying.
* ==なければ== is generally used when there _is a penalty_ for not complying.
* ==ないと== is lighter and does not imply that there can or cannot be penalty. Its construction is based on the [[Conditional#と]] particle, and should be based on knowledge or experience.
## Must not
#### 「ちゃ・じゃ」「だめ・いけない・いけません」
Only used on casual spoken conversations. いけません is a bit more formal.
This form is used with a V-て, depending on the ending:
* with て, ちゃ is used.
* with で, じゃ is used.
> [!info] Examples
> その{花|はな}を食べ==ちゃだめ==。
> Don't eat those flowers.
>
> {花瓶|か|びん}の水を{飲|の}ん==じゃいけない==。
> Don't drink the water of the flower vase.
### てはいけない
Used in a more formal or written manner. Used with a V-て.
> [!info] Example
> {鉄道|てつ|どう}に{歩|ある}い==てはいけません==。
> Do not walk on the railroad.
### なくてもいい
Means "don't have to". Used with a verb in the negative form (ない), appending なくてもいい.
Can also be used as なくていい.
> [!info] Example
> 今日はレストランで{手伝|て|つ}わ==なくてもいい==。
> You don't have to help out at the restaurant today (it's okay if you don't help at the restaurant today).
This has the meaning of like, easy to, _-ish_. Makes a direct comparison with certainty, from the point of view of the person saying it. Close to an even more casual meaning of みたい.
> [!info] Examples
> {子供|こ|ども}==っぽい==。
> Childish.
>
> {忘|わす}れ==っぽい==。
> Easy to forget.
### らしい
Expresses an information based on hearsay, or based on the situation, or ressemblance. This is always used bases on a source that is unknown or ambiguous. It can be similar to a guess.
Also means that it looks like, but connecting to nouns and verbs.
> [!info] Example
> 面白==そうに==人です。
> He seems like an interesting person.
### Summing it up
🛠 To do: check validity.
* ==ようだ== is a formal way to say that it looks like, usually from direct observation.
* ==みたい== is a less formal way, used in a casual conversation.
* ==っぽい== is even more casual. A girl trying to be masculine would be 男っぽい.
* ==らしい== is usually used when something is typical or expected. The same girl wouldn't be either 女らしい or 男っぽい because it's not what is expected from her.
* ==そうだ== is used for something that is hearsay or not directly observation, more as a guess.
Used after a reason, to explain the consequence. Means "because of", "since".
It is more objective than から: it expresses a situation that exists, and that is outside of one's control. For this reason, it can also be perceived as more polite.
> [!info] Example
> 雨な==ので==傘を持ってきてください。
> Since it is raining, please bring an umbrella.
## から
See [[🔰 Particles (2)#Because]].
It is more subjective than ので: it expresses more personal needs/actions/opinions.
## んです・のです
<divclass="usage">
<divclass="left">
<p><spanclass="box">V</span></p>
<p><spanclass="box">い-Adj</span></p>
<p><spanclass="box">な-Adj + な</span></p>
<p><spanclass="box">N + だ</span></p>
</div>
<pclass="right">+ んだ・んです・のだ・のです</p>
</div>
It is used to explain or put emphasis on something.
Means "please don't". It is a polite request. Removing the ください makes it more casual.
Formed by a verb in the negative form (ない) with the で particle.
> [!info] Example
> {冷蔵庫|れいぞうこ}のデザートは食べ==ないでください==。
> Please do not eat the dessert from the fridge.
## なさい
This form is used when commanding an action.
It is used with verbs by removing the ます and adding なさい. In casual conversation, it can be shortened to な.
> [!info] Example
> {質問|しつ|もん}を{答|こた}え==なさい==。
> Answer the question.
## ように言う
It means "to tell", "to request", "to order".
It is form by added ように{言|い}う to a verb. The verb {頼|たの}む can be used for requests, while {命|めい}じる can be used for order. The verb {言|い}う can tell the three meanings depending on the tone.
A first meaning is similar to {間|あいだ} (while), but with intentionality.
> [!info] Example
> 電車に{乗|の}った==間に==、本を読みました。
> While I was on the train, I read a book.
A second meaning is a statement of something that happened during a time period, independently of your actions.
Contrary to 間, it doesn't include the whole time period. So 間に means that at a point during the time period, something happened.
> [!info] Example
> {夜|よる}の==間に==、{隣|となり}の木が{落|お}ちていた。
> During the night, the tree next door fell.
# から~まで
See から: [[🔰 Particles (2)#From, since]].
See まで: [[🔰 Particles (2)#まで]].
See から~まで: [[🔰 Particles (2)#から~まで]].
## 前に
<divclass="usage">
<divclass="left">
<p><spanclass="box">V (dictionary)</span></p>
<p><spanclass="box">N + の</span></p>
</div>
<pclass="right">+ 前に</p>
</div>
{前|まえ}に means before (time) or in front of (place).
> [!info] Examples
> {寝|ねる}る==前に==、レストランに行こうと思います。
> I think I'll go to the restaurant before sleeping.
>
> レストランの==前に=={自転車|じ|てん|しゃ}があります。
> There are bikes in front of the restaurant.
## 後で
<divclass="usage">
<divclass="left">
<p><spanclass="box">V (た)</span></p>
<p><spanclass="box">N + の</span></p>
</div>
<pclass="right">+ 後で</p>
</div>
{後|あと}で means after or later.
⚠ Only works with the past form of verbs!
> [!info] Example
> 食べた==後で==、寝ます。
> After eating, I'll go to sleep.
## さっき
Means that something happened recently, either just now, or a little while ago.
> [!info] Example
> ==さっき==家に出てきた。
> I just left home.
## たところ
Combined with a verb in the past tense, it express that something just occurred (something just ended, just started, etc).
> [!info] Example
> 今食べた==ところ==だ。
> I just finished to eat right now.
## ているところ
See [[TeF (2) - manner of doing#ているところ]].
## たばかり
Combined with a verb in the past tense, it express that something just occurred (something just ended, just started, etc). It is more subjective than ところ. It doesn't have to be something that literally just happened, but something that feels like it just happened.
> [!info] Example
> 今食べた==ばかり==だ。
> I just finished to eat right now.
When comparing the two examples, the meaning is different depending on the context. Imagine a friend asking you to go eat with him. When using ところ, it means you just finished your meal this instant. When using ばかり, it means that it feels too soon to eat again just yet from your point of view, independently of how much time has really passed.
## 急に
{急|きゅう}に means that something happened unexpectedly or quickly.
> [!info] Example
> ==急に==電車が{現|あらわ}れた。
> A train suddenly appeared.
## やっと
Means that something happened at last. More rarely means "barely".
> [!info] Example
> ==やっと=={論文|ろん|ぶん}を書き{終|お}わった。
> I finally finished writing my thesis.
## までに
This indicates a time limit for the action, similar to "by".
> [!info] Example
> {来週|らい|しゅう}==までに=={終|お}わってください。
> Please finish by next week.
## おきに
This is used for repeated intervals, after a noun indicating something measurable.
> [!info] Example
> この電車は4分==おきに=={出発|しゅ|っぱつ}します。
> This train leaves every four minutes.
## ころ・ごろ
<divclass="usage">
<divclass="left">
<p><spanclass="box">N (time)</span></p>
</div>
<pclass="right">+ ごろ</p>
</div>
Means "around" or "about".
> [!info] Example
> 午後8時==ごろ==来てください。
> Please come around 8PM.
<divclass="usage">
<divclass="left">
<p><spanclass="box">V (casual)</span></p>
<p><spanclass="box">い/な-Adj</span></p>
<p><spanclass="box">N + の</span></p>
</div>
<pclass="right">+ ころ</p>
</div>
Means "when".
> [!info] Example
> 子供の==ころ==、毎日{公園|こうえん}で{遊|あそ}んだ。
> When I was a kid, I played every day at the park.
The は particle indicates the topic of a sentence. Usually translated by "as for".
> [!info] Example
> 私==は==フランス人です。
> I am French (As for me, I am French).
When a sentence is negative, は is usually used instead of が and を.
> [!info] Example
> 肉==は==食べません。
> I don't eat meat.
## が
The が particle indicates the subject of a sentence.
> [!info] Example
> 電車==が==好きです。
> I like trains.
It is also used for making a contrast.
> [!info] Example
> 電車は好きです==が==、バスは好きじゃない。
> I like trains, but I don't like buses.
In a noun modifying clause, は becomes が.
> [!info] Example
> {彼|かれ}はラメんを{作|つく}。
> He made ramen.
>
> {彼|かれ}==が=={作|つく}ったラメんはおいしいです。
> The ramen he made is delicious.
## Difference between は and が
Usually, they can be used in the same sentence, but have a nuanced meaning based on the context.
> [!info] Examples
> 私==は==フランス人です。
> 私==が==フランス人です。
> I am French.
Both sentences mean the same thing. But:
* In the first sentence with は, what is highlighted is that the speaker is French.
* In the second sentence with が, what is highlighted is that the French person is the speaker.
The first sentence would most likely be the answer to "where are you from?", while the second sentence would be the answer to "who is French?". が highlights the information where the focus is wanted.
## を
This particle is used for the target of the action of a verb.
> [!info] Examples
> ケーキ==を==作る。
> I prepare a cake.
## に
This particle has multiple meanings.
* A place of existence.
> [!info] Example
> {会社|かいしゃ}は東京==に==あります。
> The company is in Tokyo.
* A point in time.
> [!info] Example
> 毎日12時==に=={寝|ね}ます。
> I sleep at 12:00 everyday.
* A direction towards whom an action is directed. For example: meeting a person, phoning to someone, riding a transport, writing on something, sitting on something, etc.
> [!info] Example
> 日本==に=={住|す}んでいます。
> I live in Japan.
## に・へ
に and へ are used to indicate a direction of movement with verbs like 行く, くる, and 帰る.
> [!info] Example
> 日本==へ==行きます。
> 日本==に==行きます。
> I'm going to Japan.
## で
This particle can indicate several things.
* A place where the action is done.
> [!info] Example
> {図書館|としょかん}==で==本を{読|よ}みました。
> I read a book in the library.
* The use of something
> [!info] Example
> えんぴつ==で==書いてください。
> Please write with a pencil.
* The use of ingredients or materials
> [!info] Example
> タコ==で==たこ{焼|や}きを作る。
> I prepare takoyaki with octopus.
* Numbers or volume for multiple objects.
> [!info] Example
> 本を5{冊|さつ}==で==買った。
> I bought 5 books.
* A noun that is the cause of something.
> [!info] Example
> かぜ==で==休みました。
> I took the day off because of a cold.
* A mode of transportation.
> [!info] Example
> {休暇|きゅうか}に電車==で==行った。
> I went on holiday by train.
## の
This particle indicates possession.
> [!info] Example
> 私==の==ボール。
> My ball.
## も
This particle means "also".
> [!info] Example
> 日本{料理|りょうり}==も=={韓国|かん|こく}{料理|りょうり}==も==食べます。
> I eat Japanese and Korean food.
The particles は, が and を change to も.
> [!info] Example
> 私は{中国|ちゅう|ごく}語==も==話せます。
> I can also speak Chinese.
In other cases, it can be combined with other particles: に, で, へ, と, から.
> [!info] Example
> {大阪|おお|さか}に==も==行きたい。
> I also want to go to Osaka.
Another meaning of this particle can be found when combined with words like {何|なに}, {誰|だれ}, or どこ (what, who, where). It means nothing, nobody and nowhere. It indicates the absence.
> [!info] Example
> A: {昨日|きのう}どこかへ行った?
> B: いいえ、どこへ==も==行かなかった。
> A: Did you go somewhere yesterday?
> B: No, I didn't go anywhere.
Used with a number or a time, it means "as many as" or "nearly".
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
There are a few extensions that add [furigana](https://en.wikipedia.org/wiki/Furigana) support to Markdown. I use [Obsidian](https://obsidian.md/), and therefore its furigana extension: [obsidian-markdown-furigana](https://github.com/steven-kraft/obsidian-markdown-furigana). It works well, but by nature is limited by being used within Obsidian.
For that purpose, this python script converts this specific syntax to common, all-platforms HTML ruby tags.
## Process
This specific extension syntax is as following:
```
{漢字|かんじ}
{漢字|かん|じ}
```
When processed by this script, the result is:
```
<ruby>漢字<rt>かんじ</rt></ruby>
<ruby>漢<rt>かん</rt>字<rt>じ</rt></ruby>
```
Which leads visually from, by default markdown standards:
> {漢字|かんじ}
>
> {漢字|かん|じ}
to common HTML ruby syntax:
> <ruby>漢字<rt>かんじ</rt></ruby>
>
> <ruby>漢<rt>かん</rt>字<rt>じ</rt></ruby>
## Limitations
This has been made for my personal use, which is only kanjis with kanas as furigana. The regexp used do not recognize other inputs. But you can modify them easily for your use if needed.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
For my Japanese Grammar (JPG) project, I have created a style for explanation on the usage of certain grammar points. There is no simple way to make it in Markdown, so I tried to make it with the least amount of HTML possible. You can find it in `examples/sample.md`. However, for it to work, you have to import a custom [CSS snippet](https://help.obsidian.md/Extending+Obsidian/CSS+snippets) to Obsidian, which is located in `obsidian-snippet/usage.css`. But using it, you will have this kind of result:

## convert-usage.py
In my Quartz rendering of my markdown data, I want this kind of data to be in a callout. However, it is not possible to combine HTML and Markdown in Obsidian. For that purpose, this script encapsulates it directly in HTML. To make it both compatible in Obsidian and Quartz, and to be still easy to write, it's done with this python script. This is probably super specific and will not be of use for anybody except me!
## Usage
Usage: `python3 convert-usage.py [root folder]`
Note: Please be careful, this software applies modifications recursively!
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris massa eros, feugiat eu dapibus nec, fermentum vel ex. Nulla malesuada luctus pretium. Phasellus ac felis ut nisi lacinia malesuada nec vel odio. Donec tincidunt tincidunt lorem vel tempus. Nullam sed efficitur ligula, a porttitor nibh. Praesent justo dui, venenatis ac mi non, laoreet consequat libero. Aenean ut molestie mauris. Proin mattis volutpat ligula eget tincidunt. Fusce ex eros, condimentum consectetur efficitur vitae, euismod at justo.
**Usage**
<divclass="usage">
<divclass="left">
<p><spanclass="box">item1</span></p>
<p><spanclass="box">item2</span></p>
<p><spanclass="box">item3</span></p>
<p><spanclass="box">item4</span></p>
</div>
<pclass="right">+ final</p>
</div>
## Phasellus tristique
Phasellus tristique rutrum enim. Integer vitae ex at turpis convallis posuere nec nec erat. Cras finibus erat mauris. Suspendisse id diam at sapien luctus faucibus. Pellentesque fermentum auctor libero, ut porta orci porttitor quis. In varius at sem sed ultricies. Mauris iaculis convallis erat, congue tincidunt turpis luctus vitae.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris massa eros, feugiat eu dapibus nec, fermentum vel ex. Nulla malesuada luctus pretium. Phasellus ac felis ut nisi lacinia malesuada nec vel odio. Donec tincidunt tincidunt lorem vel tempus. Nullam sed efficitur ligula, a porttitor nibh. Praesent justo dui, venenatis ac mi non, laoreet consequat libero. Aenean ut molestie mauris. Proin mattis volutpat ligula eget tincidunt. Fusce ex eros, condimentum consectetur efficitur vitae, euismod at justo.
@ -25,10 +25,11 @@ The following sections will go into detail for what methods can be implemented f
-`BuildCtx` is defined in `quartz/ctx.ts`. It consists of
-`BuildCtx` is defined in `quartz/ctx.ts`. It consists of
-`argv`: The command line arguments passed to the Quartz [[build]] command
-`argv`: The command line arguments passed to the Quartz [[build]] command
-`cfg`: The full Quartz [[configuration]]
-`cfg`: The full Quartz [[configuration]]
-`allSlugs`: a list of all the valid content slugs (see [[paths]] for more information on what a `ServerSlug` is)
-`allSlugs`: a list of all the valid content slugs (see [[paths]] for more information on what a slug is)
-`StaticResources` is defined in `quartz/resources.tsx`. It consists of
-`StaticResources` is defined in `quartz/resources.tsx`. It consists of
-`css`: a list of URLs for stylesheets that should be loaded
-`css`: a list of CSS style definitions that should be loaded. A CSS style is described with the `CSSResource` type which is also defined in `quartz/resources.tsx`. It accepts either a source URL or the inline content of the stylesheet.
-`js`: a list of scripts that should be loaded. A script is described with the `JSResource` type which is also defined in `quartz/resources.tsx`. It allows you to define a load time (either before or after the DOM has been loaded), whether it should be a module, and either the source URL or the inline content of the script.
-`js`: a list of scripts that should be loaded. A script is described with the `JSResource` type which is also defined in `quartz/resources.tsx`. It allows you to define a load time (either before or after the DOM has been loaded), whether it should be a module, and either the source URL or the inline content of the script.
-`additionalHead`: a list of JSX elements or functions that return JSX elements to be added to the `<head>` tag of the page. Functions receive the page's data as an argument and can conditionally render elements.
## Transformers
## Transformers
@ -37,7 +38,7 @@ Transformers **map** over content, taking a Markdown file and outputting modifie
An emitter plugin must define a `name` field, an `emit` function, and a `getQuartzComponents` function. `emit` is responsible for looking at all the parsed and filtered content and then appropriately creating files and returning a list of paths to files the plugin created.
An emitter plugin must define a `name` field, an `emit` function, and a `getQuartzComponents` function. It can optionally implement a `partialEmit` function for incremental builds.
- `emit` is responsible for looking at all the parsed and filtered content and then appropriately creating files and returning a list of paths to files the plugin created.
- `partialEmit` is an optional function that enables incremental builds. It receives information about which files have changed (`changeEvents`) and can selectively rebuild only the necessary files. This is useful for optimizing build times in development mode. If `partialEmit` is undefined, it will default to the `emit` function.
- `getQuartzComponents` declares which Quartz components the emitter uses to construct its pages.
Creating new files can be done via regular Node [fs module](https://nodejs.org/api/fs.html) (i.e. `fs.cp` or `fs.writeFile`) or via the `write` function in `quartz/plugins/emitters/helpers.ts` if you are creating files that contain text. `write` has the following signature:
Creating new files can be done via regular Node [fs module](https://nodejs.org/api/fs.html) (i.e. `fs.cp` or `fs.writeFile`) or via the `write` function in `quartz/plugins/emitters/helpers.ts` if you are creating files that contain text. `write` has the following signature:
@ -234,7 +249,7 @@ export type WriteOptions = (data: {
// the build context
// the build context
ctx: BuildCtx
ctx: BuildCtx
// the name of the file to emit (not including the file extension)
// the name of the file to emit (not including the file extension)
@ -48,4 +48,4 @@ Here are the main types of slugs with a rough description of each type of path:
-`SimpleSlug`: cannot be relative and shouldn't have `/index` as an ending or a file extension. It _can_ however have a trailing slash to indicate a folder path.
-`SimpleSlug`: cannot be relative and shouldn't have `/index` as an ending or a file extension. It _can_ however have a trailing slash to indicate a folder path.
-`RelativeURL`: must start with `.` or `..` to indicate it's a relative URL. Shouldn't have `/index` as an ending or a file extension but can contain a trailing slash.
-`RelativeURL`: must start with `.` or `..` to indicate it's a relative URL. Shouldn't have `/index` as an ending or a file extension but can contain a trailing slash.
To get a clearer picture of how these relate to each other, take a look at the path tests in `quartz/path.test.ts`.
To get a clearer picture of how these relate to each other, take a look at the path tests in `quartz/util/path.test.ts`.
This part of the configuration concerns anything that can affect the whole site. The following is a list breaking down all the things you can configure:
This part of the configuration concerns anything that can affect the whole site. The following is a list breaking down all the things you can configure:
- `pageTitle`: title of the site. This is also used when generating the [[RSS Feed]] for your site.
- `pageTitle`: title of the site. This is also used when generating the [[RSS Feed]] for your site.
- `pageTitleSuffix`: a string added to the end of the page title. This only applies to the browser tab title, not the title shown at the top of the page.
- `enableSPA`: whether to enable [[SPA Routing]] on your site.
- `enableSPA`: whether to enable [[SPA Routing]] on your site.
- `enablePopovers`: whether to enable [[popover previews]] on your site.
- `enablePopovers`: whether to enable [[popover previews]] on your site.
- `analytics`: what to use for analytics on your site. Values can be
- `analytics`: what to use for analytics on your site. Values can be
- `null`: don't use analytics;
- `null`: don't use analytics;
- `{ provider: 'google', tagId: '<your-google-tag>' }`: use Google Analytics;
- `{ provider: 'google', tagId: '<your-google-tag>' }`: use Google Analytics;
- `{ provider: 'plausible' }` (managed) or `{ provider: 'plausible', host: '<your-plausible-host>' }` (self-hosted): use [Plausible](https://plausible.io/);
- `{ provider: 'plausible' }` (managed) or `{ provider: 'plausible', host: 'https://<your-plausible-host>' }` (self-hosted, make sure to include the `https://` protocol prefix): use [Plausible](https://plausible.io/);
- `{ provider: 'tinylytics', siteId: '<your-site-id>' }`: use [Tinylytics](https://tinylytics.app/);
- `{ provider: 'tinylytics', siteId: '<your-site-id>' }`: use [Tinylytics](https://tinylytics.app/);
- `{ provider: 'cabin' }` or `{ provider: 'cabin', host: 'https://cabin.example.com' }` (custom domain): use [Cabin](https://withcabin.com);
- `{provider: 'clarity', projectId: '<your-clarity-id-code'}`: use [Microsoft clarity](https://clarity.microsoft.com/). The project id can be found on top of the overview page.
- `locale`: used for [[i18n]] and date formatting
- `locale`: used for [[i18n]] and date formatting
- `baseUrl`: this is used for sitemaps and RSS feeds that require an absolute URL to know where the canonical 'home' of your site lives. This is normally the deployed URL of your site (e.g. `quartz.jzhao.xyz` for this site). Do not include the protocol (i.e. `https://`) or any leading or trailing slashes.
- `baseUrl`: this is used for sitemaps and RSS feeds that require an absolute URL to know where the canonical 'home' of your site lives. This is normally the deployed URL of your site (e.g. `quartz.jzhao.xyz` for this site). Do not include the protocol (i.e. `https://`) or any leading or trailing slashes.
- This should also include the subpath if you are [[hosting]] on GitHub pages without a custom domain. For example, if my repository is `jackyzha0/quartz`, GitHub pages would deploy to `https://jackyzha0.github.io/quartz` and the `baseUrl` would be `jackyzha0.github.io/quartz`.
- This should also include the subpath if you are [[hosting]] on GitHub pages without a custom domain. For example, if my repository is `jackyzha0/quartz`, GitHub pages would deploy to `https://jackyzha0.github.io/quartz` and the `baseUrl` would be `jackyzha0.github.io/quartz`.
@ -38,11 +41,12 @@ This part of the configuration concerns anything that can affect the whole site.
- `ignorePatterns`: a list of [glob](<https://en.wikipedia.org/wiki/Glob_(programming)>) patterns that Quartz should ignore and not search through when looking for files inside the `content` folder. See [[private pages]] for more details.
- `ignorePatterns`: a list of [glob](<https://en.wikipedia.org/wiki/Glob_(programming)>) patterns that Quartz should ignore and not search through when looking for files inside the `content` folder. See [[private pages]] for more details.
- `defaultDateType`: whether to use created, modified, or published as the default date to display on pages and page listings.
- `defaultDateType`: whether to use created, modified, or published as the default date to display on pages and page listings.
- `theme`: configure how the site looks.
- `theme`: configure how the site looks.
- `cdnCaching`: If `true` (default), use Google CDN to cache the fonts. This will generally will be faster. Disable (`false`) this if you want Quartz to download the fonts to be self-contained.
- `cdnCaching`: if `true` (default), use Google CDN to cache the fonts. This will generally be faster. Disable (`false`) this if you want Quartz to download the fonts to be self-contained.
- `typography`: what fonts to use. Any font available on [Google Fonts](https://fonts.google.com/) works here.
- `typography`: what fonts to use. Any font available on [Google Fonts](https://fonts.google.com/) works here.
- `header`: Font to use for headers
- `title`: font for the title of the site (optional, same as `header` by default)
- `code`: Font for inline and block quotes.
- `header`: font to use for headers
- `body`: Font for everything
- `code`: font for inline and block quotes
- `body`: font for everything
- `colors`: controls the theming of the site.
- `colors`: controls the theming of the site.
- `light`: page background
- `light`: page background
- `lightgray`: borders
- `lightgray`: borders
@ -52,6 +56,7 @@ This part of the configuration concerns anything that can affect the whole site.
- `secondary`: link colour, current [[graph view|graph]] node
- `secondary`: link colour, current [[graph view|graph]] node
- `tertiary`: hover states and visited [[graph view|graph]] nodes
- `tertiary`: hover states and visited [[graph view|graph]] nodes
- `highlight`: internal link background, highlighted text, [[syntax highlighting|highlighted lines of code]]
- `highlight`: internal link background, highlighted text, [[syntax highlighting|highlighted lines of code]]
- `textHighlight`: markdown highlighted text background
## Plugins
## Plugins
@ -99,8 +104,30 @@ transformers: [
]
]
```
```
Some plugins are included by default in the[ `quartz.config.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz.config.ts), but there are more available.
Some plugins are included by default in the [`quartz.config.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz.config.ts), but there are more available.
You can see a list of all plugins and their configuration options [[tags/plugin|here]].
You can see a list of all plugins and their configuration options [[tags/plugin|here]].
If you'd like to make your own plugins, see the [[making plugins|making custom plugins]] guide.
If you'd like to make your own plugins, see the [[making plugins|making custom plugins]] guide.
## Fonts
Fonts can be specified as a `string` or a `FontSpecification`:
Quartz uses [rehype-citation](https://github.com/timlrx/rehype-citation) to support parsing of a BibTex bibliography file.
Under the default configuration, a citation key `[@templeton2024scaling]` will be exported as `(Templeton et al., 2024)`.
> [!example]- BibTex file
>
> ```bib title="bibliography.bib"
> @article{templeton2024scaling,
> title={Scaling Monosemanticity: Extracting Interpretable Features from Claude 3 Sonnet},
> author={Templeton, Adly and Conerly, Tom and Marcus, Jonathan and Lindsey, Jack and Bricken, Trenton and Chen, Brian and Pearce, Adam and Citro, Craig and Ameisen, Emmanuel and Jones, Andy and Cunningham, Hoagy and Turner, Nicholas L and McDougall, Callum and MacDiarmid, Monte and Freeman, C. Daniel and Sumers, Theodore R. and Rees, Edward and Batson, Joshua and Jermyn, Adam and Carter, Shan and Olah, Chris and Henighan, Tom},
> By default, the references will be included at the end of the file. To control where the references to be included, uses `[^ref]`
>
> Refer to `rehype-citation` docs for more information.
## Customization
Citation parsing is a functionality of the [[plugins/Citations|Citation]] plugin. **This plugin is not enabled by default**. See the plugin page for customization options.
Quartz emits an RSS feed for all the content on your site by generating an `index.xml` file that RSS readers can subscribe to. Because of the RSS spec, this requires the `baseUrl` property in your [[configuration]] to be set properly for RSS readers to pick it up properly.
Quartz emits an RSS feed for all the content on your site by generating an `index.xml` file that RSS readers can subscribe to. Because of the RSS spec, this requires the `baseUrl` property in your [[configuration]] to be set properly for RSS readers to pick it up properly.
> [!info]
> After deploying, the generated RSS link will be available at `https://${baseUrl}/index.xml` by default.
>
> The `index.xml` path can be customized by passing the `rssSlug` option to the [[ContentIndex]] plugin.
## Configuration
## Configuration
This functionality is provided by the [[ContentIndex]] plugin. See the plugin page for customization options.
This functionality is provided by the [[ContentIndex]] plugin. See the plugin page for customization options.
[Roam Research](https://roamresearch.com) is a note-taking tool that organizes your knowledge graph in a unique and interconnected way.
Quartz supports transforming the special Markdown syntax from Roam Research (like `{{[[components]]}}` and other formatting) into
regular Markdown via the [[RoamFlavoredMarkdown]] plugin.
```typescript title="quartz.config.ts"
plugins: {
transformers: [
// ...
Plugin.RoamFlavoredMarkdown(),
Plugin.ObsidianFlavoredMarkdown(),
// ...
],
},
```
> [!warning]
> As seen above placement of `Plugin.RoamFlavoredMarkdown()` within `quartz.config.ts` is very important. It must come before `Plugin.ObsidianFlavoredMarkdown()`.
## Customization
This functionality is provided by the [[RoamFlavoredMarkdown]] plugin. See the plugin page for customization options.
@ -9,6 +9,7 @@ A backlink for a note is a link from another note to that note. Links in the bac
## Customization
## Customization
- Removing backlinks: delete all usages of `Component.Backlinks()` from `quartz.layout.ts`.
- Removing backlinks: delete all usages of `Component.Backlinks()` from `quartz.layout.ts`.
- Hide when empty: hide `Backlinks` if given page doesn't contain any backlinks (default to `true`). To disable this, use `Component.Backlinks({ hideWhenEmpty: false })`.
Quartz also has the ability to hook into various providers to enable readers to leave comments on your site.
![[giscus-example.png]]
As of today, only [Giscus](https://giscus.app/) is supported out of the box but PRs to support other providers are welcome!
## Providers
### Giscus
First, make sure that the [[setting up your GitHub repository|GitHub]] repository you are using for your Quartz meets the following requirements:
1. The**repository is[public](https://docs.github.com/en/github/administering-a-repository/managing-repository-settings/setting-repository-visibility#making-a-repository-public)**, otherwise visitors will not be able to view the discussion.
2. The**[giscus](https://github.com/apps/giscus)app is installed**, otherwise visitors will not be able to comment and react.
3. The**Discussions feature is turned on**by[enabling it for your repository](https://docs.github.com/en/github/administering-a-repository/managing-repository-settings/enabling-or-disabling-github-discussions-for-a-repository).
Then, use the [Giscus site](https://giscus.app/#repository) to figure out what your `repoId` and `categoryId` should be. Make sure you select `Announcements` for the Discussion category.
![[giscus-repo.png]]
![[giscus-discussion.png]]
After entering both your repository and selecting the discussion category, Giscus will compute some IDs that you'll need to provide back to Quartz. You won't need to manually add the script yourself as Quartz will handle that part for you but will need these values in the next step!
![[giscus-results.png]]
Finally, in `quartz.layout.ts`, edit the `afterBody` field of `sharedPageComponents` to include the following options but with the values you got from above:
```ts title="quartz.layout.ts"
afterBody: [
Component.Comments({
provider: 'giscus',
options: {
// from data-repo
repo: 'jackyzha0/quartz',
// from data-repo-id
repoId: 'MDEwOlJlcG9zaXRvcnkzODcyMTMyMDg',
// from data-category
category: 'Announcements',
// from data-category-id
categoryId: 'DIC_kwDOFxRnmM4B-Xg6',
// from data-lang
lang: 'en'
}
}),
],
```
### Customization
Quartz also exposes a few of the other Giscus options as well and you can provide them the same way `repo`, `repoId`, `category`, and `categoryId` are provided.
```ts
type Options = {
provider: "giscus"
options: {
repo: `${string}/${string}`
repoId: string
category: string
categoryId: string
// Url to folder with custom themes
// defaults to 'https://${cfg.baseUrl}/static/giscus'
// where to put the comment input box relative to the comments
// defaults to 'bottom'
inputPosition?: "top" | "bottom"
// set your preference language here
// defaults to 'en'
lang?: string
}
}
```
#### Custom CSS theme
Quartz supports custom theme for Giscus. To use a custom CSS theme, place the `.css` file inside the `quartz/static` folder and set the configuration values.
For example, if you have a light theme `light-theme.css`, a dark theme `dark-theme.css`, and your Quartz site is hosted at `https://example.com/`:
```ts
afterBody: [
Component.Comments({
provider: 'giscus',
options: {
// Other options
themeUrl: "https://example.com/static/giscus", // corresponds to quartz/static/giscus/
lightTheme: "light-theme", // corresponds to light-theme.css in quartz/static/giscus/
darkTheme: "dark-theme", // corresponds to dark-theme.css quartz/static/giscus/
}
}),
],
```
#### Conditionally display comments
Quartz can conditionally display the comment box based on a field `comments` in the frontmatter. By default, all pages will display comments, to disable it for a specific page, set `comments` to `false`.
folderClickBehavior: "collapse", // what happens when you click a folder ("link" to navigate to folder page on click or "collapse" to collapse folder on click)
folderClickBehavior: "collapse", // what happens when you click a folder ("link" to navigate to folder page on click or "collapse" to collapse folder on click)
folderDefaultState: "collapsed", // default state of folders ("collapsed" or "open")
folderDefaultState: "collapsed", // default state of folders ("collapsed" or "open")
useSavedState: true, // whether to use local storage to save "state" (which folders are opened) of explorer
useSavedState: true, // whether to use local storage to save "state" (which folders are opened) of explorer
// Sort order: folders first, then files. Sort folders and files alphabetically
@ -45,26 +43,30 @@ Want to customize it even more?
- Removing explorer: remove `Component.Explorer()` from `quartz.layout.ts`
- Removing explorer: remove `Component.Explorer()` from `quartz.layout.ts`
- (optional): After removing the explorer component, you can move the [[table of contents | Table of Contents]] component back to the `left` part of the layout
- (optional): After removing the explorer component, you can move the [[table of contents | Table of Contents]] component back to the `left` part of the layout
- Changing `sort`, `filter` and `map` behavior: explained in [[#Advanced customization]]
- Changing `sort`, `filter` and `map` behavior: explained in [[#Advanced customization]]
@ -100,41 +101,23 @@ For more information on how to use `sort`, `filter` and `map`, you can check [Ar
Type definitions look like this:
Type definitions look like this:
```ts
```ts
sortFn: (a: FileNode, b: FileNode) => number
type SortFn = (a: FileTrieNode, b: FileTrieNode) => number
filterFn: (node: FileNode) => boolean
type FilterFn = (node: FileTrieNode) => boolean
mapFn: (node: FileNode) => void
type MapFn = (node: FileTrieNode) => void
```
```
> [!tip]
> You can check if a `FileNode` is a folder or a file like this:
>
> ```ts
> if (node.file) {
> // node is a file
> } else {
> // node is a folder
> }
> ```
## Basic examples
## Basic examples
These examples show the basic usage of `sort`, `map` and `filter`.
These examples show the basic usage of `sort`, `map` and `filter`.
### Use `sort` to put files first
### Use `sort` to put files first
Using this example, the explorer will alphabetically sort everything, but put all **files** above all **folders**.
Using this example, the explorer will alphabetically sort everything.
```ts title="quartz.layout.ts"
```ts title="quartz.layout.ts"
Component.Explorer({
Component.Explorer({
sortFn: (a, b) => {
sortFn: (a, b) => {
if ((!a.file && !b.file) || (a.file && b.file)) {
return a.displayName.localeCompare(b.displayName)
return a.displayName.localeCompare(b.displayName)
}
if (a.file && !b.file) {
return -1
} else {
return 1
}
},
},
})
})
```
```
@ -147,42 +130,47 @@ Using this example, the display names of all `FileNodes` (folders + files) will
Component.Explorer({
Component.Explorer({
mapFn: (node) => {
mapFn: (node) => {
node.displayName = node.displayName.toUpperCase()
node.displayName = node.displayName.toUpperCase()
return node
},
},
})
})
```
```
### Remove list of elements (`filter`)
### Remove list of elements (`filter`)
Using this example, you can remove elements from your explorer by providing an array of folders/files using the `omit` set.
Using this example, you can remove elements from your explorer by providing an array of folders/files to exclude.
Note that this example filters on the title but you can also do it via slug or any other field available on `FileTrieNode`.
```ts title="quartz.layout.ts"
```ts title="quartz.layout.ts"
Component.Explorer({
Component.Explorer({
filterFn: (node) => {
filterFn: (node) => {
// set containing names of everything you want to filter out
// set containing names of everything you want to filter out
const omit = new Set(["authoring content", "tags", "hosting"])
const omit = new Set(["authoring content", "tags", "advanced"])
return !omit.has(node.name.toLowerCase())
// can also use node.slug or by anything on node.data
// note that node.data is only present for files that exist on disk
// (e.g. implicit folder nodes that have no associated index.md)
return !omit.has(node.displayName.toLowerCase())
},
},
})
})
```
```
You can customize this by changing the entries of the `omit` set. Simply add all folder or file names you want to remove.
### Remove files by tag
### Remove files by tag
You can access the frontmatter of a file by `node.file?.frontmatter?`. This allows you to filter out files based on their frontmatter, for example by their tags.
You can access the tags of a file by `node.data.tags`.
> export const sortFn: Options["sortFn"] = (a, b) => {
> export const sortFn: Options["sortFn"] = (a, b) => {
> // implement your function here
> // implement your function here
> }
> }
> ```
>
>
> You can then import them like this:
>
> ```ts title="quartz.layout.ts"
> import { mapFn, filterFn, sortFn } from "./functions.ts"
> Component.Explorer({
> Component.Explorer({
> mapFn: mapFn,
> // ... your other options
> filterFn: filterFn,
> mapFn,
> sortFn: sortFn,
> filterFn,
> sortFn,
> })
> })
> ```
> ```
@ -227,93 +213,11 @@ To add emoji prefixes (📁 for folders, 📄 for files), you could use a map fu
```ts title="quartz.layout.ts"
```ts title="quartz.layout.ts"
Component.Explorer({
Component.Explorer({
mapFn: (node) => {
mapFn: (node) => {
// dont change name of root node
if (node.isFolder) {
if (node.depth > 0) {
node.displayName = "📁 " + node.displayName
// set emoji for file/folder
} else {
if (node.file) {
node.displayName = "📄 " + node.displayName
node.displayName = "📄 " + node.displayName
} else {
node.displayName = "📁 " + node.displayName
}
}
}
},
},
})
})
```
```
### Putting it all together
In this example, we're going to customize the explorer by using functions from examples above to [[#Add emoji prefix | add emoji prefixes]], [[#remove-list-of-elements-filter| filter out some folders]] and [[#use-sort-to-put-files-first | sort with files above folders]].
```ts title="quartz.layout.ts"
Component.Explorer({
filterFn: sampleFilterFn,
mapFn: sampleMapFn,
sortFn: sampleSortFn,
order: ["filter", "sort", "map"],
})
```
Notice how we customized the `order` array here. This is done because the default order applies the `sort` function last. While this normally works well, it would cause unintended behavior here, since we changed the first characters of all display names. In our example, `sort` would be applied based off the emoji prefix instead of the first _real_ character.
To fix this, we just changed around the order and apply the `sort` function before changing the display names in the `map` function.
### Use `sort` with pre-defined sort order
Here's another example where a map containing file/folder names (as slugs) is used to define the sort order of the explorer in quartz. All files/folders that aren't listed inside of `nameOrderMap` will appear at the top of that folders hierarchy level.
It's also worth mentioning, that the smaller the number set in `nameOrderMap`, the higher up the entry will be in the explorer. Incrementing every folder/file by 100, makes ordering files in their folders a lot easier. Lastly, this example still allows you to use a `mapFn` or frontmatter titles to change display names, as it uses slugs for `nameOrderMap` (which is unaffected by display name changes).
```ts title="quartz.layout.ts"
Component.Explorer({
sortFn: (a, b) => {
const nameOrderMap: Record<string, number> = {
"poetry-folder": 100,
"essay-folder": 200,
"research-paper-file": 201,
"dinosaur-fossils-file": 300,
"other-folder": 400,
}
let orderA = 0
let orderB = 0
if (a.file && a.file.slug) {
orderA = nameOrderMap[a.file.slug] || 0
} else if (a.name) {
orderA = nameOrderMap[a.name] || 0
}
if (b.file && b.file.slug) {
orderB = nameOrderMap[b.file.slug] || 0
} else if (b.name) {
orderB = nameOrderMap[b.name] || 0
}
return orderA - orderB
},
})
```
For reference, this is how the quartz explorer window would look like with that example:
```
📖 Poetry Folder
📑 Essay Folder
⚗️ Research Paper File
🦴 Dinosaur Fossils File
🔮 Other Folder
```
And this is how the file structure would look like:
@ -30,4 +30,4 @@ As with folder listings, you can also provide a description and title for a tag
## Customization
## Customization
The folder listings are a functionality of the [[FolderPage]] plugin, the tag listings of the [[TagPage]] plugin. See the plugin pages for customization options.
Quartz allows you to define a custom sort ordering for content on both page types. The folder listings are a functionality of the [[FolderPage]] plugin, the tag listings of the [[TagPage]] plugin. See the plugin pages for customization options.
@ -13,9 +13,7 @@ There may be some notes you want to avoid publishing as a website. Quartz suppor
If you'd like to only publish a select number of notes, you can instead use [[ExplicitPublish]] which will filter out all notes except for any that have `publish: true` in the frontmatter.
If you'd like to only publish a select number of notes, you can instead use [[ExplicitPublish]] which will filter out all notes except for any that have `publish: true` in the frontmatter.
> [!warning]
> [!warning]
> Regardless of the filter plugin used, **all non-markdown files will be emitted and available publically in the final build.** This includes files such as images, voice recordings, PDFs, etc. One way to prevent this and still be able to embed local images is to create a folder specifically for public media and add the following two patterns to the ignorePatterns array.
> Regardless of the filter plugin used, **all non-markdown files will be emitted and available publically in the final build.** This includes files such as images, voice recordings, PDFs, etc.
>
> `"!(PublicMedia)**/!(*.md)", "!(*.md)"`
## `ignorePatterns`
## `ignorePatterns`
@ -28,7 +26,7 @@ Common examples include:
-`some/folder`: exclude the entire of `some/folder`
-`some/folder`: exclude the entire of `some/folder`
-`*.md`: exclude all files with a `.md` extension
-`*.md`: exclude all files with a `.md` extension
-`!*.md` exclude all files that _don't_ have a `.md` extension
-`!(*.md)` exclude all files that _don't_ have a `.md` extension. Note that negations _must_ parenthesize the rest of the pattern!
-`**/private`: exclude any files or folders named `private` at any level of nesting
-`**/private`: exclude any files or folders named `private` at any level of nesting
Reader Mode is a feature that allows users to focus on the content by hiding the sidebars and other UI elements. When enabled, it provides a clean, distraction-free reading experience.
## Configuration
Reader Mode is enabled by default. To disable it, you can remove the component from your layout configuration in `quartz.layout.ts`:
```ts
// Remove or comment out this line
Component.ReaderMode(),
```
## Usage
The Reader Mode toggle appears as a button with a book icon. When clicked:
- Sidebars are hidden
- Hovering over the content area reveals the sidebars temporarily
Unlike Dark Mode, Reader Mode state is not persisted between page reloads but is maintained during SPA navigation within the site.
## Customization
You can customize the appearance of Reader Mode through CSS variables and styles. The component uses the following classes:
-`.readermode`: The toggle button
-`.readerIcon`: The book icon
-`[reader-mode="on"]`: Applied to the root element when Reader Mode is active
A lot of social media platforms can display a rich preview for your website when sharing a link (most notably, a cover image, a title and a description).
Quartz can also dynamically generate and use new cover images for every page to be used in link previews on social media for you.
## Showcase
After enabling the [[CustomOgImages]] emitter plugin, the social media link preview for [[authoring content | Authoring Content]] looks like this:
- parse all images in page: use this for page lists if applicable?
- CV mode? with print stylesheet
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.