Showing preview only (3,840K chars total). Download the full file or copy to clipboard to get everything.
Repository: iamgio/quarkdown
Branch: main
Commit: 007e056b4dc1
Files: 1523
Total size: 3.3 MB
Directory structure:
gitextract_3z3aa1yn/
├── .dockerignore
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.yml
│ │ ├── config.yml
│ │ └── enhancement.yml
│ ├── PULL_REQUEST_TEMPLATE.md
│ ├── actions/
│ │ ├── bump-scoop/
│ │ │ └── action.yml
│ │ ├── deploy-wiki/
│ │ │ └── action.yml
│ │ ├── setup-environment/
│ │ │ └── action.yml
│ │ └── update-emoji-list/
│ │ ├── action.yml
│ │ └── generate.qd
│ └── workflows/
│ ├── deploy-wiki.yml
│ ├── generate-pdf/
│ │ ├── color.txt
│ │ ├── generate-theme-combinations.js
│ │ └── layout.txt
│ ├── generate-pdf.yml
│ ├── gradle-deploy.yml
│ ├── gradle-test.yml
│ └── update-emoji-list.yml
├── .gitignore
├── .run/
│ ├── CLI_Docs.run.xml
│ ├── CLI_Mock.run.xml
│ ├── Lint_format.run.xml
│ ├── Test_full_suite.run.xml
│ └── Test_minimal_suite.run.xml
├── CHANGELOG.md
├── CLAUDE.md
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE
├── README.md
├── build.gradle.kts
├── demo/
│ ├── code/
│ │ └── Point.java
│ ├── csv/
│ │ └── people.csv
│ ├── demo.qd
│ ├── mermaid/
│ │ └── flow.mmd
│ └── sources/
│ └── other.qd
├── docs/
│ ├── _nav.qd
│ ├── _setup.qd
│ ├── align.qd
│ ├── assets/
│ │ ├── analytics.html
│ │ ├── people.csv
│ │ ├── people2.csv
│ │ ├── point.ts
│ │ ├── sales.csv
│ │ └── style.css
│ ├── bibliography/
│ │ ├── file.bib
│ │ └── source.qd
│ ├── bibliography.qd
│ ├── boolean.qd
│ ├── box.qd
│ ├── caption-position.qd
│ ├── cli-compiler.qd
│ ├── cli-project-creator.qd
│ ├── cli-webserver.qd
│ ├── clip.qd
│ ├── code-caption.qd
│ ├── code.qd
│ ├── collapsible.qd
│ ├── color.qd
│ ├── conditional-statements.qd
│ ├── container.qd
│ ├── cross-references.qd
│ ├── css.qd
│ ├── custom-figure.qd
│ ├── declaring-functions.qd
│ ├── destructuring.qd
│ ├── dictionary.qd
│ ├── docs-library.qd
│ ├── document-metadata.qd
│ ├── document-types.qd
│ ├── emojis.qd
│ ├── enumeration-entry.qd
│ ├── figure.qd
│ ├── file-data.qd
│ ├── file-tree.qd
│ ├── float.qd
│ ├── font-configuration.qd
│ ├── footnotes.qd
│ ├── headings.qd
│ ├── html.qd
│ ├── icons.qd
│ ├── image-size.qd
│ ├── importing-external-libraries.qd
│ ├── including-other-quarkdown-files.qd
│ ├── inclusion-vs-subdocuments.qd
│ ├── inside-live-preview.qd
│ ├── iterable.qd
│ ├── lambda.qd
│ ├── landscape-content.qd
│ ├── let.qd
│ ├── line-breaks.qd
│ ├── localization.qd
│ ├── logging.qd
│ ├── loops.qd
│ ├── main.qd
│ ├── markdown-content.qd
│ ├── math.qd
│ ├── media-storage.qd
│ ├── mermaid-diagrams.qd
│ ├── multi-column-layout/
│ │ └── source.qd
│ ├── multi-column-layout.qd
│ ├── none.qd
│ ├── numbering.qd
│ ├── page-break.qd
│ ├── page-counter.qd
│ ├── page-format.qd
│ ├── page-margin-content.qd
│ ├── paper-library.qd
│ ├── paragraph-style.qd
│ ├── pdf-export.qd
│ ├── persistent-headings.qd
│ ├── pipeline---function-call-expansion.qd
│ ├── pipeline---lexing.qd
│ ├── pipeline---parsing.qd
│ ├── pipeline---post-rendering.qd
│ ├── pipeline---rendering.qd
│ ├── pipeline---tree-traversal.qd
│ ├── pipeline.qd
│ ├── quickstart.qd
│ ├── quotation-source.qd
│ ├── quote-types.qd
│ ├── range.qd
│ ├── sizes.qd
│ ├── slides-configuration.qd
│ ├── slides-fragment.qd
│ ├── slides-speaker-notes.qd
│ ├── stacks.qd
│ ├── subdocuments.qd
│ ├── syntax-of-a-function-call.qd
│ ├── table-caption.qd
│ ├── table-generation.qd
│ ├── table-manipulation.qd
│ ├── table-of-contents.qd
│ ├── tex-formulae.qd
│ ├── tex-macros.qd
│ ├── text-symbols.qd
│ ├── text.qd
│ ├── themes.qd
│ ├── typing.qd
│ ├── variables.qd
│ ├── whitespace.qd
│ └── xy-chart.qd
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── mock/
│ ├── README.md
│ ├── alignment.qd
│ ├── bibliography/
│ │ └── bibliography.bib
│ ├── bibliography.qd
│ ├── boxes.qd
│ ├── code/
│ │ └── Wrapper.java
│ ├── code.qd
│ ├── collapsibles.qd
│ ├── colorpreview.qd
│ ├── crossreferences.qd
│ ├── errors.qd
│ ├── footnotes.qd
│ ├── headings.qd
│ ├── icons.qd
│ ├── images.qd
│ ├── lists.qd
│ ├── localization.qd
│ ├── main.qd
│ ├── math.qd
│ ├── mermaid/
│ │ ├── class.mmd
│ │ ├── flow.mmd
│ │ ├── git.mmd
│ │ ├── pie.mmd
│ │ └── sequence.mmd
│ ├── mermaid.qd
│ ├── paragraphs.qd
│ ├── quotes.qd
│ ├── separators.qd
│ ├── setup.qd
│ ├── stacks.qd
│ ├── tables.qd
│ └── textformatting.qd
├── quarkdown-cli/
│ ├── LICENSE
│ ├── build.gradle.kts
│ └── src/
│ ├── main/
│ │ ├── kotlin/
│ │ │ └── com/
│ │ │ └── quarkdown/
│ │ │ └── cli/
│ │ │ ├── CliOptions.kt
│ │ │ ├── PipelineInitialization.kt
│ │ │ ├── QuarkdownCli.kt
│ │ │ ├── creator/
│ │ │ │ ├── ProjectCreator.kt
│ │ │ │ ├── command/
│ │ │ │ │ └── CreateProjectCommand.kt
│ │ │ │ ├── content/
│ │ │ │ │ ├── DefaultProjectCreatorInitialContentSupplier.kt
│ │ │ │ │ ├── DefaultTheme.kt
│ │ │ │ │ ├── DocsProjectCreatorInitialContentSupplier.kt
│ │ │ │ │ ├── EmptyProjectCreatorInitialContentSupplier.kt
│ │ │ │ │ └── ProjectCreatorInitialContentSupplier.kt
│ │ │ │ └── template/
│ │ │ │ ├── DefaultProjectCreatorTemplateProcessorFactory.kt
│ │ │ │ ├── DocsProjectCreatorTemplateProcessorFactory.kt
│ │ │ │ ├── ProjectCreatorTemplatePlaceholders.kt
│ │ │ │ └── ProjectCreatorTemplateProcessorFactory.kt
│ │ │ ├── exec/
│ │ │ │ ├── CompileCommand.kt
│ │ │ │ ├── Execute.kt
│ │ │ │ ├── ExecuteCommand.kt
│ │ │ │ ├── ExecutionOutcome.kt
│ │ │ │ ├── ReplCommand.kt
│ │ │ │ └── strategy/
│ │ │ │ ├── FileExecutionStrategy.kt
│ │ │ │ ├── PipelineExecutionStrategy.kt
│ │ │ │ └── ReplExecutionStrategy.kt
│ │ │ ├── lib/
│ │ │ │ └── QdLibraries.kt
│ │ │ ├── lsp/
│ │ │ │ └── LanguageServerCommand.kt
│ │ │ ├── renderer/
│ │ │ │ └── RendererRetriever.kt
│ │ │ ├── server/
│ │ │ │ ├── BrowserLauncherOption.kt
│ │ │ │ ├── StartWebServerCommand.kt
│ │ │ │ ├── WebServerOptions.kt
│ │ │ │ └── WebServerStarter.kt
│ │ │ ├── util/
│ │ │ │ ├── IOUtils.kt
│ │ │ │ └── MillisStopwatch.kt
│ │ │ └── watcher/
│ │ │ └── DirectoryWatcher.kt
│ │ └── resources/
│ │ └── creator/
│ │ ├── docs/
│ │ │ ├── _nav.qd
│ │ │ ├── main.qd.jte
│ │ │ ├── page-1.qd
│ │ │ ├── page-2.qd
│ │ │ └── page-3.qd
│ │ ├── initialcontent.qd.jte
│ │ └── main.qd.jte
│ └── test/
│ └── kotlin/
│ └── com/
│ └── quarkdown/
│ └── cli/
│ ├── BrowserLauncherSelectionTest.kt
│ ├── CompileCommandTest.kt
│ ├── ProjectCreatorCommandTest.kt
│ ├── ProjectCreatorTest.kt
│ ├── TempDirectory.kt
│ ├── VersionTest.kt
│ └── WatcherTest.kt
├── quarkdown-core/
│ ├── build.gradle.kts
│ ├── csl-styles.txt
│ └── src/
│ ├── main/
│ │ ├── kotlin/
│ │ │ └── com/
│ │ │ └── quarkdown/
│ │ │ └── core/
│ │ │ ├── ExitCodes.kt
│ │ │ ├── ast/
│ │ │ │ ├── AstRoot.kt
│ │ │ │ ├── InlineContent.kt
│ │ │ │ ├── MarkdownContent.kt
│ │ │ │ ├── Node.kt
│ │ │ │ ├── attributes/
│ │ │ │ │ ├── AstAttributes.kt
│ │ │ │ │ ├── id/
│ │ │ │ │ │ ├── Identifiable.kt
│ │ │ │ │ │ └── IdentifierProvider.kt
│ │ │ │ │ ├── link/
│ │ │ │ │ │ └── ResolvedLinkUrlProperty.kt
│ │ │ │ │ ├── localization/
│ │ │ │ │ │ ├── LocalizedKind.kt
│ │ │ │ │ │ └── LocalizedKindKeys.kt
│ │ │ │ │ ├── location/
│ │ │ │ │ │ ├── LocationLabelProperty.kt
│ │ │ │ │ │ ├── LocationTrackableNode.kt
│ │ │ │ │ │ ├── SectionLocation.kt
│ │ │ │ │ │ └── SectionLocationProperty.kt
│ │ │ │ │ ├── presence/
│ │ │ │ │ │ ├── CodePresenceProperty.kt
│ │ │ │ │ │ ├── MathPresenceProperty.kt
│ │ │ │ │ │ ├── MermaidPresenceProperty.kt
│ │ │ │ │ │ └── ThirdPartyPresenceProperties.kt
│ │ │ │ │ └── reference/
│ │ │ │ │ ├── ReferenceNode.kt
│ │ │ │ │ └── ResolvedReferenceProperty.kt
│ │ │ │ ├── base/
│ │ │ │ │ ├── LinkNode.kt
│ │ │ │ │ ├── TextNode.kt
│ │ │ │ │ ├── block/
│ │ │ │ │ │ ├── BlankNode.kt
│ │ │ │ │ │ ├── BlockQuote.kt
│ │ │ │ │ │ ├── Code.kt
│ │ │ │ │ │ ├── FootnoteDefinition.kt
│ │ │ │ │ │ ├── Heading.kt
│ │ │ │ │ │ ├── HeadingFactory.kt
│ │ │ │ │ │ ├── HeadingMarker.kt
│ │ │ │ │ │ ├── HorizontalRule.kt
│ │ │ │ │ │ ├── Html.kt
│ │ │ │ │ │ ├── LinkDefinition.kt
│ │ │ │ │ │ ├── Newline.kt
│ │ │ │ │ │ ├── Paragraph.kt
│ │ │ │ │ │ ├── Table.kt
│ │ │ │ │ │ └── list/
│ │ │ │ │ │ ├── List.kt
│ │ │ │ │ │ ├── ListItem.kt
│ │ │ │ │ │ ├── ListItemVariant.kt
│ │ │ │ │ │ └── TaskListItemVariant.kt
│ │ │ │ │ └── inline/
│ │ │ │ │ ├── CheckBox.kt
│ │ │ │ │ ├── CodeSpan.kt
│ │ │ │ │ ├── Comment.kt
│ │ │ │ │ ├── Emphasis.kt
│ │ │ │ │ ├── Image.kt
│ │ │ │ │ ├── LineBreak.kt
│ │ │ │ │ ├── Link.kt
│ │ │ │ │ ├── ReferenceFootnote.kt
│ │ │ │ │ ├── SubdocumentLink.kt
│ │ │ │ │ └── Text.kt
│ │ │ │ ├── dsl/
│ │ │ │ │ ├── AstBuilder.kt
│ │ │ │ │ ├── BlockAstBuilder.kt
│ │ │ │ │ ├── InlineAstBuilder.kt
│ │ │ │ │ ├── ListAstBuilder.kt
│ │ │ │ │ └── TableAstBuilder.kt
│ │ │ │ ├── iterator/
│ │ │ │ │ ├── AstIterator.kt
│ │ │ │ │ ├── AstIteratorHook.kt
│ │ │ │ │ └── ObservableAstIterator.kt
│ │ │ │ ├── media/
│ │ │ │ │ └── StoredMediaProperty.kt
│ │ │ │ └── quarkdown/
│ │ │ │ ├── CaptionableNode.kt
│ │ │ │ ├── FunctionCallNode.kt
│ │ │ │ ├── bibliography/
│ │ │ │ │ ├── BibliographyCitation.kt
│ │ │ │ │ └── BibliographyView.kt
│ │ │ │ ├── block/
│ │ │ │ │ ├── Box.kt
│ │ │ │ │ ├── Clipped.kt
│ │ │ │ │ ├── Collapse.kt
│ │ │ │ │ ├── Container.kt
│ │ │ │ │ ├── Figure.kt
│ │ │ │ │ ├── FileTree.kt
│ │ │ │ │ ├── Landscape.kt
│ │ │ │ │ ├── Math.kt
│ │ │ │ │ ├── MermaidDiagram.kt
│ │ │ │ │ ├── NavigationContainer.kt
│ │ │ │ │ ├── Numbered.kt
│ │ │ │ │ ├── PageBreak.kt
│ │ │ │ │ ├── SlidesFragment.kt
│ │ │ │ │ ├── SlidesSpeakerNote.kt
│ │ │ │ │ ├── Stacked.kt
│ │ │ │ │ ├── SubdocumentGraph.kt
│ │ │ │ │ ├── list/
│ │ │ │ │ │ ├── FocusListItemVariant.kt
│ │ │ │ │ │ ├── LocationTargetListItemVariant.kt
│ │ │ │ │ │ └── TableOfContentsItemVariant.kt
│ │ │ │ │ └── toc/
│ │ │ │ │ ├── TableOfContentsUtils.kt
│ │ │ │ │ └── TableOfContentsView.kt
│ │ │ │ ├── inline/
│ │ │ │ │ ├── IconImage.kt
│ │ │ │ │ ├── InlineCollapse.kt
│ │ │ │ │ ├── LastHeading.kt
│ │ │ │ │ ├── MathSpan.kt
│ │ │ │ │ ├── PageCounter.kt
│ │ │ │ │ ├── TextSymbol.kt
│ │ │ │ │ ├── TextTransform.kt
│ │ │ │ │ └── Whitespace.kt
│ │ │ │ ├── invisible/
│ │ │ │ │ ├── PageMarginContentInitializer.kt
│ │ │ │ │ ├── PageNumberFormatter.kt
│ │ │ │ │ ├── PageNumberReset.kt
│ │ │ │ │ └── SlidesConfigurationInitializer.kt
│ │ │ │ └── reference/
│ │ │ │ ├── CrossReference.kt
│ │ │ │ └── CrossReferenceableNode.kt
│ │ │ ├── bibliography/
│ │ │ │ ├── Bibliography.kt
│ │ │ │ └── style/
│ │ │ │ ├── BibliographyEntryLabelProviderStrategy.kt
│ │ │ │ ├── BibliographyStyle.kt
│ │ │ │ └── csl/
│ │ │ │ ├── CslBibliographyStyle.kt
│ │ │ │ ├── CslTokenConverter.kt
│ │ │ │ ├── FormattedBibliographyEntry.kt
│ │ │ │ └── QuarkdownCslFormat.kt
│ │ │ ├── context/
│ │ │ │ ├── BaseContext.kt
│ │ │ │ ├── ChildContext.kt
│ │ │ │ ├── Context.kt
│ │ │ │ ├── ContextOptions.kt
│ │ │ │ ├── MutableContext.kt
│ │ │ │ ├── ScopeContext.kt
│ │ │ │ ├── SharedContext.kt
│ │ │ │ ├── SubdocumentContext.kt
│ │ │ │ ├── file/
│ │ │ │ │ └── FileSystem.kt
│ │ │ │ ├── hooks/
│ │ │ │ │ ├── LinkUrlResolverHook.kt
│ │ │ │ │ ├── MediaStorerHook.kt
│ │ │ │ │ ├── SubdocumentRegistrationHook.kt
│ │ │ │ │ ├── TableOfContentsGeneratorHook.kt
│ │ │ │ │ ├── location/
│ │ │ │ │ │ ├── LocationAwareLabelStorerHook.kt
│ │ │ │ │ │ ├── LocationAwarenessHook.kt
│ │ │ │ │ │ └── NumberedEvaluatorHook.kt
│ │ │ │ │ ├── presence/
│ │ │ │ │ │ └── ThirdPartyPresenceHook.kt
│ │ │ │ │ └── reference/
│ │ │ │ │ ├── BibliographyCitationResolverHook.kt
│ │ │ │ │ ├── CrossReferenceResolverHook.kt
│ │ │ │ │ ├── FootnoteResolverHook.kt
│ │ │ │ │ ├── LinkDefinitionResolverHook.kt
│ │ │ │ │ └── ReferenceDefinitionResolverHook.kt
│ │ │ │ ├── localization/
│ │ │ │ │ └── ContextLocalization.kt
│ │ │ │ ├── subdocument/
│ │ │ │ │ └── SubdocumentsData.kt
│ │ │ │ └── toc/
│ │ │ │ └── TableOfContents.kt
│ │ │ ├── document/
│ │ │ │ ├── DocumentAuthor.kt
│ │ │ │ ├── DocumentInfo.kt
│ │ │ │ ├── DocumentTheme.kt
│ │ │ │ ├── DocumentType.kt
│ │ │ │ ├── layout/
│ │ │ │ │ ├── DocumentLayoutInfo.kt
│ │ │ │ │ ├── caption/
│ │ │ │ │ │ ├── CaptionPosition.kt
│ │ │ │ │ │ └── CaptionPositionInfo.kt
│ │ │ │ │ ├── font/
│ │ │ │ │ │ └── FontInfo.kt
│ │ │ │ │ ├── page/
│ │ │ │ │ │ ├── PageFormatInfo.kt
│ │ │ │ │ │ ├── PageMarginPosition.kt
│ │ │ │ │ │ ├── PageOrientation.kt
│ │ │ │ │ │ ├── PageSide.kt
│ │ │ │ │ │ └── PageSizeFormat.kt
│ │ │ │ │ └── paragraph/
│ │ │ │ │ └── ParagraphStyleInfo.kt
│ │ │ │ ├── numbering/
│ │ │ │ │ ├── DocumentNumbering.kt
│ │ │ │ │ ├── NumberingCounterSymbol.kt
│ │ │ │ │ ├── NumberingFixedSymbol.kt
│ │ │ │ │ ├── NumberingFormat.kt
│ │ │ │ │ └── NumberingSymbol.kt
│ │ │ │ ├── size/
│ │ │ │ │ ├── BoundingBox.kt
│ │ │ │ │ ├── Size.kt
│ │ │ │ │ └── Sizes.kt
│ │ │ │ ├── slides/
│ │ │ │ │ └── Transition.kt
│ │ │ │ ├── sub/
│ │ │ │ │ ├── Subdocument.kt
│ │ │ │ │ └── SubdocumentOutputNaming.kt
│ │ │ │ └── tex/
│ │ │ │ └── TexInfo.kt
│ │ │ ├── flavor/
│ │ │ │ ├── LexerFactory.kt
│ │ │ │ ├── MarkdownFlavor.kt
│ │ │ │ ├── ParserFactory.kt
│ │ │ │ ├── RendererFactory.kt
│ │ │ │ ├── TreeIteratorFactory.kt
│ │ │ │ ├── base/
│ │ │ │ │ ├── BaseMarkdownFlavor.kt
│ │ │ │ │ ├── BaseMarkdownLexerFactory.kt
│ │ │ │ │ ├── BaseMarkdownParserFactory.kt
│ │ │ │ │ ├── BaseMarkdownRendererFactory.kt
│ │ │ │ │ └── BaseMarkdownTreeIteratorFactory.kt
│ │ │ │ └── quarkdown/
│ │ │ │ ├── QuarkdownFlavor.kt
│ │ │ │ ├── QuarkdownLexerFactory.kt
│ │ │ │ ├── QuarkdownParserFactory.kt
│ │ │ │ ├── QuarkdownRendererFactory.kt
│ │ │ │ └── QuarkdownTreeIteratorFactory.kt
│ │ │ ├── function/
│ │ │ │ ├── Function.kt
│ │ │ │ ├── FunctionParameter.kt
│ │ │ │ ├── Naming.kt
│ │ │ │ ├── call/
│ │ │ │ │ ├── CallDepth.kt
│ │ │ │ │ ├── FunctionCall.kt
│ │ │ │ │ ├── FunctionCallArgument.kt
│ │ │ │ │ ├── FunctionCallNodeExpander.kt
│ │ │ │ │ ├── UncheckedFunctionCall.kt
│ │ │ │ │ ├── binding/
│ │ │ │ │ │ ├── AllArgumentsBinder.kt
│ │ │ │ │ │ ├── ArgumentsBinder.kt
│ │ │ │ │ │ ├── InjectedArgumentsBinder.kt
│ │ │ │ │ │ └── RegularArgumentsBinder.kt
│ │ │ │ │ └── validate/
│ │ │ │ │ ├── DocumentTypeFunctionCallValidator.kt
│ │ │ │ │ └── FunctionCallValidator.kt
│ │ │ │ ├── error/
│ │ │ │ │ ├── FunctionCallRuntimeException.kt
│ │ │ │ │ ├── FunctionException.kt
│ │ │ │ │ ├── InvalidArgumentCountException.kt
│ │ │ │ │ ├── InvalidFunctionCallException.kt
│ │ │ │ │ ├── MismatchingArgumentTypeException.kt
│ │ │ │ │ ├── NoSuchElementException.kt
│ │ │ │ │ ├── ParameterAlreadyBoundException.kt
│ │ │ │ │ ├── UnnamedArgumentAfterNamedException.kt
│ │ │ │ │ ├── UnresolvedParameterException.kt
│ │ │ │ │ ├── UnresolvedReferenceException.kt
│ │ │ │ │ └── internal/
│ │ │ │ │ └── InvalidExpressionEvalException.kt
│ │ │ │ ├── expression/
│ │ │ │ │ ├── ComposedExpression.kt
│ │ │ │ │ ├── Expression.kt
│ │ │ │ │ ├── SafeExpression.kt
│ │ │ │ │ └── visitor/
│ │ │ │ │ ├── AppendExpressionVisitor.kt
│ │ │ │ │ ├── EvalExpressionVisitor.kt
│ │ │ │ │ └── ExpressionVisitor.kt
│ │ │ │ ├── library/
│ │ │ │ │ ├── Library.kt
│ │ │ │ │ ├── LibraryExporter.kt
│ │ │ │ │ ├── LibraryRegistrant.kt
│ │ │ │ │ ├── loader/
│ │ │ │ │ │ ├── FunctionLibraryLoader.kt
│ │ │ │ │ │ ├── LibraryLoader.kt
│ │ │ │ │ │ ├── MultiFunctionLibraryLoader.kt
│ │ │ │ │ │ └── MultiLibraryLoader.kt
│ │ │ │ │ └── module/
│ │ │ │ │ └── QuarkdownModule.kt
│ │ │ │ ├── reflect/
│ │ │ │ │ ├── DynamicValueConverter.kt
│ │ │ │ │ ├── InjectedValue.kt
│ │ │ │ │ ├── KFunctionAdapter.kt
│ │ │ │ │ ├── ReflectionUtils.kt
│ │ │ │ │ └── annotation/
│ │ │ │ │ ├── Injected.kt
│ │ │ │ │ ├── Name.kt
│ │ │ │ │ ├── NoAutoArgumentUnwrapping.kt
│ │ │ │ │ ├── OnlyForDocumentType.kt
│ │ │ │ │ └── QuarkdocAnnotations.kt
│ │ │ │ └── value/
│ │ │ │ ├── AdaptableValue.kt
│ │ │ │ ├── BooleanValue.kt
│ │ │ │ ├── Destructurable.kt
│ │ │ │ ├── DictionaryValue.kt
│ │ │ │ ├── DynamicValue.kt
│ │ │ │ ├── EnumValue.kt
│ │ │ │ ├── GeneralCollectionValue.kt
│ │ │ │ ├── IterableValue.kt
│ │ │ │ ├── LambdaValue.kt
│ │ │ │ ├── MarkdownContentValue.kt
│ │ │ │ ├── NodeValue.kt
│ │ │ │ ├── NoneValue.kt
│ │ │ │ ├── NumberValue.kt
│ │ │ │ ├── ObjectValue.kt
│ │ │ │ ├── OrderedCollectionValue.kt
│ │ │ │ ├── PairValue.kt
│ │ │ │ ├── StringValue.kt
│ │ │ │ ├── UnorderedCollectionValue.kt
│ │ │ │ ├── Value.kt
│ │ │ │ ├── VoidValue.kt
│ │ │ │ ├── data/
│ │ │ │ │ ├── EvaluableString.kt
│ │ │ │ │ ├── Lambda.kt
│ │ │ │ │ └── Range.kt
│ │ │ │ ├── factory/
│ │ │ │ │ ├── IllegalRawValueException.kt
│ │ │ │ │ └── ValueFactory.kt
│ │ │ │ └── output/
│ │ │ │ ├── OutputValueVisitor.kt
│ │ │ │ ├── OutputValueVisitorFactory.kt
│ │ │ │ └── node/
│ │ │ │ ├── BlockNodeOutputValueVisitor.kt
│ │ │ │ ├── InlineNodeOutputValueVisitor.kt
│ │ │ │ ├── NodeOutputValueVisitor.kt
│ │ │ │ └── NodeOutputValueVisitorFactory.kt
│ │ │ ├── graph/
│ │ │ │ ├── Graph.kt
│ │ │ │ ├── Graphs.kt
│ │ │ │ ├── PersistentDirectedGraph.kt
│ │ │ │ └── VisitableOnceGraph.kt
│ │ │ ├── lexer/
│ │ │ │ ├── AbstractLexer.kt
│ │ │ │ ├── Lexer.kt
│ │ │ │ ├── Token.kt
│ │ │ │ ├── TokenCoordinates.kt
│ │ │ │ ├── TokenData.kt
│ │ │ │ ├── patterns/
│ │ │ │ │ ├── BaseMarkdownBlockTokenRegexPatterns.kt
│ │ │ │ │ ├── BaseMarkdownInlineTokenRegexPatterns.kt
│ │ │ │ │ ├── FunctionCallPatterns.kt
│ │ │ │ │ ├── PatternHelpers.kt
│ │ │ │ │ ├── QuarkdownBlockTokenRegexPatterns.kt
│ │ │ │ │ ├── QuarkdownInlineTokenRegexPatterns.kt
│ │ │ │ │ └── TextSymbolReplacement.kt
│ │ │ │ ├── regex/
│ │ │ │ │ ├── RegexBuilder.kt
│ │ │ │ │ ├── RegexLexer.kt
│ │ │ │ │ ├── StandardRegexLexer.kt
│ │ │ │ │ └── pattern/
│ │ │ │ │ ├── NamedRegexPattern.kt
│ │ │ │ │ ├── RegexPatternGroup.kt
│ │ │ │ │ ├── TokenRegexPattern.kt
│ │ │ │ │ └── WalkedToken.kt
│ │ │ │ └── tokens/
│ │ │ │ ├── BlockTokens.kt
│ │ │ │ ├── FunctionCallToken.kt
│ │ │ │ └── InlineTokens.kt
│ │ │ ├── localization/
│ │ │ │ ├── Locale.kt
│ │ │ │ ├── LocaleLoader.kt
│ │ │ │ ├── LocalizationExceptions.kt
│ │ │ │ ├── LocalizationTable.kt
│ │ │ │ └── jvm/
│ │ │ │ ├── JVMLocale.kt
│ │ │ │ └── JVMLocaleLoader.kt
│ │ │ ├── log/
│ │ │ │ ├── DebugFormatter.kt
│ │ │ │ └── Log.kt
│ │ │ ├── media/
│ │ │ │ ├── LocalMedia.kt
│ │ │ │ ├── Media.kt
│ │ │ │ ├── MediaVisitor.kt
│ │ │ │ ├── RemoteMedia.kt
│ │ │ │ ├── ResolvableMedia.kt
│ │ │ │ ├── export/
│ │ │ │ │ └── MediaOutputResourceConverter.kt
│ │ │ │ └── storage/
│ │ │ │ ├── MutableMediaStorage.kt
│ │ │ │ ├── ReadOnlyMediaStorage.kt
│ │ │ │ ├── StoredMedia.kt
│ │ │ │ ├── name/
│ │ │ │ │ ├── MediaNameProviderStrategy.kt
│ │ │ │ │ └── SanitizedMediaNameProvider.kt
│ │ │ │ └── options/
│ │ │ │ ├── MediaStorageOptions.kt
│ │ │ │ ├── MediaTypeEnabledChecker.kt
│ │ │ │ └── ReadOnlyMediaStorageOptions.kt
│ │ │ ├── misc/
│ │ │ │ ├── color/
│ │ │ │ │ ├── Color.kt
│ │ │ │ │ ├── NamedColor.kt
│ │ │ │ │ └── decoder/
│ │ │ │ │ ├── ColorDecoder.kt
│ │ │ │ │ ├── ColorDecoderUtils.kt
│ │ │ │ │ ├── HexColorDecoder.kt
│ │ │ │ │ ├── HsvHslColorDecoder.kt
│ │ │ │ │ ├── NamedColorDecoder.kt
│ │ │ │ │ └── RgbaColorDecoder.kt
│ │ │ │ └── font/
│ │ │ │ ├── FontFamily.kt
│ │ │ │ └── resolver/
│ │ │ │ ├── FontFamilyResolver.kt
│ │ │ │ └── JVMFontFamilyResolver.kt
│ │ │ ├── parser/
│ │ │ │ ├── BlockTokenParser.kt
│ │ │ │ ├── FunctionCallRefiner.kt
│ │ │ │ ├── InlineTokenParser.kt
│ │ │ │ └── walker/
│ │ │ │ ├── GrammarUtils.kt
│ │ │ │ ├── WalkerParser.kt
│ │ │ │ ├── WalkerParsingResult.kt
│ │ │ │ └── funcall/
│ │ │ │ ├── FunctionCallGrammar.kt
│ │ │ │ ├── FunctionCallWalkerParser.kt
│ │ │ │ └── WalkedFunctionCall.kt
│ │ │ ├── pipeline/
│ │ │ │ ├── Pipeline.kt
│ │ │ │ ├── PipelineChainFactory.kt
│ │ │ │ ├── PipelineHooks.kt
│ │ │ │ ├── PipelineOptions.kt
│ │ │ │ ├── Pipelines.kt
│ │ │ │ ├── error/
│ │ │ │ │ ├── BasePipelineErrorHandler.kt
│ │ │ │ │ ├── IOPipelineException.kt
│ │ │ │ │ ├── PipelineErrorHandler.kt
│ │ │ │ │ ├── PipelineException.kt
│ │ │ │ │ ├── StrictPipelineErrorHandler.kt
│ │ │ │ │ └── UnattachedPipelineException.kt
│ │ │ │ ├── output/
│ │ │ │ │ ├── ArtifactType.kt
│ │ │ │ │ ├── BinaryOutputArtifact.kt
│ │ │ │ │ ├── LazyOutputArtifact.kt
│ │ │ │ │ ├── OutputArtifact.kt
│ │ │ │ │ ├── OutputResource.kt
│ │ │ │ │ ├── OutputResourceGroup.kt
│ │ │ │ │ ├── OutputResourceVisitor.kt
│ │ │ │ │ ├── TextOutputArtifact.kt
│ │ │ │ │ └── visitor/
│ │ │ │ │ ├── CopyOutputResourceVisitor.kt
│ │ │ │ │ └── FileResourceExporter.kt
│ │ │ │ ├── stage/
│ │ │ │ │ ├── PeekPipelineStage.kt
│ │ │ │ │ ├── PipelineStage.kt
│ │ │ │ │ ├── PipelineStageChain.kt
│ │ │ │ │ └── SharedPipelineData.kt
│ │ │ │ └── stages/
│ │ │ │ ├── AfterAllRenderingPeek.kt
│ │ │ │ ├── AttachmentStage.kt
│ │ │ │ ├── AttributesUpdateStage.kt
│ │ │ │ ├── FunctionCallExpansionStage.kt
│ │ │ │ ├── LexingStage.kt
│ │ │ │ ├── LibrariesRegistrationStage.kt
│ │ │ │ ├── ParsingStage.kt
│ │ │ │ ├── PostRenderingStage.kt
│ │ │ │ ├── RenderingStage.kt
│ │ │ │ ├── ResourceGenerationStage.kt
│ │ │ │ └── TreeTraversalStage.kt
│ │ │ ├── property/
│ │ │ │ ├── AssociatedProperties.kt
│ │ │ │ ├── Property.kt
│ │ │ │ └── PropertyContainer.kt
│ │ │ ├── rendering/
│ │ │ │ ├── NodeRenderer.kt
│ │ │ │ ├── PostRenderer.kt
│ │ │ │ ├── RenderingComponents.kt
│ │ │ │ ├── UnsupportedRenderException.kt
│ │ │ │ ├── representable/
│ │ │ │ │ ├── RenderRepresentable.kt
│ │ │ │ │ └── RenderRepresentableVisitor.kt
│ │ │ │ └── tag/
│ │ │ │ ├── MultiTagBuilder.kt
│ │ │ │ ├── TagBuilder.kt
│ │ │ │ └── TagNodeRenderer.kt
│ │ │ ├── template/
│ │ │ │ └── TemplateProcessor.kt
│ │ │ ├── util/
│ │ │ │ ├── CollectionUtils.kt
│ │ │ │ ├── EnumUtils.kt
│ │ │ │ ├── EscapeUtils.kt
│ │ │ │ ├── IOUtils.kt
│ │ │ │ ├── RangeUtils.kt
│ │ │ │ ├── ScopedCounter.kt
│ │ │ │ ├── StringCase.kt
│ │ │ │ ├── StringUtils.kt
│ │ │ │ ├── URLUtils.kt
│ │ │ │ └── node/
│ │ │ │ ├── NodeUtils.kt
│ │ │ │ └── conversion/
│ │ │ │ └── list/
│ │ │ │ ├── MarkdownListConverter.kt
│ │ │ │ ├── MarkdownListToCollectionValue.kt
│ │ │ │ ├── MarkdownListToDictionaryValue.kt
│ │ │ │ ├── MarkdownListToIterable.kt
│ │ │ │ └── MarkdownListToList.kt
│ │ │ └── visitor/
│ │ │ ├── node/
│ │ │ │ └── NodeVisitor.kt
│ │ │ └── token/
│ │ │ ├── BlockTokenVisitor.kt
│ │ │ ├── InlineTokenVisitor.kt
│ │ │ ├── TokenVisitor.kt
│ │ │ └── TokenVisitorAdapter.kt
│ │ └── resources/
│ │ └── log4j2.xml
│ ├── test/
│ │ ├── kotlin/
│ │ │ └── com/
│ │ │ └── quarkdown/
│ │ │ └── core/
│ │ │ ├── AstDslTest.kt
│ │ │ ├── BibliographyCitationResolutionTest.kt
│ │ │ ├── BlockParserTest.kt
│ │ │ ├── ChildContextIsolationTest.kt
│ │ │ ├── ChildContextTest.kt
│ │ │ ├── CrossReferenceResolutionTest.kt
│ │ │ ├── CslBibliographyStyleTest.kt
│ │ │ ├── DocumentLayoutInfoTest.kt
│ │ │ ├── FileResourceExporterNameSanitizationTest.kt
│ │ │ ├── FontTest.kt
│ │ │ ├── FootnoteResolutionTest.kt
│ │ │ ├── FunctionNodeExpansionTest.kt
│ │ │ ├── GraphTest.kt
│ │ │ ├── InlineParserTest.kt
│ │ │ ├── LambdaTest.kt
│ │ │ ├── LexerTest.kt
│ │ │ ├── LocaleTest.kt
│ │ │ ├── LocalizationTest.kt
│ │ │ ├── MediaTest.kt
│ │ │ ├── MiscTest.kt
│ │ │ ├── NumberingFormatTest.kt
│ │ │ ├── NumberingTest.kt
│ │ │ ├── PipelineStageTest.kt
│ │ │ ├── PropertiesTest.kt
│ │ │ ├── StandaloneFunctionTest.kt
│ │ │ ├── SubdocumentRegistrationTest.kt
│ │ │ ├── TableOfContentsTest.kt
│ │ │ ├── TemplateProcessorTest.kt
│ │ │ ├── TreeTraversalTest.kt
│ │ │ ├── ValueFactoryTest.kt
│ │ │ └── util/
│ │ │ └── ScopedCounterTest.kt
│ │ └── resources/
│ │ ├── bib/
│ │ │ ├── article.bib
│ │ │ ├── bibliography.bib
│ │ │ ├── book.bib
│ │ │ ├── misc.bib
│ │ │ └── online.bib
│ │ ├── function/
│ │ │ └── hello.txt
│ │ ├── lexing/
│ │ │ ├── blocks.md
│ │ │ ├── comment.md
│ │ │ ├── emphasis.md
│ │ │ ├── entity.md
│ │ │ ├── escape.md
│ │ │ ├── inline.md
│ │ │ ├── inlinefunction.md
│ │ │ ├── linebreak.md
│ │ │ └── textreplacement.md
│ │ ├── parsing/
│ │ │ ├── blockcode.md
│ │ │ ├── blockquote.md
│ │ │ ├── fencescode.md
│ │ │ ├── figure.md
│ │ │ ├── footnotedefinition.md
│ │ │ ├── functioncall-chain.md
│ │ │ ├── functioncall.md
│ │ │ ├── heading.md
│ │ │ ├── hr.md
│ │ │ ├── inline/
│ │ │ │ ├── codespan.md
│ │ │ │ ├── emphasis.md
│ │ │ │ ├── entity.md
│ │ │ │ ├── escape.md
│ │ │ │ ├── image.md
│ │ │ │ ├── link.md
│ │ │ │ ├── mathspan.md
│ │ │ │ ├── reffootnote-all-in-one.md
│ │ │ │ ├── reffootnote.md
│ │ │ │ ├── refimage.md
│ │ │ │ ├── reflink.md
│ │ │ │ ├── strikethrough.md
│ │ │ │ ├── strong.md
│ │ │ │ ├── strongemphasis.md
│ │ │ │ └── subdocumentlink.md
│ │ │ ├── linkdefinition.md
│ │ │ ├── math_multiline.md
│ │ │ ├── math_oneline.md
│ │ │ ├── orderedlist.md
│ │ │ ├── pagebreak.md
│ │ │ ├── paragraph.md
│ │ │ ├── setextheading.md
│ │ │ ├── table.md
│ │ │ └── unorderedlist.md
│ │ ├── subdoc/
│ │ │ ├── subdoc-1.qd
│ │ │ └── subdoc-2.qd
│ │ └── template/
│ │ └── template.jte
│ └── testFixtures/
│ └── kotlin/
│ └── com/
│ └── quarkdown/
│ └── core/
│ └── TestUtils.kt
├── quarkdown-html/
│ ├── .gitignore
│ ├── README.md
│ ├── build.gradle.kts
│ ├── package.json
│ ├── playwright.config.ts
│ ├── src/
│ │ ├── main/
│ │ │ ├── kotlin/
│ │ │ │ └── com/
│ │ │ │ └── quarkdown/
│ │ │ │ └── rendering/
│ │ │ │ └── html/
│ │ │ │ ├── HtmlIdentifierProvider.kt
│ │ │ │ ├── HtmlTagBuilder.kt
│ │ │ │ ├── css/
│ │ │ │ │ ├── CssBuilder.kt
│ │ │ │ │ ├── CssPageSelectors.kt
│ │ │ │ │ ├── CssRepresentableVisitor.kt
│ │ │ │ │ └── StylesheetBuilder.kt
│ │ │ │ ├── extension/
│ │ │ │ │ ├── HtmlRendererExtension.kt
│ │ │ │ │ └── HtmlRendererFactoryVisitor.kt
│ │ │ │ ├── node/
│ │ │ │ │ ├── BaseHtmlNodeRenderer.kt
│ │ │ │ │ ├── QuarkdownHtmlNodeRenderer.kt
│ │ │ │ │ └── SidebarRenderer.kt
│ │ │ │ ├── pdf/
│ │ │ │ │ ├── HtmlPdfExportOptions.kt
│ │ │ │ │ ├── HtmlPdfExporter.kt
│ │ │ │ │ ├── PdfHtmlPostRendererDecorator.kt
│ │ │ │ │ ├── PuppeteerNodeModule.kt
│ │ │ │ │ └── PuppeteerPdfGeneratorScript.kt
│ │ │ │ ├── post/
│ │ │ │ │ ├── HtmlOnlyPostRenderer.kt
│ │ │ │ │ ├── HtmlPostRenderer.kt
│ │ │ │ │ ├── HtmlSubdocumentPostRenderer.kt
│ │ │ │ │ ├── document/
│ │ │ │ │ │ ├── CssFontFacesImporter.kt
│ │ │ │ │ │ ├── HtmlDocumentBuilder.kt
│ │ │ │ │ │ └── HtmlDocumentStylesheet.kt
│ │ │ │ │ └── resources/
│ │ │ │ │ ├── MediaPostRendererResource.kt
│ │ │ │ │ ├── PostRendererResource.kt
│ │ │ │ │ ├── ProxiedPostRendererResource.kt
│ │ │ │ │ ├── ScriptPostRendererResource.kt
│ │ │ │ │ ├── SearchIndexPostRendererResource.kt
│ │ │ │ │ └── ThemePostRendererResource.kt
│ │ │ │ └── search/
│ │ │ │ ├── SearchIndex.kt
│ │ │ │ └── SearchIndexGenerator.kt
│ │ │ ├── resources/
│ │ │ │ └── pdf/
│ │ │ │ └── pdf.js
│ │ │ ├── scss/
│ │ │ │ ├── color/
│ │ │ │ │ ├── beaver.scss
│ │ │ │ │ ├── darko.scss
│ │ │ │ │ ├── galactic.scss
│ │ │ │ │ └── paperwhite.scss
│ │ │ │ ├── components/
│ │ │ │ │ ├── _alignment.scss
│ │ │ │ │ ├── _bibliography.scss
│ │ │ │ │ ├── _block.scss
│ │ │ │ │ ├── _blockquote.scss
│ │ │ │ │ ├── _box.scss
│ │ │ │ │ ├── _clip.scss
│ │ │ │ │ ├── _code.scss
│ │ │ │ │ ├── _collapsible.scss
│ │ │ │ │ ├── _container.scss
│ │ │ │ │ ├── _docs.scss
│ │ │ │ │ ├── _empty.scss
│ │ │ │ │ ├── _figure.scss
│ │ │ │ │ ├── _filetree.scss
│ │ │ │ │ ├── _float.scss
│ │ │ │ │ ├── _focus.scss
│ │ │ │ │ ├── _font.scss
│ │ │ │ │ ├── _footnote.scss
│ │ │ │ │ ├── _heading.scss
│ │ │ │ │ ├── _hr.scss
│ │ │ │ │ ├── _landscape.scss
│ │ │ │ │ ├── _link.scss
│ │ │ │ │ ├── _list.scss
│ │ │ │ │ ├── _location.scss
│ │ │ │ │ ├── _math.scss
│ │ │ │ │ ├── _mermaid.scss
│ │ │ │ │ ├── _multicolumn.scss
│ │ │ │ │ ├── _page-break.scss
│ │ │ │ │ ├── _page-margin.scss
│ │ │ │ │ ├── _paged.scss
│ │ │ │ │ ├── _paragraph.scss
│ │ │ │ │ ├── _search.scss
│ │ │ │ │ ├── _sidebar.scss
│ │ │ │ │ ├── _size.scss
│ │ │ │ │ ├── _smooth-scroll.scss
│ │ │ │ │ ├── _stack.scss
│ │ │ │ │ ├── _table.scss
│ │ │ │ │ ├── _toc.scss
│ │ │ │ │ ├── _viewport.scss
│ │ │ │ │ └── util/
│ │ │ │ │ ├── _heading-selectors.scss
│ │ │ │ │ ├── _icon.scss
│ │ │ │ │ ├── _location-selectors.scss
│ │ │ │ │ ├── _media-queries.scss
│ │ │ │ │ └── _misc-selectors.scss
│ │ │ │ ├── global.scss
│ │ │ │ ├── layout/
│ │ │ │ │ ├── beamer.scss
│ │ │ │ │ ├── hyperlegible.scss
│ │ │ │ │ ├── latex.scss
│ │ │ │ │ ├── minimal.scss
│ │ │ │ │ └── util/
│ │ │ │ │ ├── _beamer-toc.scss
│ │ │ │ │ ├── _docs-headings-border.scss
│ │ │ │ │ ├── _docs-navigation.scss
│ │ │ │ │ ├── _gh-tables.scss
│ │ │ │ │ ├── _latex-tables.scss
│ │ │ │ │ ├── _latex-toc.scss
│ │ │ │ │ ├── _minimal-footer.scss
│ │ │ │ │ ├── _minimal-tables.scss
│ │ │ │ │ ├── _minimal-toc.scss
│ │ │ │ │ ├── _progressive-heading-margins.scss
│ │ │ │ │ └── _progressive-heading-sizes.scss
│ │ │ │ └── locale/
│ │ │ │ └── zh.scss
│ │ │ └── typescript/
│ │ │ ├── capabilities.ts
│ │ │ ├── chunker/
│ │ │ │ └── page-chunker.ts
│ │ │ ├── document/
│ │ │ │ ├── __tests__/
│ │ │ │ │ └── document-handler.spec.ts
│ │ │ │ ├── document-handler.ts
│ │ │ │ ├── global-handlers.ts
│ │ │ │ ├── handlers/
│ │ │ │ │ ├── __tests__/
│ │ │ │ │ │ ├── code-highlighter.spec.ts
│ │ │ │ │ │ ├── footnotes-document-handler.spec.ts
│ │ │ │ │ │ ├── inline-collapsibles.spec.ts
│ │ │ │ │ │ ├── math-renderer.spec.ts
│ │ │ │ │ │ ├── mermaid-renderer.spec.ts
│ │ │ │ │ │ ├── page-margins-docs.spec.ts
│ │ │ │ │ │ ├── page-margins-document-handler.spec.ts
│ │ │ │ │ │ ├── page-numbers-document-handler.spec.ts
│ │ │ │ │ │ ├── persistent-headings.spec.ts
│ │ │ │ │ │ └── remaining-height.spec.ts
│ │ │ │ │ ├── capabilities/
│ │ │ │ │ │ ├── code-highlighter.ts
│ │ │ │ │ │ ├── math-renderer.ts
│ │ │ │ │ │ └── mermaid-renderer.ts
│ │ │ │ │ ├── docs/
│ │ │ │ │ │ ├── __tests__/
│ │ │ │ │ │ │ └── sibling-pages-buttons.spec.ts
│ │ │ │ │ │ ├── page-list-autoscroll.ts
│ │ │ │ │ │ ├── search-field-focus.ts
│ │ │ │ │ │ ├── search-field.ts
│ │ │ │ │ │ ├── sibling-pages-buttons.ts
│ │ │ │ │ │ ├── toc-active-tracking.ts
│ │ │ │ │ │ └── util/
│ │ │ │ │ │ ├── __tests__/
│ │ │ │ │ │ │ └── page-list-analyzer.spec.ts
│ │ │ │ │ │ └── page-list-analyzer.ts
│ │ │ │ │ ├── footnotes/
│ │ │ │ │ │ ├── footnotes-docs.ts
│ │ │ │ │ │ ├── footnotes-document-handler.ts
│ │ │ │ │ │ ├── footnotes-paged.ts
│ │ │ │ │ │ ├── footnotes-plain.ts
│ │ │ │ │ │ └── footnotes-slides.ts
│ │ │ │ │ ├── inline-collapsibles.ts
│ │ │ │ │ ├── landscape-size-swapper.ts
│ │ │ │ │ ├── page-margins/
│ │ │ │ │ │ ├── page-margins-docs.ts
│ │ │ │ │ │ ├── page-margins-document-handler.ts
│ │ │ │ │ │ ├── page-margins-paged.ts
│ │ │ │ │ │ └── page-margins-slides.ts
│ │ │ │ │ ├── page-numbers.ts
│ │ │ │ │ ├── paged/
│ │ │ │ │ │ └── split-code-blocks-fix-paged.ts
│ │ │ │ │ ├── persistent-headings.ts
│ │ │ │ │ ├── remaining-height.ts
│ │ │ │ │ ├── show-on-ready.ts
│ │ │ │ │ └── sidebar.ts
│ │ │ │ ├── paged-like-quarkdown-document.ts
│ │ │ │ ├── quarkdown-document.ts
│ │ │ │ └── type/
│ │ │ │ ├── docs-document.ts
│ │ │ │ ├── paged-document.ts
│ │ │ │ ├── plain-document.ts
│ │ │ │ └── slides-document.ts
│ │ │ ├── footnotes/
│ │ │ │ ├── footnote-dom.ts
│ │ │ │ ├── footnote-lookup.ts
│ │ │ │ └── footnote-pair.ts
│ │ │ ├── index.ts
│ │ │ ├── live/
│ │ │ │ └── live-preview.ts
│ │ │ ├── navigation/
│ │ │ │ └── active-tracking.ts
│ │ │ ├── queue/
│ │ │ │ ├── async-execution-queue.ts
│ │ │ │ └── execution-queues.ts
│ │ │ ├── search/
│ │ │ │ ├── __tests__/
│ │ │ │ │ ├── search-highlight.spec.ts
│ │ │ │ │ ├── search-result-expander.spec.ts
│ │ │ │ │ ├── search-result-renderer.spec.ts
│ │ │ │ │ └── search.spec.ts
│ │ │ │ ├── search-highlight.ts
│ │ │ │ ├── search-result-expander.ts
│ │ │ │ ├── search-result-renderer.ts
│ │ │ │ └── search.ts
│ │ │ ├── types/
│ │ │ │ └── pagedjs.d.ts
│ │ │ └── util/
│ │ │ ├── __tests__/
│ │ │ │ ├── escape.spec.ts
│ │ │ │ └── page-number.spec.ts
│ │ │ ├── browser.ts
│ │ │ ├── escape.ts
│ │ │ ├── hash.ts
│ │ │ ├── id.ts
│ │ │ ├── meta.ts
│ │ │ ├── numbering.ts
│ │ │ └── visibility.ts
│ │ └── test/
│ │ ├── e2e/
│ │ │ ├── __util/
│ │ │ │ ├── compile.ts
│ │ │ │ ├── css.ts
│ │ │ │ ├── free-port.ts
│ │ │ │ ├── global-setup.ts
│ │ │ │ ├── global-teardown.ts
│ │ │ │ ├── live-preview-runner.ts
│ │ │ │ ├── paths.ts
│ │ │ │ └── runner.ts
│ │ │ ├── alerts/
│ │ │ │ ├── box/
│ │ │ │ │ ├── box.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ └── quote/
│ │ │ │ ├── main.qd
│ │ │ │ └── quote.spec.ts
│ │ │ ├── alignment/
│ │ │ │ ├── container/
│ │ │ │ │ ├── container.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ └── doctype/
│ │ │ │ ├── doctype.spec.ts
│ │ │ │ └── main.qd
│ │ │ ├── captions/
│ │ │ │ ├── customized/
│ │ │ │ │ ├── customized.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ ├── default/
│ │ │ │ │ ├── default.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ └── index.ts
│ │ │ ├── code/
│ │ │ │ ├── caption/
│ │ │ │ │ ├── caption.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ ├── default/
│ │ │ │ │ ├── default.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ ├── focus/
│ │ │ │ │ ├── focus.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ ├── no-line-numbers/
│ │ │ │ │ ├── main.qd
│ │ │ │ │ └── no-line-numbers.spec.ts
│ │ │ │ ├── numbered/
│ │ │ │ │ ├── main.qd
│ │ │ │ │ └── numbered.spec.ts
│ │ │ │ └── page-split/
│ │ │ │ ├── main.qd
│ │ │ │ └── page-split.spec.ts
│ │ │ ├── colors/
│ │ │ │ ├── colors.spec.ts
│ │ │ │ └── main.qd
│ │ │ ├── cross-reference/
│ │ │ │ ├── default/
│ │ │ │ │ ├── default.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ └── localized/
│ │ │ │ ├── localized.spec.ts
│ │ │ │ └── main.qd
│ │ │ ├── css/
│ │ │ │ ├── properties/
│ │ │ │ │ ├── main.qd
│ │ │ │ │ └── properties.spec.ts
│ │ │ │ └── raw/
│ │ │ │ ├── main.qd
│ │ │ │ └── raw.spec.ts
│ │ │ ├── docs/
│ │ │ │ ├── content-width/
│ │ │ │ │ ├── content-width.spec.ts
│ │ │ │ │ ├── long-code.qd
│ │ │ │ │ ├── main.qd
│ │ │ │ │ └── simple.qd
│ │ │ │ ├── layout/
│ │ │ │ │ ├── layout.spec.ts
│ │ │ │ │ ├── main.qd
│ │ │ │ │ └── scroll.spec.ts
│ │ │ │ ├── lib/
│ │ │ │ │ ├── customization/
│ │ │ │ │ │ ├── _nav.qd
│ │ │ │ │ │ ├── _setup.qd
│ │ │ │ │ │ ├── main.qd
│ │ │ │ │ │ ├── page-1.qd
│ │ │ │ │ │ └── structure.spec.ts
│ │ │ │ │ └── default/
│ │ │ │ │ ├── _nav.qd
│ │ │ │ │ ├── _setup.qd
│ │ │ │ │ ├── main.qd
│ │ │ │ │ ├── nested/
│ │ │ │ │ │ └── nested-page.qd
│ │ │ │ │ ├── page-1.qd
│ │ │ │ │ ├── page-2.qd
│ │ │ │ │ └── structure.spec.ts
│ │ │ │ ├── long-pagelist/
│ │ │ │ │ ├── autoscroll.spec.ts
│ │ │ │ │ ├── main.qd
│ │ │ │ │ └── page.qd
│ │ │ │ └── multi-page/
│ │ │ │ ├── main.qd
│ │ │ │ ├── page-1.qd
│ │ │ │ ├── page-2.qd
│ │ │ │ ├── page-3.qd
│ │ │ │ ├── pagelist.spec.ts
│ │ │ │ ├── setup.qd
│ │ │ │ ├── sibling-pages.spec.ts
│ │ │ │ ├── toc-active-tracking.spec.ts
│ │ │ │ └── toc.spec.ts
│ │ │ ├── doctype/
│ │ │ │ ├── default/
│ │ │ │ │ ├── default.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ └── responsiveness/
│ │ │ │ ├── main.qd
│ │ │ │ └── responsiveness.spec.ts
│ │ │ ├── filetree/
│ │ │ │ ├── filetree.spec.ts
│ │ │ │ └── main.qd
│ │ │ ├── font/
│ │ │ │ ├── customization-full/
│ │ │ │ │ ├── customization-full.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ ├── customization-localized/
│ │ │ │ │ ├── customization-localized.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ ├── customization-minimal-no-headings/
│ │ │ │ │ ├── customization-minimal-no-headings.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ ├── customization-minimal-on-headings/
│ │ │ │ │ ├── customization-minimal-on-headings.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ ├── default/
│ │ │ │ │ ├── default.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ ├── index.ts
│ │ │ │ └── localized-default/
│ │ │ │ ├── localized-default.spec.ts
│ │ │ │ └── main.qd
│ │ │ ├── footnote/
│ │ │ │ ├── multiple/
│ │ │ │ │ ├── main.qd
│ │ │ │ │ └── multiple.spec.ts
│ │ │ │ └── single/
│ │ │ │ ├── main.qd
│ │ │ │ └── single.spec.ts
│ │ │ ├── hr/
│ │ │ │ ├── hr.spec.ts
│ │ │ │ └── main.qd
│ │ │ ├── icon/
│ │ │ │ ├── icon.spec.ts
│ │ │ │ └── main.qd
│ │ │ ├── list/
│ │ │ │ ├── issue_customization-not-affecting-list/
│ │ │ │ │ ├── bulletin.yml
│ │ │ │ │ ├── customization-not-affecting-list.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ └── issue_overjustified-list-in-page-break/
│ │ │ │ ├── bulletin.yml
│ │ │ │ ├── main.qd
│ │ │ │ └── overjustified-list-in-page-break.spec.ts
│ │ │ ├── live-preview/
│ │ │ │ ├── live-preview.spec.ts
│ │ │ │ ├── main.qd
│ │ │ │ └── sub.qd
│ │ │ ├── margin-reset/
│ │ │ │ └── first-in-page/
│ │ │ │ ├── first-in-page.spec.ts
│ │ │ │ └── main.qd
│ │ │ ├── math/
│ │ │ │ ├── issue_misaligned-in-block/
│ │ │ │ │ ├── bulletin.yml
│ │ │ │ │ ├── main.qd
│ │ │ │ │ └── misaligned-in-parent.spec.ts
│ │ │ │ ├── issue_paged-overflow/
│ │ │ │ │ ├── bulletin.yml
│ │ │ │ │ ├── issue_paged-overflow.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ ├── main.qd
│ │ │ │ └── math.spec.ts
│ │ │ ├── media/
│ │ │ │ ├── main.qd
│ │ │ │ └── media.spec.ts
│ │ │ ├── mermaid/
│ │ │ │ ├── class/
│ │ │ │ │ ├── class.mmd
│ │ │ │ │ ├── class.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ ├── index.ts
│ │ │ │ ├── pie/
│ │ │ │ │ ├── main.qd
│ │ │ │ │ ├── pie.mmd
│ │ │ │ │ └── pie.spec.ts
│ │ │ │ └── xy/
│ │ │ │ ├── main.qd
│ │ │ │ └── xy.spec.ts
│ │ │ ├── multicolumn/
│ │ │ │ ├── all-columns-by-page-fill/
│ │ │ │ │ ├── all-columns-by-page-fill.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ ├── full-span/
│ │ │ │ │ ├── full-span.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ └── only-first-column/
│ │ │ │ ├── main.qd
│ │ │ │ └── only-first-column.spec.ts
│ │ │ ├── numbering/
│ │ │ │ ├── default/
│ │ │ │ │ ├── default.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ └── localized/
│ │ │ │ ├── localized.spec.ts
│ │ │ │ └── main.qd
│ │ │ ├── page-break/
│ │ │ │ ├── main.qd
│ │ │ │ └── page-break.spec.ts
│ │ │ ├── page-format/
│ │ │ │ ├── alignment-global/
│ │ │ │ │ ├── alignment-global.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ ├── alignment-local/
│ │ │ │ │ ├── alignment-local.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ ├── border/
│ │ │ │ │ ├── border.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ ├── index.ts
│ │ │ │ ├── margins/
│ │ │ │ │ ├── main.qd
│ │ │ │ │ └── margins.spec.ts
│ │ │ │ ├── scoped/
│ │ │ │ │ ├── range/
│ │ │ │ │ │ ├── main.qd
│ │ │ │ │ │ └── range.spec.ts
│ │ │ │ │ ├── range-side/
│ │ │ │ │ │ ├── main.qd
│ │ │ │ │ │ └── range-side.spec.ts
│ │ │ │ │ └── side/
│ │ │ │ │ ├── main.qd
│ │ │ │ │ └── side.spec.ts
│ │ │ │ └── size/
│ │ │ │ ├── format/
│ │ │ │ │ ├── format.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ ├── format-and-width/
│ │ │ │ │ ├── format-and-width.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ ├── height/
│ │ │ │ │ ├── height.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ ├── width/
│ │ │ │ │ ├── main.qd
│ │ │ │ │ └── width.spec.ts
│ │ │ │ └── width-and-height/
│ │ │ │ ├── main.qd
│ │ │ │ └── width-and-height.spec.ts
│ │ │ ├── page-margins/
│ │ │ │ ├── all-pages/
│ │ │ │ │ ├── all-pages.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ ├── format-page-numbers/
│ │ │ │ │ ├── format-page-numbers.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ ├── index.ts
│ │ │ │ ├── mirror/
│ │ │ │ │ ├── main.qd
│ │ │ │ │ └── mirror.spec.ts
│ │ │ │ ├── page-counter/
│ │ │ │ │ ├── main.qd
│ │ │ │ │ └── page-counter.spec.ts
│ │ │ │ ├── persistent-headings/
│ │ │ │ │ ├── main.qd
│ │ │ │ │ └── persistent-headings.spec.ts
│ │ │ │ └── scoped/
│ │ │ │ ├── main.qd
│ │ │ │ └── scoped.spec.ts
│ │ │ ├── paragraph/
│ │ │ │ ├── customization/
│ │ │ │ │ ├── customization.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ ├── localized-configuration/
│ │ │ │ │ ├── localized-configuration.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ ├── spacing/
│ │ │ │ │ ├── base/
│ │ │ │ │ │ ├── base.spec.ts
│ │ │ │ │ │ └── main.qd
│ │ │ │ │ ├── with-container/
│ │ │ │ │ │ ├── main.qd
│ │ │ │ │ │ └── with-container.spec.ts
│ │ │ │ │ └── with-float/
│ │ │ │ │ ├── main.qd
│ │ │ │ │ └── with-float.spec.ts
│ │ │ │ └── typography/
│ │ │ │ ├── main.qd
│ │ │ │ └── typography.spec.ts
│ │ │ ├── quarkdown.ts
│ │ │ ├── sidebar/
│ │ │ │ ├── empty/
│ │ │ │ │ ├── empty.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ ├── issue_border-in-minimal-theme/
│ │ │ │ │ ├── border-in-minimal-theme.spec.ts
│ │ │ │ │ ├── bulletin.yml
│ │ │ │ │ └── main.qd
│ │ │ │ ├── main.qd
│ │ │ │ └── sidebar.spec.ts
│ │ │ ├── slides/
│ │ │ │ └── chunking/
│ │ │ │ ├── chunking.spec.ts
│ │ │ │ └── main.qd
│ │ │ ├── stack/
│ │ │ │ ├── default/
│ │ │ │ │ ├── default.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ ├── gap/
│ │ │ │ │ ├── gap.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ ├── grid-row-column-gap/
│ │ │ │ │ ├── grid-row-column-gap.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ └── index.ts
│ │ │ ├── text-formatting/
│ │ │ │ ├── case/
│ │ │ │ │ ├── case.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ ├── decoration/
│ │ │ │ │ ├── decoration.spec.ts
│ │ │ │ │ └── main.qd
│ │ │ │ ├── size/
│ │ │ │ │ ├── main.qd
│ │ │ │ │ └── size.spec.ts
│ │ │ │ ├── style/
│ │ │ │ │ ├── main.qd
│ │ │ │ │ └── style.spec.ts
│ │ │ │ ├── variant/
│ │ │ │ │ ├── main.qd
│ │ │ │ │ └── variant.spec.ts
│ │ │ │ └── weight/
│ │ │ │ ├── main.qd
│ │ │ │ └── weight.spec.ts
│ │ │ └── toc/
│ │ │ ├── format-page-numbers/
│ │ │ │ ├── format-page-numbers.spec.ts
│ │ │ │ └── main.qd
│ │ │ ├── index.ts
│ │ │ ├── latex/
│ │ │ │ ├── latex.spec.ts
│ │ │ │ └── main.qd
│ │ │ ├── minimal/
│ │ │ │ ├── main.qd
│ │ │ │ └── minimal.spec.ts
│ │ │ └── page-numbers/
│ │ │ ├── main.qd
│ │ │ └── page-numbers.spec.ts
│ │ ├── kotlin/
│ │ │ └── com/
│ │ │ └── quarkdown/
│ │ │ └── rendering/
│ │ │ └── html/
│ │ │ ├── HtmlIdentifiersTest.kt
│ │ │ ├── HtmlNodeRendererTest.kt
│ │ │ ├── HtmlPostRendererTest.kt
│ │ │ ├── HtmlSecurityTest.kt
│ │ │ ├── HtmlToPdfTest.kt
│ │ │ ├── MediaTest.kt
│ │ │ ├── SearchIndexGeneratorTest.kt
│ │ │ └── SidebarRendererTest.kt
│ │ └── resources/
│ │ ├── issues/
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── data/
│ │ │ │ └── bibliography/
│ │ │ │ └── bibliography.bib
│ │ │ ├── landscape.qd
│ │ │ ├── math-page-overflow.qd
│ │ │ ├── mermaid-size.qd
│ │ │ ├── mirrored-bibliography.qd
│ │ │ ├── misaligned-math-fraction.qd
│ │ │ ├── misaligned-math-in-box.qd
│ │ │ ├── misaligned-math-in-quote.qd
│ │ │ ├── multiple-font-configurations.qd
│ │ │ └── template/
│ │ │ └── template.qd
│ │ ├── media/
│ │ │ └── file.txt
│ │ └── rendering/
│ │ ├── block/
│ │ │ ├── blockquote.html
│ │ │ ├── code.html
│ │ │ ├── footnote.html
│ │ │ ├── heading.html
│ │ │ ├── math.html
│ │ │ ├── orderedlist.html
│ │ │ ├── paragraph.html
│ │ │ ├── table.html
│ │ │ └── unorderedlist.html
│ │ ├── inline/
│ │ │ ├── codespan.html
│ │ │ ├── emphasis.html
│ │ │ ├── image.html
│ │ │ ├── link.html
│ │ │ ├── math.html
│ │ │ ├── reffootnote.html
│ │ │ ├── refimage.html
│ │ │ ├── reflink.html
│ │ │ ├── strikethrough.html
│ │ │ ├── strong.html
│ │ │ └── strongemphasis.html
│ │ └── quarkdown/
│ │ ├── bibliography.html
│ │ ├── box.html
│ │ ├── clipped.html
│ │ ├── collapse.html
│ │ ├── container.html
│ │ ├── figure.html
│ │ ├── filetree.html
│ │ ├── fullspan.html
│ │ ├── inlinecollapse.html
│ │ ├── lastheading.html
│ │ ├── navigationcontainer.html
│ │ └── texttransform.html
│ ├── tsconfig.json
│ └── vitest.config.ts
├── quarkdown-interaction/
│ ├── README.md
│ ├── build.gradle.kts
│ └── src/
│ ├── main/
│ │ └── kotlin/
│ │ └── com/
│ │ └── quarkdown/
│ │ └── interaction/
│ │ ├── Env.kt
│ │ ├── executable/
│ │ │ ├── ExecutableWrapper.kt
│ │ │ ├── NodeJsWrapper.kt
│ │ │ ├── NodeModule.kt
│ │ │ ├── NodeNpmHelper.kt
│ │ │ ├── NpmWrapper.kt
│ │ │ └── WithDefaultPath.kt
│ │ └── os/
│ │ └── OsUtils.kt
│ └── test/
│ └── kotlin/
│ └── com/
│ └── quarkdown/
│ └── interaction/
│ └── NodeNpmWrapperTest.kt
├── quarkdown-libs/
│ ├── README.md
│ ├── build.gradle.kts
│ └── src/
│ └── main/
│ └── resources/
│ ├── docs.qd
│ └── paper.qd
├── quarkdown-lsp/
│ ├── LICENSE
│ ├── README.md
│ ├── build.gradle.kts
│ └── src/
│ ├── main/
│ │ └── kotlin/
│ │ └── com/
│ │ └── quarkdown/
│ │ └── lsp/
│ │ ├── QuarkdownLanguageServer.kt
│ │ ├── QuarkdownLanguageServerLauncher.kt
│ │ ├── QuarkdownTextDocumentService.kt
│ │ ├── QuarkdownWorkspaceService.kt
│ │ ├── TextDocument.kt
│ │ ├── cache/
│ │ │ ├── CacheableFunctionCatalogue.kt
│ │ │ ├── DocumentCache.kt
│ │ │ └── DocumentedFunction.kt
│ │ ├── completion/
│ │ │ ├── CompletionItemConverters.kt
│ │ │ ├── CompletionSupplier.kt
│ │ │ ├── CompletionSuppliersFactory.kt
│ │ │ └── function/
│ │ │ ├── AbstractFunctionCompletionSupplier.kt
│ │ │ ├── FunctionCallInsertionSnippet.kt
│ │ │ ├── name/
│ │ │ │ ├── ChainedFunctionNameCompletionSupplier.kt
│ │ │ │ ├── FunctionNameCompletionSupplier.kt
│ │ │ │ └── RegularFunctionNameCompletionSupplier.kt
│ │ │ └── parameter/
│ │ │ ├── FunctionParameterAllowedValuesCompletionSupplier.kt
│ │ │ └── FunctionParameterNameCompletionSupplier.kt
│ │ ├── diagnostics/
│ │ │ ├── AbstractFunctionCallDiagnosticsSupplier.kt
│ │ │ ├── DiagnosticsSupplier.kt
│ │ │ ├── DiagnosticsSuppliersFactory.kt
│ │ │ ├── SimpleDiagnostic.kt
│ │ │ ├── cause/
│ │ │ │ ├── DiagnosticCause.kt
│ │ │ │ ├── DuplicateParameterNameDiagnosticCause.kt
│ │ │ │ ├── UnallowedValueDiagnosticCause.kt
│ │ │ │ └── UnresolvedParameterNameDiagnosticCause.kt
│ │ │ └── function/
│ │ │ ├── FunctionDuplicateParameterNameDiagnosticsSupplier.kt
│ │ │ ├── FunctionParameterValueDiagnosticsSupplier.kt
│ │ │ └── FunctionUnresolvedParameterNameDiagnosticsSupplier.kt
│ │ ├── documentation/
│ │ │ ├── FunctionDocumentation.kt
│ │ │ └── HtmlToMarkdown.kt
│ │ ├── highlight/
│ │ │ ├── SemanticTokensEncoder.kt
│ │ │ ├── SemanticTokensSupplier.kt
│ │ │ ├── SemanticTokensSuppliersFactory.kt
│ │ │ ├── TokenData.kt
│ │ │ ├── TokenType.kt
│ │ │ └── function/
│ │ │ ├── FunctionCallTokensSupplier.kt
│ │ │ └── ValueQualifier.kt
│ │ ├── hover/
│ │ │ ├── HoverSupplier.kt
│ │ │ ├── HoverSuppliersFactory.kt
│ │ │ └── function/
│ │ │ └── FunctionDocumentationHoverSupplier.kt
│ │ ├── ontype/
│ │ │ ├── OnTypeFormattingEditSupplier.kt
│ │ │ ├── OnTypeFormattingSuppliersFactory.kt
│ │ │ └── TrailingSpacesRemoverOnTypeFormattingEditSupplier.kt
│ │ ├── pattern/
│ │ │ └── QuarkdownPatterns.kt
│ │ ├── subservices/
│ │ │ ├── CompletionSubservice.kt
│ │ │ ├── DiagnosticsSubservice.kt
│ │ │ ├── HoverSubservice.kt
│ │ │ ├── OnTypeFormattingSubservice.kt
│ │ │ ├── SemanticTokensSubservice.kt
│ │ │ └── TextDocumentSubservice.kt
│ │ ├── tokenizer/
│ │ │ ├── FunctionCall.kt
│ │ │ ├── FunctionCallTokenizer.kt
│ │ │ └── TokenSearch.kt
│ │ └── util/
│ │ ├── FunctionParameterLookupUtils.kt
│ │ ├── ParsingUtils.kt
│ │ └── PositionUtils.kt
│ └── test/
│ ├── kotlin/
│ │ └── com/
│ │ └── quarkdown/
│ │ └── lsp/
│ │ ├── DocumentCacheTest.kt
│ │ ├── FunctionCallTokenizerTest.kt
│ │ ├── FunctionCallTokensSupplierTest.kt
│ │ ├── FunctionCompletionSupplierTest.kt
│ │ ├── FunctionDocumentationHoverSupplierTest.kt
│ │ ├── HtmlToMarkdownTest.kt
│ │ ├── PositionTest.kt
│ │ ├── TrailingSpacesRemoverFormattingEditSupplierTest.kt
│ │ └── diagnostics/
│ │ ├── DiagnosticsTestUtils.kt
│ │ ├── FunctionDuplicateParameterNameDiagnosticsSupplierTest.kt
│ │ ├── FunctionParameterValueDiagnosticsSupplierTest.kt
│ │ └── FunctionUnresolvedParameterNameDiagnosticsSupplierTest.kt
│ └── resources/
│ ├── docs/
│ │ ├── com.quarkdown.stdlib.module.Data/
│ │ │ └── csv.html
│ │ └── com.quarkdown.stdlib.module.Layout/
│ │ ├── align.html
│ │ ├── clip.html
│ │ └── column.html
│ └── html-to-markdown/
│ ├── align.html
│ └── align.md
├── quarkdown-plaintext/
│ ├── README.md
│ ├── build.gradle.kts
│ └── src/
│ ├── main/
│ │ └── kotlin/
│ │ └── com/
│ │ └── quarkdown/
│ │ └── rendering/
│ │ └── plaintext/
│ │ ├── extension/
│ │ │ └── PlainTextRendererExtension.kt
│ │ ├── node/
│ │ │ └── PlainTextNodeRenderer.kt
│ │ └── post/
│ │ └── PlainTextPostRenderer.kt
│ └── test/
│ └── kotlin/
│ └── com/
│ └── quarkdown/
│ └── rendering/
│ └── plaintext/
│ ├── PlainTextNodeRendererTest.kt
│ └── PlainTextPostRendererTest.kt
├── quarkdown-quarkdoc/
│ ├── README.md
│ ├── build.gradle.kts
│ └── src/
│ ├── main/
│ │ ├── kotlin/
│ │ │ └── com/
│ │ │ └── quarkdown/
│ │ │ └── quarkdoc/
│ │ │ └── dokka/
│ │ │ ├── QuarkdocDokkaPlugin.kt
│ │ │ ├── kdoc/
│ │ │ │ ├── DeepDocumentationMapper.kt
│ │ │ │ ├── DocTagDsl.kt
│ │ │ │ ├── DocumentationMapper.kt
│ │ │ │ ├── DocumentationMapperDsl.kt
│ │ │ │ ├── DocumentationReferencesTransformer.kt
│ │ │ │ └── SimpleDocumentationMapper.kt
│ │ │ ├── page/
│ │ │ │ ├── DocumentTypeConstraintsPageTransformer.kt
│ │ │ │ ├── DocumentablePageTransformer.kt
│ │ │ │ ├── LikelyChainedPageTransformer.kt
│ │ │ │ ├── NewSectionDocumentablePageTransformer.kt
│ │ │ │ └── WikiLinkPageTransformer.kt
│ │ │ ├── signature/
│ │ │ │ ├── KotlinSignatureReflectionHelper.kt
│ │ │ │ ├── LineBreakingStrategy.kt
│ │ │ │ └── QuarkdownSignatureProvider.kt
│ │ │ ├── transformers/
│ │ │ │ ├── QuarkdocDocumentableReplacerTransformer.kt
│ │ │ │ ├── QuarkdocParameterDocumentationTransformer.kt
│ │ │ │ ├── enumeration/
│ │ │ │ │ ├── EnumParameterEntryListerTransformer.kt
│ │ │ │ │ ├── EnumStorage.kt
│ │ │ │ │ ├── EnumStorer.kt
│ │ │ │ │ ├── QuarkdocEnum.kt
│ │ │ │ │ └── adapters/
│ │ │ │ │ ├── DokkaEnumAdapter.kt
│ │ │ │ │ ├── QuarkdocEnumAdapters.kt
│ │ │ │ │ └── ReflectionEnumAdapter.kt
│ │ │ │ ├── misc/
│ │ │ │ │ └── DocumentTypeConstraintsTransformer.kt
│ │ │ │ ├── module/
│ │ │ │ │ ├── ModuleAsPackageTransformer.kt
│ │ │ │ │ ├── ModulesStorer.kt
│ │ │ │ │ └── QuarkdownModulesStorage.kt
│ │ │ │ ├── name/
│ │ │ │ │ ├── DocumentableNameTransformer.kt
│ │ │ │ │ ├── DocumentationNameTransformer.kt
│ │ │ │ │ ├── RenamingsStorage.kt
│ │ │ │ │ └── RenamingsStorer.kt
│ │ │ │ ├── optional/
│ │ │ │ │ └── AdditionalParameterPropertiesTransformer.kt
│ │ │ │ ├── suppress/
│ │ │ │ │ └── SuppressInjectedTransformer.kt
│ │ │ │ └── type/
│ │ │ │ └── ValueTypeTransformer.kt
│ │ │ └── util/
│ │ │ ├── Annotation.kt
│ │ │ ├── ContentBuilder.kt
│ │ │ ├── DocTagCopy.kt
│ │ │ ├── Dri.kt
│ │ │ ├── Enum.kt
│ │ │ ├── Extra.kt
│ │ │ ├── KDoc.kt
│ │ │ ├── Package.kt
│ │ │ ├── Scraping.kt
│ │ │ └── Source.kt
│ │ └── resources/
│ │ ├── META-INF/
│ │ │ └── services/
│ │ │ └── org.jetbrains.dokka.plugability.DokkaPlugin
│ │ └── styles/
│ │ └── stylesheet.css
│ └── test/
│ └── kotlin/
│ └── com/
│ └── quarkdown/
│ └── quarkdoc/
│ └── dokka/
│ ├── AdditionalParameterPropertiesTransformerTest.kt
│ ├── DocumentTypeConstraintsTransformerTest.kt
│ ├── EnumParameterEntryListerTransformerTest.kt
│ ├── LikelyChainedTransformerTest.kt
│ ├── ModuleTransformerTest.kt
│ ├── NameTransformerTest.kt
│ ├── QuarkdocDokkaTest.kt
│ ├── QuarkdownSignatureTest.kt
│ ├── SuppressInjectedTransformerTest.kt
│ ├── ValueTypeTransformerTest.kt
│ └── WikiLinkTransformerTest.kt
├── quarkdown-quarkdoc-reader/
│ ├── README.md
│ ├── build.gradle.kts
│ └── src/
│ ├── main/
│ │ └── kotlin/
│ │ └── com/
│ │ └── quarkdown/
│ │ └── quarkdoc/
│ │ └── reader/
│ │ ├── DocsContentExtractor.kt
│ │ ├── DocsFunction.kt
│ │ ├── DocsWalker.kt
│ │ ├── anchors/
│ │ │ ├── Anchors.kt
│ │ │ └── AnchorsHtml.kt
│ │ └── dokka/
│ │ ├── DokkaHtmlContentExtractor.kt
│ │ └── DokkaHtmlWalker.kt
│ └── test/
│ ├── kotlin/
│ │ └── com/
│ │ └── quarkdown/
│ │ └── quarkdoc/
│ │ └── reader/
│ │ └── DokkaReaderTest.kt
│ └── resources/
│ ├── content/
│ │ ├── capitalize.html
│ │ ├── container.html
│ │ ├── index.html
│ │ ├── isnone.html
│ │ ├── lowercase.html
│ │ └── uppercase.html
│ └── extract/
│ └── lowercase.html
├── quarkdown-server/
│ ├── README.md
│ ├── build.gradle.kts
│ └── src/
│ ├── main/
│ │ ├── kotlin/
│ │ │ └── com/
│ │ │ └── quarkdown/
│ │ │ └── server/
│ │ │ ├── LocalFileWebServer.kt
│ │ │ ├── Server.kt
│ │ │ ├── ServerEndpoints.kt
│ │ │ ├── ServerFreePortScanner.kt
│ │ │ ├── browser/
│ │ │ │ ├── BrowserLauncher.kt
│ │ │ │ ├── DefaultBrowserLauncher.kt
│ │ │ │ ├── EnvBrowserLauncher.kt
│ │ │ │ ├── NoneBrowserLauncher.kt
│ │ │ │ ├── PathBrowserLauncher.kt
│ │ │ │ └── XdgBrowserLauncher.kt
│ │ │ ├── endpoints/
│ │ │ │ ├── LivePreviewEndpoint.kt
│ │ │ │ └── ReloadEndpoint.kt
│ │ │ ├── message/
│ │ │ │ ├── ServerMessage.kt
│ │ │ │ └── ServerMessageSession.kt
│ │ │ └── stop/
│ │ │ ├── KtorStoppableAdapter.kt
│ │ │ └── Stoppable.kt
│ │ └── resources/
│ │ ├── live-preview/
│ │ │ └── wrapper.html.jte
│ │ └── simplelogger.properties
│ └── test/
│ ├── kotlin/
│ │ └── com/
│ │ └── quarkdown/
│ │ └── server/
│ │ ├── LivePreviewEndpointTest.kt
│ │ ├── LocalFileWebServerTest.kt
│ │ └── ServerFreePortScannerTest.kt
│ └── resources/
│ └── test.html
├── quarkdown-stdlib/
│ ├── build.gradle.kts
│ └── src/
│ ├── main/
│ │ ├── kotlin/
│ │ │ └── com/
│ │ │ └── quarkdown/
│ │ │ └── stdlib/
│ │ │ ├── Bibliography.kt
│ │ │ ├── Collection.kt
│ │ │ ├── Data.kt
│ │ │ ├── Dictionary.kt
│ │ │ ├── Document.kt
│ │ │ ├── Ecosystem.kt
│ │ │ ├── Emoji.kt
│ │ │ ├── Flow.kt
│ │ │ ├── Icon.kt
│ │ │ ├── Injection.kt
│ │ │ ├── Layout.kt
│ │ │ ├── Library.kt
│ │ │ ├── Localization.kt
│ │ │ ├── Logger.kt
│ │ │ ├── Logical.kt
│ │ │ ├── Math.kt
│ │ │ ├── Mermaid.kt
│ │ │ ├── MiscElements.kt
│ │ │ ├── Optionality.kt
│ │ │ ├── Primitives.kt
│ │ │ ├── Reference.kt
│ │ │ ├── Slides.kt
│ │ │ ├── Stdlib.kt
│ │ │ ├── String.kt
│ │ │ ├── TableComputation.kt
│ │ │ ├── Text.kt
│ │ │ ├── external/
│ │ │ │ └── QdLibraryExporter.kt
│ │ │ └── internal/
│ │ │ ├── Css.kt
│ │ │ ├── FileTree.kt
│ │ │ ├── Font.kt
│ │ │ ├── RootFileSystem.kt
│ │ │ ├── Sorting.kt
│ │ │ └── Types.kt
│ │ └── resources/
│ │ ├── lib/
│ │ │ └── localization.qd
│ │ └── text/
│ │ └── lorem-ipsum.txt
│ └── test/
│ ├── kotlin/
│ │ └── com/
│ │ └── quarkdown/
│ │ └── stdlib/
│ │ ├── DataTest.kt
│ │ ├── FileTreeTest.kt
│ │ ├── FlowTest.kt
│ │ ├── LocalizationTest.kt
│ │ ├── TextTest.kt
│ │ └── internal/
│ │ ├── CssTest.kt
│ │ └── SortingTest.kt
│ └── resources/
│ └── data/
│ ├── code.html
│ ├── drinks.csv
│ ├── listfiles/
│ │ ├── a.txt
│ │ ├── b.txt
│ │ ├── c.txt
│ │ └── d/
│ │ └── d.txt
│ ├── people.csv
│ └── test.txt
├── quarkdown-test/
│ ├── README.md
│ ├── build.gradle.kts
│ └── src/
│ └── test/
│ ├── kotlin/
│ │ └── com/
│ │ └── quarkdown/
│ │ └── test/
│ │ ├── BibliographyTest.kt
│ │ ├── BoxesTest.kt
│ │ ├── CaptionTest.kt
│ │ ├── CodeTest.kt
│ │ ├── CommentsTest.kt
│ │ ├── CrossReferenceTest.kt
│ │ ├── DocsLibraryTest.kt
│ │ ├── DocumentTest.kt
│ │ ├── EcosystemTest.kt
│ │ ├── EmojiTest.kt
│ │ ├── FileTreeTest.kt
│ │ ├── FontTest.kt
│ │ ├── FootnoteTest.kt
│ │ ├── FormatPageNumberTest.kt
│ │ ├── FunctionCallChainingTest.kt
│ │ ├── FunctionCallTest.kt
│ │ ├── HeadingTest.kt
│ │ ├── HtmlOutputResourceTest.kt
│ │ ├── IOTest.kt
│ │ ├── InjectionTest.kt
│ │ ├── IterableTest.kt
│ │ ├── LayoutTest.kt
│ │ ├── LinkTest.kt
│ │ ├── LocalizationTest.kt
│ │ ├── MathTest.kt
│ │ ├── MediaStorageTest.kt
│ │ ├── MermaidTest.kt
│ │ ├── NodesTest.kt
│ │ ├── NonStrictErrorHandlingTest.kt
│ │ ├── NumberingTest.kt
│ │ ├── OptionalityTest.kt
│ │ ├── PageBreakTest.kt
│ │ ├── PageMarginsTest.kt
│ │ ├── PaperLibTest.kt
│ │ ├── PersistentHeadingTest.kt
│ │ ├── ScriptingTest.kt
│ │ ├── SecurityTest.kt
│ │ ├── SidebarTest.kt
│ │ ├── StrictErrorHandlingTest.kt
│ │ ├── StringTest.kt
│ │ ├── SubdocumentTest.kt
│ │ ├── TableComputationTest.kt
│ │ ├── TableOfContentsTest.kt
│ │ ├── TablesTest.kt
│ │ ├── TextTest.kt
│ │ ├── UtilitiesTest.kt
│ │ └── util/
│ │ ├── Launcher.kt
│ │ ├── LibraryUtils.kt
│ │ └── OutputResourceUtils.kt
│ └── resources/
│ └── data/
│ ├── bib/
│ │ └── bibliography.bib
│ ├── code.txt
│ ├── css/
│ │ └── style.css
│ ├── csv/
│ │ ├── people.csv
│ │ ├── sales.csv
│ │ └── sums.csv
│ ├── include/
│ │ ├── absolute-image.md
│ │ ├── basic-source.md
│ │ ├── document-info-modification.md
│ │ ├── dynamic-value.md
│ │ ├── function-definition.md
│ │ ├── function-with-content.md
│ │ ├── mutable-data.md
│ │ ├── read-relative-path-in-scope.md
│ │ ├── read-relative-path.md
│ │ ├── reference-image.md
│ │ ├── relative-image.md
│ │ ├── shared-function-usage.md
│ │ ├── stdlib-call.md
│ │ ├── subdocument-linker.qd
│ │ ├── transitive-include.md
│ │ └── url-image.md
│ ├── libraries/
│ │ ├── content.qd
│ │ ├── file-reader.qd
│ │ └── hello.qd
│ ├── mermaid/
│ │ └── class.mmd
│ ├── search-index/
│ │ ├── search-index-no-headings-no-metadata.json
│ │ ├── search-index-no-headings-with-metadata.json
│ │ ├── search-index-with-headings.json
│ │ └── search-index-with-page-margin.json
│ └── subdoc/
│ ├── circular-1.qd
│ ├── circular-2.qd
│ ├── docs/
│ │ ├── _nav.qd
│ │ ├── _setup.qd
│ │ ├── page-1.qd
│ │ ├── page-2.qd
│ │ └── page-3.qd
│ ├── gateway.qd
│ ├── headings-1.qd
│ ├── headings-2.qd
│ ├── include-lib-1.qd
│ ├── include-lib-2.qd
│ ├── include-stdlib.qd
│ ├── media-storage.qd
│ ├── media.qd
│ ├── metadata.qd
│ ├── nav-includer.qd
│ ├── nav.qd
│ ├── path-to-root/
│ │ ├── subdoc/
│ │ │ └── subdoc.qd
│ │ └── utils/
│ │ └── path-to-root.qd
│ ├── recursive.qd
│ ├── simple-1.qd
│ ├── simple-2.qd
│ └── stdlib-call.qd
├── scripts/
│ ├── bootstrap.bat
│ └── bootstrap.sh
├── settings.gradle.kts
└── version.txt
================================================
FILE CONTENTS
================================================
================================================
FILE: .dockerignore
================================================
build/
================================================
FILE: .github/FUNDING.yml
================================================
github: iamgio
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.yml
================================================
name: Bug report
description: Report a bug or unexpected behavior
title: "[Bug] "
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to report a bug!
Please fill out the sections below so we can reproduce and fix the issue.
- type: checkboxes
id: checklist
attributes:
label: Before submitting
options:
- label: I am using the latest version of Quarkdown.
required: true
- label: I am using Java 17 or later (`java -version`).
required: true
- type: textarea
id: description
attributes:
label: Description
description: A clear and concise description of the bug.
placeholder: Describe what happened and what you expected to happen instead.
validations:
required: true
- type: textarea
id: input
attributes:
label: Input
description: The Quarkdown source that triggers the bug.
render: markdown
- type: textarea
id: output
attributes:
label: Actual output
description: The output you got (rendered result, error message, or stack trace).
- type: textarea
id: expected
attributes:
label: Expected output
description: What you expected to see instead.
- type: input
id: os
attributes:
label: Operating system
placeholder: e.g. macOS 15, Windows 11, Ubuntu 24.04
- type: textarea
id: additional-context
attributes:
label: Additional context
description: Any other context, screenshots, or information that might help.
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
- name: Question
url: https://github.com/iamgio/quarkdown/discussions/new/choose
about: Ask a question or start a discussion.
================================================
FILE: .github/ISSUE_TEMPLATE/enhancement.yml
================================================
name: Enhancement suggestion
description: Suggest a new feature or improvement
title: "[Enhancement] "
labels: ["enhancement"]
body:
- type: markdown
attributes:
value: |
Thanks for suggesting an enhancement!
Please describe your idea so we can evaluate it.
- type: checkboxes
id: checklist
attributes:
label: Before submitting
options:
- label: I am using the latest version of Quarkdown.
required: true
- label: I have checked the [wiki](https://quarkdown.com/wiki) to confirm this feature doesn't already exist.
required: true
- label: I have searched existing [issues](https://github.com/iamgio/quarkdown/issues) for duplicates.
required: true
- type: textarea
id: description
attributes:
label: Description
description: A clear and detailed description of the enhancement you'd like to see.
placeholder: What would you like to be added or changed?
validations:
required: true
- type: textarea
id: proposed-syntax
attributes:
label: Proposed syntax or behavior
description: If applicable, show how this feature might look in Quarkdown.
render: markdown
- type: textarea
id: additional-context
attributes:
label: Additional context
description: Any other context, motivation, screenshots, or information that might help.
================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
- [X] I confirm an issue for this change exists, and it was discussed with maintainers.
- [X] I have read the [contributing guidelines](https://github.com/iamgio/quarkdown/blob/main/CONTRIBUTING.md).
- [X] I have tested the changes locally.
- [ ] (Optional) I have added necessary documentation to [`docs`](https://github.com/iamgio/quarkdown/tree/main/docs) and [CHANGELOG.md](https://github.com/iamgio/quarkdown/blob/main/CHANGELOG.md)
================================================
FILE: .github/actions/bump-scoop/action.yml
================================================
name: "Bump Scoop Manifest"
description: "Update Scoop bucket manifest with a new version"
inputs:
version:
description: "Version string to update (e.g. 1.5.0)"
required: true
type: string
committer_token:
description: "Personal Access Token to push to the bucket"
required: true
type: string
runs:
using: composite
steps:
- name: Set version variable
run: |
VERSION="${{ inputs.version }}"
VERSION="${VERSION#v}"
echo "VERSION=$VERSION" >> $GITHUB_ENV
shell: bash
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y jq unzip curl
shell: bash
- name: Checkout Scoop bucket repo
uses: actions/checkout@v3
with:
repository: "quarkdown-labs/scoop-quarkdown"
token: ${{ inputs.committer_token }}
- name: Update manifest version and URL
run: |
jq --arg ver "$VERSION" \
'.version = $ver |
.url = "https://github.com/iamgio/quarkdown/releases/download/v" + $ver + "/quarkdown.zip"' \
bucket/quarkdown.json > bucket/tmp.json
mv bucket/tmp.json bucket/quarkdown.json
shell: bash
- name: Download release zip for checksum
run: |
curl -L -o quarkdown.zip "https://github.com/iamgio/quarkdown/releases/download/v$VERSION/quarkdown.zip"
shell: bash
- name: Calculate SHA256 checksum and update manifest
run: |
SHASUM=$(shasum -a 256 quarkdown.zip | cut -d " " -f 1)
jq --arg shasum "$SHASUM" '.hash = $shasum' bucket/quarkdown.json > bucket/tmp.json
mv bucket/tmp.json bucket/quarkdown.json
shell: bash
- name: Commit and push updated manifest
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add bucket/quarkdown.json
git diff --cached --quiet || git commit -m "Bump to $VERSION"
git push origin main
env:
GITHUB_TOKEN: ${{ inputs.committer_token }}
shell: bash
================================================
FILE: .github/actions/deploy-wiki/action.yml
================================================
name: Deploy Wiki
description: Builds and deploys the docs folder to the wiki directory of gh-pages
inputs:
quarkdown-path:
description: "Path to the Quarkdown executable"
required: true
github-token:
description: "GitHub token for deploying to gh-pages"
required: true
runs:
using: composite
steps:
- name: Build wiki documentation
run: |
cd docs
${{ inputs.quarkdown-path }} c main.qd --strict --clean --out-name wiki
shell: bash
- name: Deploy to gh-pages
uses: peaceiris/actions-gh-pages@v4
with:
personal_token: ${{ inputs.github-token }}
external_repository: quarkdown-labs/quarkdown.com
publish_dir: docs/output/wiki
destination_dir: wiki
================================================
FILE: .github/actions/setup-environment/action.yml
================================================
name: Quarkdown Environment Setup
description: Sets up Quarkdown execution environment
inputs:
full-checkout:
description: "If true, fetches full history and tags. Defaults to false."
required: false
default: 'false'
checkout-token:
description: "Token used to checkout the repository. Defaults to GITHUB_TOKEN."
required: false
default: ''
runs:
using: composite
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: ${{ inputs.full-checkout && '0' || '1' }}
fetch-tags: ${{ inputs.full-checkout }}
token: ${{ inputs.checkout-token != '' && inputs.checkout-token || github.token }}
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
- name: Setup Node.js
uses: actions/setup-node@v4
- name: Setup Chrome
uses: browser-actions/setup-chrome@v1
id: setup-chrome
- name: Set Puppeteer's executable path
run: |
echo "PUPPETEER_EXECUTABLE_PATH=${{ steps.setup-chrome.outputs.chrome-path }}" >> $GITHUB_ENV
shell: bash
- name: Set npm environment variables
run: |
mkdir -p $HOME/.npm-global/lib
echo "QD_NPM_PREFIX=$HOME/.npm-global/lib" >> $GITHUB_ENV
echo "NODE_PATH=$HOME/.npm-global/lib/node_modules" >> $GITHUB_ENV
shell: bash
- name: Install Puppeteer
run: |
export PUPPETEER_SKIP_DOWNLOAD=true
npm install puppeteer --prefix ${{ env.QD_NPM_PREFIX }}
shell: bash
================================================
FILE: .github/actions/update-emoji-list/action.yml
================================================
name: Update Emoji List
description: Generates emoji list using Quarkdown and commits it to the gh-pages-src branch
inputs:
quarkdown-path:
description: 'Path to the Quarkdown executable'
required: true
default: 'quarkdown'
runs:
using: composite
steps:
- name: Generate emoji list
run: ${{ inputs.quarkdown-path }} c .github/actions/update-emoji-list/generate.qd -o build/qd-ci --nowrap
shell: bash
- name: Setup gh-pages-src branch for emoji list commit
run: |
# Save the generated emoji list before switching branches
cp build/qd-ci/emoji-list/index.html /tmp/emoji-list.html
git stash || true
git fetch origin gh-pages-src
git checkout gh-pages-src
# Copy built emoji list to layout/docs/emoji-list.html, suitable for inclusion in Hugo site,
# prepending {{ define "main" }} and appending {{ end }} to the file.
{
echo '{{ define "main" }}'
cat /tmp/emoji-list.html
echo '{{ end }}'
} > layouts/docs/emoji-list.html
shell: bash
- name: Commit emoji list to gh-pages-src branch
uses: stefanzweifel/git-auto-commit-action@v7
with:
commit_message: "chore: update emoji list"
commit_user_name: "github-actions"
commit_user_email: "github-actions[bot]@users.noreply.github.com"
file_pattern: layouts/docs/emoji-list.html
================================================
FILE: .github/actions/update-emoji-list/generate.qd
================================================
.docname {emoji-list}
.var {headers}
- Emoji
- Code
.tablebyrows {.headers}
.foreach {.allemojis}
emoji code:
.pair {.emoji} {.code::codespan}
================================================
FILE: .github/workflows/deploy-wiki.yml
================================================
name: Deploy Wiki
on:
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: iamgio/quarkdown/.github/actions/setup-environment@main
- name: Build distribution
uses: burrunan/gradle-cache-action@v3
with:
job-id: main
arguments: installDist
- name: Deploy wiki
uses: iamgio/quarkdown/.github/actions/deploy-wiki@main
with:
quarkdown-path: ${{ github.workspace }}/build/install/quarkdown/bin/quarkdown
github-token: ${{ secrets.COMMITTER_TOKEN }}
================================================
FILE: .github/workflows/generate-pdf/color.txt
================================================
paperwhite
darko
beaver
galactic
================================================
FILE: .github/workflows/generate-pdf/generate-theme-combinations.js
================================================
const fs = require('fs');
const path = require('path');
const PROJECT_DIR = 'mock';
const MAIN_FILE = PROJECT_DIR + '/main.qd';
const WORKFLOW_DIR = '.github/workflows/generate-pdf';
const COLOR_FILE = WORKFLOW_DIR + '/color.txt';
const LAYOUT_FILE = WORKFLOW_DIR + '/layout.txt';
function getLines(file) {
return fs.readFileSync(file, 'utf8')
.split('\n')
.map(l => l.trim())
.filter(l => l.length > 0);
}
function createNewFileName(color, layout) {
return `generated_main_${color}_${layout}.qd`;
}
function generateThemeVariants() {
try {
const colors = getLines(COLOR_FILE);
const layouts = getLines(LAYOUT_FILE);
const mainContent = fs.readFileSync(MAIN_FILE, 'utf8');
// Generate all combinations
for (const color of colors) {
for (const layout of layouts) {
const newFile = `${PROJECT_DIR}/${createNewFileName(color, layout)}`;
// Create new content with theme line
const themeLine = `.theme color:{${color}} layout:{${layout}}`;
const newNameLine = `.docname {${color}_${layout}}`;
const newContent = mainContent + '\n\n' + newNameLine + '\n' + themeLine;
// Write to file
fs.writeFileSync(newFile, newContent);
console.log(`Created: ${newFile}`);
}
}
console.log(`Successfully generated ${colors.length * layouts.length} theme variants.`);
} catch (error) {
console.error('Error:', error.message);
process.exit(1);
}
}
generateThemeVariants();
================================================
FILE: .github/workflows/generate-pdf/layout.txt
================================================
latex
minimal
beamer
hyperlegible
================================================
FILE: .github/workflows/generate-pdf.yml
================================================
name: PDF generation via Puppeteer
on:
push:
tags: [ "v*" ]
paths-ignore:
- '*.md'
- '**/README.md'
- 'LICENSE'
- '.github/FUNDING.yml'
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: iamgio/quarkdown/.github/actions/setup-environment@main
- name: Setup Chrome
uses: browser-actions/setup-chrome@v1.7.3
id: setup-chrome
- name: Build distribution
uses: burrunan/gradle-cache-action@v3
with:
job-id: main
arguments: distZip
- name: Unzip distribution
run: unzip -q build/distributions/quarkdown.zip -d build/distributions/
- name: Setup staging directory
run: |
rm -rf pdf
mkdir -p pdf/mock
- name: Generate theme combinations
run: |
node .github/workflows/generate-pdf/generate-theme-combinations.js
- name: Compile Mock as PDF
run: |
for generated in $(ls mock/generated_*.qd); do
./build/distributions/quarkdown/bin/quarkdown c $generated -o pdf/mock --pdf --pdf-no-sandbox
done
ls -d $PWD/pdf/*
- name: Remove directories, keep files
run: |
rm -rf pdf/mock/*/
ls -d $PWD/pdf/*
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: mock-pdf
path: pdf/mock
- name: Push to generated repo
uses: cpina/github-action-push-to-another-repository@v1.7.2
env:
API_TOKEN_GITHUB: ${{ secrets.COMMITTER_TOKEN }}
with:
source-directory: pdf/mock
destination-github-username: quarkdown-labs
destination-repository-name: generated
target-directory: mock
commit-message: "Generate Mock PDF files from ${{ github.sha }}"
user-name: "github-actions[bot]"
user-email: "github-actions[bot]@users.noreply.github.com"
================================================
FILE: .github/workflows/gradle-deploy.yml
================================================
# This workflow will build the project with Gradle and release its build.
name: Gradle deploy
on:
push:
branches: [ "main", "workflow-test" ]
tags: [ "v*" ]
paths-ignore:
- '*.md'
- '**/README.md'
- 'LICENSE'
- '.github/ISSUE_TEMPLATE/**'
- '.github/FUNDING.yml'
jobs:
test:
uses: iamgio/quarkdown/.github/workflows/gradle-test.yml@main
build:
runs-on: ubuntu-latest
needs: [test]
steps:
- uses: iamgio/quarkdown/.github/actions/setup-environment@main
with:
full-checkout: true
checkout-token: ${{ secrets.COMMITTER_TOKEN }}
# Writes the new version (tag name without the leading 'v') to version.txt
- name: Bump version
if: github.ref_type == 'tag'
run: printf "%s" "${GITHUB_REF_NAME#v}" > version.txt
- name: Update changelog
uses: thomaseizinger/keep-a-changelog-new-release@v2
if: github.ref_type == 'tag'
with:
tag: ${{ github.ref_name }}
- name: Extract release notes
id: release-notes
if: github.ref_type == 'tag'
uses: ffurrer2/extract-release-notes@v3
- name: Commit release updates
uses: stefanzweifel/git-auto-commit-action@v7
if: github.ref_type == 'tag'
with:
commit_message: "chore: release ${{ github.ref_name }}"
commit_user_name: "github-actions"
commit_user_email: "github-actions[bot]@users.noreply.github.com"
file_pattern: version.txt CHANGELOG.md
branch: main
- name: Build distribution
uses: burrunan/gradle-cache-action@v3
with:
job-id: main
arguments: distZip
- name: Unzip distribution (keeping the zip file)
run: |
mkdir -p build/unzipped
unzip -q build/distributions/quarkdown.zip -d build/unzipped
echo "$PWD/build/unzipped/quarkdown/bin" >> $GITHUB_PATH
- name: Echo output files
run: ls -d "$PWD/build/"*
- name: Deploy wiki
if: github.ref_type == 'tag'
uses: iamgio/quarkdown/.github/actions/deploy-wiki@main
with:
quarkdown-path: ${{ github.workspace }}/build/unzipped/quarkdown/bin/quarkdown
github-token: ${{ secrets.COMMITTER_TOKEN }}
- name: Distribute artifact
uses: actions/upload-artifact@v4
with:
name: quarkdown
path: build/distributions/quarkdown.zip
- name: Move devbuild tag to latest commit
run: |
git tag -d latest || true
git tag -f latest
git push origin +latest
- name: Create devbuild release
uses: softprops/action-gh-release@v2.2.2
with:
token: "${{ secrets.GITHUB_TOKEN }}"
tag_name: "latest"
prerelease: true
generate_release_notes: true
name: Development build
files: build/distributions/quarkdown.zip
- name: Create release
uses: softprops/action-gh-release@v2
if: github.ref_type == 'tag'
with:
token: "${{ secrets.GITHUB_TOKEN }}"
body: ${{ steps.release-notes.outputs.release_notes }}
files: build/distributions/quarkdown.zip
- name: Generate docs
uses: burrunan/gradle-cache-action@v3
with:
job-id: main
arguments: quarkdocGenerateAll
- name: Deploy docs
uses: peaceiris/actions-gh-pages@v4
if: github.ref_type == 'tag'
with:
personal_token: ${{ secrets.COMMITTER_TOKEN }}
external_repository: quarkdown-labs/quarkdown.com
publish_dir: ./build/docs
destination_dir: docs
- name: Deploy devbuild docs
uses: peaceiris/actions-gh-pages@v4
with:
personal_token: ${{ secrets.COMMITTER_TOKEN }}
external_repository: quarkdown-labs/quarkdown.com
publish_dir: ./build/docs
destination_dir: docs/latest
# Bump Homebrew
- uses: mislav/bump-homebrew-formula-action@v3
if: github.ref_type == 'tag'
with:
formula-name: quarkdown
homebrew-tap: 'quarkdown-labs/homebrew-quarkdown'
download-url: "https://github.com/iamgio/quarkdown/releases/download/${{ github.ref_name }}/quarkdown.zip"
env:
COMMITTER_TOKEN: ${{ secrets.COMMITTER_TOKEN }}
# Bump Scoop
- uses: iamgio/quarkdown/.github/actions/bump-scoop@main
if: github.ref_type == 'tag'
with:
version: ${{ github.ref_name }}
committer_token: ${{ secrets.COMMITTER_TOKEN }}
dependency-submission:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
# Generates and submits a dependency graph, enabling Dependabot Alerts for all project dependencies.
# See: https://github.com/gradle/actions/blob/main/dependency-submission/README.md
- name: Generate and submit dependency graph
uses: gradle/actions/dependency-submission@v4
================================================
FILE: .github/workflows/gradle-test.yml
================================================
# This workflow will build the project with Gradle and release its build.
name: Gradle test
on:
workflow_call:
push:
branches-ignore: [ "main", "workflow-test" ]
pull_request:
jobs:
unit-test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
steps:
- uses: iamgio/quarkdown/.github/actions/setup-environment@main
if: matrix.os == 'ubuntu-latest'
with:
full-checkout: ${{ inputs.full-checkout }}
- name: Checkout Repository (Windows)
if: matrix.os == 'windows-latest'
uses: actions/checkout@v4
- name: Set up JDK 17 (Windows)
if: matrix.os == 'windows-latest'
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Setup Gradle (Windows)
if: matrix.os == 'windows-latest'
uses: gradle/actions/setup-gradle@v3
- name: Run tests
uses: burrunan/gradle-cache-action@v3
with:
job-id: unit-test-${{ matrix.os }}
arguments: ${{ matrix.os == 'ubuntu-latest' && 'ktlintCheck test' || 'test' }}
e2e-build:
runs-on: ubuntu-latest
steps:
- uses: iamgio/quarkdown/.github/actions/setup-environment@main
with:
full-checkout: ${{ inputs.full-checkout }}
- name: Build CLI
id: build
uses: burrunan/gradle-cache-action@v3
with:
job-id: e2e-build
arguments: installDist
# Building the wiki to ensure it compiles
- name: Build wiki
run: |
cd docs
${{ github.workspace }}/build/install/quarkdown/bin/quarkdown c main.qd --strict --clean
- name: Upload CLI artifact
uses: actions/upload-artifact@v4
with:
name: quarkdown-e2e-cli
path: build/install/quarkdown
retention-days: 1
e2e-test:
runs-on: ubuntu-latest
needs: e2e-build
strategy:
fail-fast: false
matrix:
shard: [1, 2, 3, 4]
steps:
- uses: iamgio/quarkdown/.github/actions/setup-environment@main
with:
full-checkout: ${{ inputs.full-checkout }}
- name: Download CLI artifact
uses: actions/download-artifact@v4
with:
name: quarkdown-e2e-cli
path: build/install/quarkdown
- name: Make CLI executable
run: chmod +x build/install/quarkdown/bin/quarkdown
- name: Run E2E tests (shard ${{ matrix.shard }}/4)
uses: burrunan/gradle-cache-action@v3
env:
QUARKDOWN_CLI_PATH: ${{ github.workspace }}/build/install/quarkdown/bin/quarkdown
with:
job-id: e2e-test
arguments: :quarkdown-html:e2eTest -Pshard=${{ matrix.shard }} -PtotalShards=4
================================================
FILE: .github/workflows/update-emoji-list.yml
================================================
# This workflow updates the emoji list on the gh-pages-src branch.
name: Update emoji list
on:
schedule:
# Runs every Sunday at 00:00 UTC
- cron: '0 0 * * 0'
workflow_dispatch:
jobs:
update-emoji-list:
runs-on: ubuntu-latest
steps:
- uses: iamgio/quarkdown/.github/actions/setup-environment@main
with:
full-checkout: true
checkout-token: ${{ secrets.COMMITTER_TOKEN }}
- name: Build distribution
uses: burrunan/gradle-cache-action@v3
with:
job-id: main
arguments: distZip
- name: Unzip distribution
run: |
mkdir -p build/unzipped
unzip -q build/distributions/quarkdown.zip -d build/unzipped
echo "$PWD/build/unzipped/quarkdown/bin" >> $GITHUB_PATH
- name: Update emoji list
uses: iamgio/quarkdown/.github/actions/update-emoji-list@main
with:
quarkdown-path: ./build/unzipped/quarkdown/bin/quarkdown
================================================
FILE: .gitignore
================================================
##############################
## Java
##############################
.mtj.tmp/
*.class
*.jar
*.war
*.ear
*.nar
hs_err_pid*
replay_pid*
##############################
## Maven
##############################
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
pom.xml.bak
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
.mvn/wrapper/maven-wrapper.jar
##############################
## Gradle
##############################
bin/
build/
.gradle
.gradletasknamecache
gradle-app.setting
!gradle-wrapper.jar
##############################
## JTE (Java Template Engine)
##############################
jte-classes/
##############################
## NPM
##############################
node_modules/
npm-debug.log
##############################
## IntelliJ
##############################
out/
.idea/
.idea_modules/
*.iml
*.ipr
*.iws
##############################
## Eclipse
##############################
.settings/
tmp/
.metadata
.classpath
.project
*.tmp
*.bak
*.swp
*~.nib
local.properties
.loadpath
.factorypath
##############################
## NetBeans
##############################
nbproject/private/
nbbuild/
dist/
nbdist/
nbactions.xml
nb-configuration.xml
##############################
## Visual Studio Code
##############################
.vscode/
.code-workspace
##############################
## OS X
##############################
.DS_Store
##############################
## Quarkdown
##############################
/*/output/
##############################
## Miscellaneous
##############################
.claude/
*.log
**/_test/
================================================
FILE: .run/CLI_Docs.run.xml
================================================
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="CLI: Docs" type="JetRunConfigurationType">
<option name="MAIN_CLASS_NAME" value="com.quarkdown.cli.QuarkdownCliKt" />
<module name="quarkdown.quarkdown-cli.main" />
<option name="PROGRAM_PARAMETERS" value="c main.qd --clean --libs ../quarkdown-libs/src/main/resources --out-name wiki" />
<shortenClasspath name="NONE" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/docs" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>
================================================
FILE: .run/CLI_Mock.run.xml
================================================
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="CLI: Mock" type="JetRunConfigurationType">
<option name="MAIN_CLASS_NAME" value="com.quarkdown.cli.QuarkdownCliKt" />
<module name="quarkdown.quarkdown-cli.main" />
<option name="PROGRAM_PARAMETERS" value="c main.qd --libs ../quarkdown-libs/src/main/resources" />
<shortenClasspath name="NONE" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/mock" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>
================================================
FILE: .run/Lint_format.run.xml
================================================
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Lint: format" type="GradleRunConfiguration" factoryName="Gradle">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="ktlintFormat" />
</list>
</option>
<option name="vmOptions" />
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<ExternalSystemDebugDisabled>false</ExternalSystemDebugDisabled>
<DebugAllEnabled>false</DebugAllEnabled>
<RunAsTest>false</RunAsTest>
<GradleProfilingDisabled>false</GradleProfilingDisabled>
<GradleCoverageDisabled>false</GradleCoverageDisabled>
<method v="2" />
</configuration>
</component>
================================================
FILE: .run/Test_full_suite.run.xml
================================================
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Test: full suite" type="GradleRunConfiguration" factoryName="Gradle">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="test" />
</list>
</option>
<option name="vmOptions" />
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<ExternalSystemDebugDisabled>false</ExternalSystemDebugDisabled>
<DebugAllEnabled>false</DebugAllEnabled>
<RunAsTest>false</RunAsTest>
<GradleProfilingDisabled>false</GradleProfilingDisabled>
<GradleCoverageDisabled>false</GradleCoverageDisabled>
<method v="2" />
</configuration>
</component>
================================================
FILE: .run/Test_minimal_suite.run.xml
================================================
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Test: minimal suite" type="GradleRunConfiguration" factoryName="Gradle">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="quarkdown-core:test" />
<option value="quarkdown-html:test" />
<option value="quarkdown-test:test" />
</list>
</option>
<option name="vmOptions" />
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<ExternalSystemDebugDisabled>false</ExternalSystemDebugDisabled>
<DebugAllEnabled>false</DebugAllEnabled>
<RunAsTest>false</RunAsTest>
<GradleProfilingDisabled>false</GradleProfilingDisabled>
<GradleCoverageDisabled>false</GradleCoverageDisabled>
<method v="2" />
</configuration>
</component>
================================================
FILE: CHANGELOG.md
================================================
# Changelog
## [Unreleased]
### Added
#### [CSL bibliography styles](https://quarkdown.com/wiki/bibliography) (breaking change)
Quarkdown's internal bibliography management is now powered by [CSL](https://citationstyles.org) (Citation Style Language).
- A curated selection of citation styles from the [CSL Style Repository](https://github.com/citation-style-language/styles) is now supported. The `style` parameter now accepts a CSL style identifier (e.g. `ieee`, `apa`, `chicago-author-date`, `nature`). The default style is now `ieee`.
**Breaking change:** `plain` and `ieeetr` styles do not exist anymore, and have been replaced by `ieee`.
- Along with BibTeX (`.bib`) files, the following file formats are now accepted:
- CSL JSON (`.json`)
- YAML (`.yaml`/`.yml`)
- EndNote (`.enl`)
- RIS (`.ris`)
- Rendered bibliography entries are now localized to the document locale, set via `.doclang`.
#### [Multi-key citations](https://quarkdown.com/wiki/bibliography#citations)
`.cite` now accepts a comma-separated list of keys (e.g. `.cite {einstein, hawking}`) to produce a single combined citation label, whose format depends on the active citation style (e.g. `[1], [2]` for IEEE, `(Einstein, 1905; Hawking, 1988)` for APA).
#### [Scoped page formatting](https://quarkdown.com/wiki/page-format#scoped-formatting)
`.pageformat` now supports scoping formats to specific pages in `paged` documents via two combinable parameters:
- `side` (`left` or `right`): restricts formatting to recto or verso pages, enabling mirrored margins and other asymmetric layouts.
- `pages` (e.g. `2..5`): restricts formatting to an inclusive range of page indices.
```markdown
.pageformat size:{A4}
.pageformat side:{left} margin:{2cm 3cm 2cm 1cm}
.pageformat side:{right} margin:{2cm 1cm 2cm 3cm}
```
```markdown
.pageformat pages:{1..3} borderbottom:{4px}
```
#### [`.heading` primitive function](https://quarkdown.com/wiki/headings)
The new `.heading` function creates headings with granular control over their behavior, unlike standard Markdown headings (`#`, `##`, ...).
It allows explicit control over numbering (`numbered`), table of contents indexing (`indexed`), page breaks (`breakpage`), depth, and reference ID (`ref`).
#### New syntax: [Tight function calls](https://quarkdown.com/wiki/syntax-of-a-function-call#tight-function-calls)
Inline function calls can now be wrapped in curly braces to delimit them from surrounding content, without relying on whitespace.
```markdown
abc{.uppercase {def}}ghi
```
#### [`.pagebreak` primitive function](https://quarkdown.com/wiki/page-break)
The new `.pagebreak` function provides an explicit way to insert a page break as an alternative to the `<<<` syntax.
#### [File tree](https://quarkdown.com/wiki/file-tree)
The new `.filetree` function renders a visual file tree from a Markdown list.
```markdown
.filetree
- src
- main.ts
- ...
- README.md
```
Bold entries (`**name**`) are highlighted with a distinct background color, useful for drawing attention to specific items.
```markdown
.filetree
- src
- **main.ts**
- utils.ts
- README.md
```
#### [Better heading configuration for table of contents and bibliography](https://quarkdown.com/wiki/table-of-contents)
Both `.tableofcontents` and `.bibliography` now accept the following optional parameters to control the heading that precedes them:
- `breakpage`: controls whether the heading triggers an automatic page break.
- `headingdepth`: the depth of the heading (1-6).
- `numberheading`: controls whether the heading is numbered in the document hierarchy.
- `indexheading`: when enabled, the heading is included in the document's own table of contents.
#### [Subscript and superscript text](https://quarkdown.com/wiki/text)
The `.text` function now accepts a `script` parameter with `sub` and `sup` values for subscript and superscript text.
### Changed
#### Removed `includeunnumbered` parameter from `.tableofcontents`
The `includeunnumbered` parameter has been removed, in favor of the more granular heading configuration previously mentioned.
Now all indexable headings are included in the ToC by default, regardless of their numbering.
#### `.fullspan` now relies on `.container`
`.fullspan`, used to create a block spanning over multiple columns in a multi-column layout, is now shorthand for `.container fullspan:{yes}`.
### Fixed
#### Stabilized multi-column layout
The [multi-column layout](https://quarkdown.com/wiki/multi-column-layout) via `.pageformat columns:{N}` is no longer experimental, and now works reliably across all document types.
#### Added call stack limit
Infinite recursion in function calls is now detected and reported as a clear error.
#### Fixed default browser not opening on Linux (Wayland and XDG environments)
On Linux systems where the Java AWT Desktop API does not support the BROWSE action (e.g., Wayland), `--browser default` now falls back to `xdg-open` automatically.
Additionally, `--browser xdg` is now a supported named choice for the `--browser` CLI option.
Thanks @szy1840!
#### Fixed scroll position not fully restored during live preview on long paged documents
When editing long paged documents with live preview, the scroll position could sometimes be restored only partially because of long paged.js load times. The swap now reliably waits for the content to be fully loaded.
#### Improved lexer performance
The lexer has been optimized to reduce regex builds to a minimum, resulting in significantly improved performance for large documents.
* * *
### Sponsors
Thanks to our sponsors! 🎉
@vitto4
<a href="https://falconer.com"><img src="https://raw.githubusercontent.com/iamgio/quarkdown/project-files/images/sponsors/falconer.jpeg" alt="Falconer" width="350"></a>
## [1.14.1] - 2026-03-06
### Added
#### [Escaped characters in numbering formats](https://quarkdown.com/wiki/numbering)
A backslash (`\`) in a numbering format string now escapes the next character, treating it as a fixed symbol. For example, `\1` produces a literal `1` instead of a decimal counter.
### Fixed
#### Fixed live preview sometimes timing out on Windows
Fixed an IPv6-related issue that caused connections to Quarkdown's server to time out on Windows. _Please also update to the latest version of the VS Code extension to v1.1.2 or later._
#### Fixed block function call incorrectly matching lines with trailing content
Fixed an issue that caused a line like `.sum {1} {2} .sum {3} {4}` to be incorrectly lexed as two block function calls rather than a single paragraph with two inline function calls.
### Changed
#### Improved lexer performance
The lexer no longer restarts its regex search from scratch when a function call advances the scan position, resulting in slightly improved performance, especially for documents with many function calls.
## [1.14.0] - 2026-02-19
This version is the biggest release to date, with a large number of new features and improvements, and a [new official wiki](https://quarkdown.com/wiki), written in Quarkdown, that fully replaces the GitHub wiki for a better experience.
> Going forward, next minor releases will be smaller and more frequent.
### Added
#### [`docs` document type](https://quarkdown.com/wiki/document-types#docs-docs)
`docs` is the fourth document type available in Quarkdown, alongside `plain`, `paged` and `slides`. It is designed for technical documentation, wikis and knowledge bases.
It derives from `plain`, and adds a customizable navigation sidebar, a ToC sidebar, a header, accurate client-side search, and next/previous page navigation buttons.
You can see it in action in the [new official wiki](https://quarkdown.com/wiki)! To get started with a new `docs` document, you can rely on `quarkdown create` as usual.
#### New themes: Galactic (color) and Hyperlegible (layout)
Inspired by Astro, this new theme combination is the one used in the new wiki for improved readability and modern look.
<img width="606" height="350" alt="Galactic+Hyperlegible" src="https://github.com/user-attachments/assets/d8609d22-fb57-4db9-8b4a-98fa28cda421" />
#### [GitHub-style alerts](https://quarkdown.com/wiki/quote-types)
GitHub's alert syntax is now supported, making it easier to migrate from other tools:
```markdown
> [!NOTE]
> This is a note
```
Note that Quarkdown's original syntax is still supported _and recommended_, especially for English documents:
```markdown
> Note: This is a note
```
#### [Subdocument links now allow anchors](https://quarkdown.com/wiki/subdocuments)
Links to Quarkdown subdocuments now support anchors, to link to specific sections:
```markdown
[Page](page.qd#section)
```
#### [Customizable page numbering format](https://quarkdown.com/wiki/page-counter#formatting-the-page-number)
The `.formatpagenumber {format}` function overrides the page numbering format from the current page onward. It accepts the same format specifiers as `.numbering`, and applies to both page counters and table of contents.
```markdown
.pagemargin {topcenter}
.currentpage
# First page
.formatpagenumber {i}
# Second page
# Third page
```
<img width="550" alt="Page number format example" src="https://raw.githubusercontent.com/iamgio/quarkdown/main/docs/page-counter/format.png" />
Thanks @OverSamu!
#### [Horizontal/vertical gap customization of `.grid`](https://quarkdown.com/wiki/stacks#parameters)
The `.grid` function now accepts `hgap` and `vgap` parameters to customize the horizontal and vertical gaps between grid items. `gap` still works as a shorthand for both.
Thanks @OverSamu!
#### [`none` is now converted to `null`](https://quarkdown.com/wiki/none#passing-none-to-functions)
When invoking a native function from the stdlib, [`none`](https://quarkdown.com/wiki/none) is now supported by nullable parameters, and converted to `null`.
Before:
```markdown
.function {rectangle}
width height background?:
.if {.background::isnone}
.container width:{.width} height:{.height}
.ifnot {.background::isnone}
.container width:{.width} height:{.height} background:{.background}
```
After:
```markdown
.function {rectangle}
width height background?:
.container width:{.width} height:{.height} background:{.background}
```
#### [Icons](https://quarkdown.com/wiki/icons)
The new `.icon {name}` function relies on [Bootstrap Icons](https://icons.getbootstrap.com/#icons) to display pixel-perfect icons in your documents.
```markdown
Quarkdown is on .icon {github}
```
#### New output target: plain text
Quarkdown can now render to plain text (`.txt`) via `--render plaintext`.
This has no particular use case. It was needed to implement the docs search feature in the first place.
#### Get path to root directory
The new `.pathtoroot {granularity?}` function returns the relative path from the current source file to the parent directory of:
- the root document, if `granularity` is `project` (default)
- the subdocument, if `granularity` is `subdocument`
### Changed
#### `.css` doesn't require `!important` anymore
The `.css` function now applies `!important` automatically at the end of each rule.
#### Revised navigation sidebar
The navigation sidebar, visible in `plain` and `paged` documents on web view, is now easier to navigate, with all entries visible at once, and more accessible for screen readers.
<img width="208" height="632" alt="Sidebar" src="https://github.com/user-attachments/assets/54956e66-db34-486f-bb9a-275271ae7a7e" />
Additionally, its generation is now performed at compile time rather than runtime, providing major performance improvements for large documents.
#### Flexible naming strategy for subdocument output files
`--no-subdoc-collisions` was removed in favor of `--subdoc-naming <strategy>`, which is a flexible way to choose how subdocument output files are named:
- `file-name` (default): each subdocument output file is named after its source file
- `document-name`: each subdocument output file is named after its `.docname` value
- `collision-proof`: former `--no-subdoc-collisions`
#### Revamped `create` CLI
The `quarkdown create` command is now more intuitive, for a smoother onboarding experience.
#### Libraries now include content
`.include {library}` now also includes top-level Markdown content from the library, just like `.include {file.qd}` does for regular files.
#### Page content border adjustments
Page content border (`.pageformat bordercolor`) is now supported in `plain` documents, and refined for `slides` documents, especially in PDF output.
#### Improved code diff styling
Code blocks using the `diff` language now have improved and clearer styling for added and removed lines.
### Fixed
#### Major improvements to live preview
Live preview has undergone major performance improvements and increased reliability, especially in combination with the new VS Code extension update.
Live reloading not being performed when editing subdocuments has also been fixed.
#### Fixed subdocument resolution from included files
Linking to subdocuments from files included via `.include` from a different directory now correctly resolves the subdocument path.
#### Fixed unresolved reference of local variables in body arguments
The following snippet used to cause an unresolved reference error for `y`:
```markdown
.function {a}
x:
.x
.function {b}
y:
.a
.y
.b {hello}
```
#### Fixed paragraph spacing with floating element
Fixed an issue that caused no spacing to be present between two paragraphs if a floating element was in-between, via `.float`.
#### Fixed ToC with no level 1 headings
Table of contents are no longer empty if no level 1 headings are present, or if all are decorative.
#### Fixed line spacing in table cells
Table cells now correctly apply the same line spacing as paragraphs and lists.
* * *
### Sponsors
Shout out to our sponsors! 🎉
@vitto4
@serkonda7
<a href="https://falconer.com"><img src="https://raw.githubusercontent.com/iamgio/quarkdown/project-files/images/sponsors/falconer.jpeg" alt="Falconer" width="350"></a>
[Unreleased]: https://github.com/iamgio/quarkdown/compare/v1.14.1...HEAD
[1.14.1]: https://github.com/iamgio/quarkdown/compare/v1.14.0...v1.14.1
[1.14.0]: https://github.com/iamgio/quarkdown/compare/36ef163d22c13e51edfca12739b99aa6aa1368b4...v1.14.0
================================================
FILE: CLAUDE.md
================================================
# About Quarkdown
This is the Quarkdown project. Quarkdown is a:
- Turing-complete Markdown flavor, with a `.qd` standard file extension
- Typesetting system, as an alternative to LaTeX, with high-quality typography and layout customization
- Compiler, parser and renderer to:
- HTML
- PDF (via Puppeteer)
- Plain text
- CLI tool
Quarkdown supports different document types, which can be set via the `.doctype {type}` function:
- Plain documents (`plain`), suitable for notes, website, etc. Notion-like.
- Paged documents (`paged`), suitable for books, articles, reports, etc. LaTeX-like.
- Slides (`slides`), suitable for presentations.
- Documentation (`docs`), suitable for technical documentation websites and wikis.
The Quarkdown flavor extends CommonMark and GFM with various features. The most notable one is *functions*:
- Inline function:
```markdown
Lorem ipsum .myfunction {arg1} param:{arg2} dolor sit amet.
```
- Block function:
```markdown
.myfunction {arg1} param:{arg2}
arg3
```
Quarkdown is dynamically typed, although types do live in the native Kotlin implementation of functions.
For a full function call syntax reference, see [here](docs/syntax-of-a-function-call.qd).
For any other information, see the [documentation](docs) and the [README](README.md).
# Making changes
## Guidelines
You are a senior software engineer with high expertise in handling complex codebases, compilers, and typesetting systems.
You care about software quality, maintainability, and readability.
Avoid repetitive code at all costs and strive for elegant solutions, abstracting common patterns into reusable components.
Keep functions and classes small and focused on a single responsibility.
It's possible to over-engineer when necessary to achieve high cohesion, low coupling, to anticipate future changes,
leveraging design patterns, such as strategy and visitor (frequent in this codebase), and best practices.
Write medium-sized documentation comments for all public classes, methods, and properties,
and also non-public ones when the logic is not straightforward. Update existing documentation when making changes to the codebase, both in code and [docs](docs), and make sure to keep it consistent with the style used in the project.
Aim for a test-driven development (TDD) approach when possible. Tests play an important role. See [Testing](#testing) below.
When creating new files, always add them to git via `git add`, and make sure to place them in the correct module and package, following the existing project structure.
## Overview
The project is structured as a multi-module Gradle project.
- To build, always run `./gradlew installDist` or `distZip` from the root folder. Never run `build`.
- To test, run `./gradlew test`, optionally specifying a module, e.g., `:quarkdown-core:test`.
- `./gradlew run` is acceptable.
## Compiler
The main compiler, located in [quarkdown-core](quarkdown-core),
along with rendering extensions, such as [quarkdown-html](quarkdown-html) and [quarkdown-plaintext](quarkdown-plaintext),
the language server, located in [quarkdown-lsp](quarkdown-lsp),
the CLI, located in [quarkdown-cli](quarkdown-cli),
and other modules, is written in Kotlin with the Ktlint code style.
Follow the code style used in the project, and make sure to run `./gradlew ktlintFormat` after making changes to ensure the code is properly formatted.
### Pipeline
The compiler is structured as a sequential pipeline (`pipeline` package).
See `Pipeline-*` files in the [documentation](docs) to understand the different stages (`pipeline/stages` package).
### Context
`Context` is the most important interface in the compiler (`context` package). A context contains information about libraries, functions,
metadata, settings, and other data needed during compilation.
Each function call has a reference to the context it was parsed in.
A context can be forked to create a child context with additional or overridden data.
There are three forking methods, depending on the implementation, which affect the sandbox level:
- `SharedContext`: exchanges information bi-directionally. Changes made in the child context are reflected in the parent context, and vice versa,
allowing for full sharing of variables, functions and other declarations.
- `ScopeContext`: like `SharedContext`, but the child context does not share new declarations (functions and variables) back to the parent context.
This is the behavior used within lambda blocks, such as in `.foreach`.
`SubdocumentContext`: no information is shared back to the main file's context, only inherited from it. This also applies to the document info (metadata, title, etc.),
This is the behavior used for subdocuments (see [Subdocuments](docs/subdocuments.qd)).
### Nodes
Nodes are defined in the `ast/base` or `ast/quarkdown` package, depending on whether they are from CommonMark/GFM or Quarkdown-specific.
Defining a new node involves:
- Implementing `Node` or `NestableNode`, depending on whether the node can have children or not. Nodes should never be data classes, and `children` must always be the last property.
- Implementing `override fun <T> accept(visitor: NodeVisitor<T>): T = visitor.visit(this)`
- Adding a `visit` method to `NodeVisitor` and its implementations (`*Renderer`)
- Adding lexing/parsing logic (very uncommon in the current state of the project) or, more commonly for non-GFM nodes,
defining a native function in the [standard library](#standard-library) that returns the node. See the `Layout` stdlib module for examples.
### Function calls and scripting
The function call subsystem spans parsing, resolution, execution, and output mapping.
#### Parsing and refinement
Source code function calls (e.g. `.foo {x}::bar {y}`) are first extracted by the `FunctionCallWalker` (lexer-level)
into `WalkedFunctionCall` structures. These are then refined by `FunctionCallRefiner` into `FunctionCallNode` AST nodes.
**Inline vs body arguments:** Inline arguments (inside `{...}`) are eagerly evaluated as expressions via `ValueFactory.safeExpression`,
resolving nested function calls at parse time. Body arguments (indented blocks) are stored as raw `DynamicValue` strings
for lazy evaluation by the consuming function. This distinction is critical: body arguments intentionally defer evaluation
so that the receiving function can choose to use them as raw text, evaluate them as Markdown, or both.
**Chaining:** `FunctionCallRefiner` transforms the linked-list chain `.foo {x}::bar {y}` into a nested tree `bar(foo(x), y)`.
#### Resolution and execution
`FunctionCallNodeExpander` drives function call expansion during the `FunctionCallExpansionStage`:
1. Each `FunctionCallNode` carries the `Context` it was parsed in (`node.context`).
2. Resolution: `node.context.resolveUnchecked(node)` finds the function by name and creates an `UncheckedFunctionCall`
with `context = this` (the resolving context). This context is accessible as `call.context` during execution.
3. Execution: the function's `invoke(bindings, call)` runs and returns an `OutputValue`.
4. Output mapping: the result is passed to a `NodeOutputValueVisitor` (block or inline), which converts it to an AST `Node`.
For `DynamicValue` results containing raw strings, the visitor calls `parseRaw`, which invokes `ValueFactory.blockMarkdown`
or `ValueFactory.inlineMarkdown` to parse the string as Markdown with function expansion. The context used for `parseRaw`
is the one held by the `FunctionCallNodeExpander`, which is the context passed to `ValueFactory.markdown` when the current
parse cycle was initiated.
#### Custom functions and lambdas
Custom user-defined functions (`.function` in the `Flow` stdlib module) bridge Quarkdown scripting with the native function system:
1. **Definition:** `Flow.function()` creates a `SimpleFunction` and registers it in a `Library` prefixed with `__func__`.
The function's parameters are derived from the Lambda's explicit parameters.
2. **Lambda invocation (`Lambda.invokeDynamic`):**
- Forks from `parentContext` (the context where the Lambda was *defined*, not called).
- Registers lambda parameter functions via `createLambdaParametersLibrary`: each parameter becomes a zero-arg `SimpleFunction`
that returns `DynamicValue(argument.unwrappedValue)`.
- Propagates the calling context's libraries (when `callingContext` is provided), so that variable references
from the calling scope can be resolved within the lambda body.
- Calls the Lambda's `action(arguments, forkedContext)`, which typically runs `ValueFactory.eval(body, forkedContext)`.
3. **`ValueFactory.eval` and recursive resolution:** `eval` parses a raw string as an expression (via `safeExpression`),
evaluates it, and returns the result. When the result is a `DynamicValue` wrapping a single-line string different
from the input (indicating an intermediate, unresolved reference such as a lambda parameter holding `.y`), `eval`
recursively evaluates the result in the same context. Multi-line strings are excluded from recursion
as they represent raw Markdown body content intended for lazy evaluation.
4. **Variables:** `Flow.variable()` defines a variable as a function with an optional parameter, acting as both getter and setter.
Variable reassignment scans the context hierarchy upward to find the owning context.
#### Key files
| File | Role |
|-------------------------------------------------------|---------------------------------------------------------------------------|
| `FunctionCallRefiner` | Refines walked calls into `FunctionCallNode`s, handles chaining |
| `FunctionCallNodeExpander` | Expands function call nodes in the AST, maps outputs to nodes |
| `FunctionCallExpansionStage` | Pipeline stage that drives expansion |
| `Lambda` | Parameterized action block with context forking and argument registration |
| `ValueFactory.eval` / `safeExpression` / `expression` | Expression parsing and evaluation |
| `NodeOutputValueVisitor` | Converts function output values to AST nodes |
| `Flow.kt` (`function`, `variable`) | Custom function and variable definition |
## Standard library
The standard library is located in [quarkdown-stdlib](quarkdown-stdlib).
It's a *native* library, meaning it's implemented in Kotlin.
The stdlib is organized into modules, each one with its own Kotlin source file,
with a `QuarkdownModule` declaration, which exposes functions:
```kotlin
val Layout: QuarkdownModule =
moduleOf(
::container,
::align,
::center,
// ...
)
```
The module should then be registered in [Stdlib](quarkdown-stdlib/src/main/kotlin/com/quarkdown/stdlib/Stdlib.kt).
By default, a function declared as `fun x(y: Type): ReturnType` in Kotlin
is exposed to Quarkdown as a function call `.x y:{arg}` that returns a dynamic value.
Additionally, `@Name` can be used to rename functions and parameters.
For instance, Quarkdown's standard uses lowercase, while Kotlin uses camelCase:
```kotlin
@Name("myfunction")
fun myFunction(
@Name("myparam") myParam: String
): StringValue {
// ...
}
```
Native functions can also accept and return Quarkdown AST nodes directly,
for example: `Paragraph(...).wrappedAsValue()`. `wrappedAsValue()` is available for many value types.
Functions must be documented thoroughly with KDoc comments,
including examples of usage in Quarkdown syntax. All parameters and return types must be documented.
A `Context` parameter can be added to access context information during execution,
by declaring it as the first parameter of the function, and marked as `@Injected`.
This parameter is not exposed to Quarkdown and must not be documented.
## Quarkdoc
Quarkdoc is Quarkdown's documentation generation system, located in [quarkdoc](quarkdoc).
It relies on Dokka v2 to generate documentation from KDoc comments in the Kotlin codebase,
with custom extensions.
Quarkdoc's HTML output is bundled in the build, or can be generated separately via `./gradlew quarkdocGenerateAll`
When writing native functions, the following annotations are useful to document them properly:
- `@LikelyNamed`: indicates that a parameter is likely to be named rather than positional when called from Quarkdown.
For example, `.container width:{100}` instead of `.container {100}`.
Using `@Name` implies `@LikelyNamed`.
- `@LikelyBody`: indicates that a parameter is likely to be passed as a body block when called from Quarkdown.
Body parameters are always the last parameters of a function.
```markdown
.container width:{100}
This is the body content.
```
- `@LikelyChained`: indicates that a function is likely to be used in a chained manner via the chain syntax
(see [Function call syntax](docs/syntax-of-a-function-call.qd#chaining-calls)).
For example, in `.myvar::uppercase`, `uppercase` is marked with `@LikelyChained`.
- `@OnlyForDocumentType`/`@NotForDocumentType`: indicates that a function is only available for, or not available for,
specific document types. An error is raised if the function is called in an incompatible document type.
## HTML front-end
The HTML rendering engine is located in [quarkdown-html](quarkdown-html).
After the Kotlin extension renders the Quarkdown AST to HTML elements,
the front-end TypeScript code takes care of interactivity and dynamic features,
while SCSS files handle styling and layout.
Additionally, Puppeteer is used to generate PDF output from the HTML rendering,
relying on the webserver, located in [quarkdown-server](quarkdown-server).
### Themes
Quarkdown allows for a layout theme and a color theme to be selected independently, for more combination possibilities.
[scss](quarkdown-html/src/main/scss) exports themes to [theme](quarkdown-html/src/main/resources/render/theme):
- `global.css`: global styles
- `layout/*.css`: layout styles
- `color/*.css`: theme styles
## Server
[quarkdown-server](quarkdown-server) is a Ktor-based web server that serves the HTML rendering and allows PDF generation via Puppeteer. The `/preview/<path>` endpoint, used in combination with the CLI's `--preview` and `--watch` options, serves the HTML through a double iframe buffer, allowing for live preview during editing.
## Testing
The project has high test coverage, with three types of tests:
- Regular unit tests, located in each module's `src/test/kotlin` folder for Kotlin, and `__tests__` folders for TypeScript,
which test individual components, classes, and functions in isolation.
- Integration unit tests, located in [quarkdown-test](quarkdown-test/src/test/kotlin),
which test the compiler as a whole, by compiling Quarkdown source files into different output formats, mainly HTML.
- End-to-end tests, located in [e2e](quarkdown-html/src/test/e2e), which test the HTML rendering engine in a real browser environment via Playwright,
ensuring HTML output, TypeScript runtime, and CSS styles work correctly together. CSS, in particular, is prone to visual issues that are hard to catch otherwise.
When adding or modifying an E2E test, run only the affected test file to speed up the feedback loop:
```bash
cd quarkdown-html && npx playwright test path/to/test.spec.ts
```
When making changes to the compiler or other modules, make sure to add or update tests accordingly.
### E2E test structure
Each E2E test lives in a directory under `quarkdown-html/src/test/e2e/` containing:
- `main.qd`: the Quarkdown source document for the test.
- `<test-name>.spec.ts`: the Playwright spec file.
The test framework (`quarkdown.ts`) provides a `suite(testDir)` factory that returns:
- `test(name, fn, options?)`: defines a single test case. `options` supports `subpath` for subdocument navigation.
- `testMatrix(name, docTypes, fn, options?)`: runs the same test across multiple document types (e.g. `["plain", "paged", "slides"]`),
creating separate test cases for each. The runner prepends `.doctype {type}` to the source automatically.
This is the only way to specify a document type; `test()` does not support `docType`.
- `expect`: Playwright's `expect` for assertions.
The runner (`__util/runner.ts`) compiles the source via the CLI, navigates to the Quarkdown server, and waits for `window.isReady()`.
Each test run gets a unique ID for parallel isolation.
Utility helpers in `__util/css.ts` provide computed style access.
## Documentation
Documentation files are located in the [docs](docs) folder, and are written in Quarkdown itself.
When making changes to the compiler or other modules, features or changes,
make sure to also update the documentation accordingly, along with [CHANGELOG](CHANGELOG.md).
The changelog follows the [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) format,
uses [Semantic Versioning](https://semver.org/), uses extensive description for each major change,
with links to the corresponding documentation at `https://quarkdown.com/wiki/Page`.
When writing documentation, you're an expert technical writer who follows these guidelines:
- Use American English spelling.
- Use active voice.
- Be concise and clear, but not at the cost of clarity. Avoid unnecessary jargon but also ambiguity.
- Use consistent terminology. For example, always use "function call" instead of sometimes "function invocation".
- Use a professional and friendly tone, and be as human as possible.
Avoid overly technical or robotic language.
Avoid en-dashes, em-dashes, and emojis.
To demo a source+output example, use functions defined in [`_Setup.qd`](docs/_setup.qd):
- `.examplemirror` for showing both source code and rendered output side-by-side.
This is great for Quarkdown snippets that don't affect the overall document structure or style.
- `.example` for showing the source code and a manual output, such as an image.
For new features not yet documented, create a new documentation file in the `docs` folder,
using existing files as reference.
### Compiling the documentation
To compile it, run the following command from the `docs` folder via `gradlew run`:
```bash
c main.qd --clean
```
This will generate the documentation website in `docs/output/Quarkdown-Wiki`.
================================================
FILE: CONTRIBUTING.md
================================================
[Issues]: https://github.com/iamgio/quarkdown/issues
[Issue]: https://github.com/iamgio/quarkdown/issues
[Discussions]: https://github.com/iamgio/quarkdown/discussions
[Discussion]: https://github.com/iamgio/quarkdown/discussions
[wiki]: https://quarkdown.com/wiki
[documentation]: https://quarkdown.com/docs
[standard library]: https://github.com/iamgio/quarkdown/tree/main/quarkdown-stdlib/src/main/kotlin/com/quarkdown/stdlib
# Contributing to Quarkdown
Thanks for interest in contributing to Quarkdown, the Markdown-based typesetting system, and its ecosystem!
All types of contributions are encouraged and valued.
Please make sure to read the relevant section before making your contribution, as it will make it easier for maintainers to handle it.
> If you like the project, but don't have time to contribute, that's totally fine!
> You can still support us and show your appreciation by doing any of the following:
> - Star :star2: the project.
> - Post the project on social media.
> - Mention the project to others.
## Table of Contents
- [Questions](#questions)
- [Contributing via issues](#contributing-via-issues)
- [Reporting Bugs](#reporting-bugs)
- [Suggesting Enhancements](#suggesting-enhancements)
- [Contributing via PR](#contributing-via-pr)
- [Your first contribution](#your-first-contribution)
- [Understanding the architecture](#understanding-the-architecture)
- [Styleguides](#styleguides)
## Questions
Before you ask a question, it is best to search for existing [Issues] or [Discussions] that might help you.
If you then still feel the need to ask a question and need clarification, we recommend the following:
- Open a [Discussion](https://github.com/iamgio/quarkdown/discussions/new/choose) or [Issue](https://github.com/iamgio/quarkdown/issues/new), depending on what you feel is more appropriate for your question.
- Provide as much context as you can about what you're running into.
- Provide project version, along with JVM version and OS if relevant.
We will then take care of the issue as soon as possible.
## Contributing via issues
> ### Legal Notice
> When contributing to this project, you must agree that you have authored 100% of the content, that you have the necessary rights to the content and that the content you contribute may be provided under the project license.
### Reporting Bugs
#### Before submitting a bug report
A good bug report shouldn't leave others needing to chase you up for more information. Therefore, we ask you to investigate carefully, collect information and describe the issue in detail in your report. Please complete the following steps in advance to help us fix any potential bug as fast as possible.
- Make sure that you are using the latest version.
- Determine if your bug is really a bug and not an error on your side.
- Check if there is not already an issue for your bug in [Issues].
#### Submitting
Open an [Issue] with a clear and descriptive title. The body should contain the following information:
- Your input
- The output or stack trace
- JVM version
- Operating system
- Can you reliably reproduce the issue? And can you also reproduce it with older versions?
### Suggesting Enhancements
#### Before submitting an enhancement
- Make sure that you are using the latest version.
- Check the [wiki] and [documentation] carefully to check if the functionality is already present.
- Check [Issues] to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one.
- Find out whether your idea fits with the scope and aims of the project.
#### Submitting
Open an [Issue] with a clear and descriptive title. The body should contain the following information:
- Provide a step-by-step description of the suggested enhancement in as many details as possible.
- Describe the current behavior and explain which behavior you expected to see instead. At this point you can also tell which alternatives do not work for you.
- Explain why this enhancement would be useful.
## Contributing via PR
### Your first contribution
> [!IMPORTANT]
> Please **open a PR only after opening an [Issue]** for the change you want to make, so that maintainers can give you feedback on whether your contribution is likely to be accepted and how it should be implemented.
The following list shows contributions that are highly welcome, in order of importance:
1. [Issues] labeled with `good first issue` or `help wanted`. These issues are usually easier to solve and are a good starting point for new contributors.
2. Improve the **documentation** of the [standard library], which will be shown in the auto-generated [documentation].
To have a preview of the generated documentation, you can run `gradlew quarkdocGenerate`
3. Improve performance of the pipeline.
4. Add new functions to the [standard library]. It's suggested to open an [enhancement suggestion](#suggesting-enhancements) first.
5. Add new [themes](https://github.com/iamgio/quarkdown/tree/main/quarkdown-html/src/main/scss).
Please ensure your theme looks correctly on all document types (`plain`, `paged`, `slides`, `docs`)
on the [Mock document](https://github.com/iamgio/quarkdown/tree/main/mock) and [Quarkdown's wiki](https://github.com/iamgio/quarkdown/tree/main/docs).
### Understanding the architecture
The architecture behind Quarkdown's core is explained in the wiki's [*Pipeline*](https://quarkdown.com/wiki/pipeline).
## Tooling
> If you're using IntelliJ IDEA, you can import run configurations from the `.run` directory.
### Building
The project uses Gradle as its build system.
To build the project, always run:
```bash
./gradlew installDist
```
> [!WARNING]
> Avoid `./gradlew build`, always use `installDist` or `distZip` instead.
### Testing
To run the full test suite:
```bash
./gradlew test
```
You can also run tests for a specific module:
```bash
./gradlew :quarkdown-core:test
./gradlew :quarkdown-html:test
```
End-to-end tests are heavy and aren't included in `:test`. They can be run with:
```bash
./gradlew :quarkdown-html:e2eTest
```
Note that all tests are automatically run on every PR.
### Running the CLI
You can run the Quarkdown CLI directly via Gradle, without needing to build the project first:
```bash
./gradlew run --args="c <file.qd> [options] --libs quarkdown-libs/src/main/resources"
```
### Documentation
- To compile the [wiki](docs), run either of the following commands from the `docs` directory:
- ```bash
quarkdown c main.qd --clean
```
- ```bash
./gradlew run --args="c main.qd --clean --libs ../quarkdown-libs/src/main/resources"
```
- To generate Quarkdoc documentation only for the standard library:
```bash
./gradlew quarkdocGenerate
```
- To generate Quarkdoc documentation for the whole project:
```bash
./gradlew quarkdocGenerateAll
```
## Styleguides
#### Kotlin code style
Quarkdown uses [ktlint](https://github.com/pinterest/ktlint) to ensure a consistent codestyle is kept across the whole project.
Upon opening a PR, `./gradlew ktlintCheck` is automatically run, and the checks must pass before the PR can be merged. You can also run `./gradlew ktlintFormat` to automatically fix any formatting issues in your code.
#### Commit messages
Please ensure your commit messages use the [imperative tense](https://cbea.ms/git-commit/#imperative)
and following the [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) specification, so that they are clear and consistent across the project.
## Attribution
This file was inspired by [contributing.md](https://contributing.md/).
================================================
FILE: Dockerfile
================================================
# Build stage via Gradle
FROM gradle:8.14.3-jdk17 AS builder
COPY . /app
WORKDIR /app
# Build the distribution zip
RUN gradle --no-daemon distZip
# For testing purposes, replace the Gradle build with the following to reduce delays.
# RUN mkdir -p build/distributions
# RUN curl -L -o build/distributions/quarkdown.zip https://github.com/iamgio/quarkdown/releases/download/latest/quarkdown.zip
WORKDIR build/distributions
RUN unzip quarkdown.zip && rm quarkdown.zip
# Run stage
FROM ghcr.io/puppeteer/puppeteer:24.15.0 AS runner
# Install JDK
USER root
RUN apt-get update && apt-get install -y openjdk-17-jdk \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
USER pptruser
WORKDIR /app
COPY --from=builder /app/build/distributions/quarkdown quarkdown
ENV PATH="/app/quarkdown/bin:${PATH}"
ENTRYPOINT ["quarkdown"]
LABEL org.opencontainers.image.vendor="Quarkdown"
LABEL org.opencontainers.image.title="Quarkdown Docker image"
LABEL org.opencontainers.image.description="Versatile Markdown-based typsetting system."
LABEL org.opencontainers.image.authors="Giorgio Garofalo (iamgio) and contributors <info@quarkdown.com>"
LABEL org.opencontainers.image.url="https://quarkdown.com"
LABEL org.opencontainers.image.source="https://github.com/iamgio/quarkdown"
LABEL org.opencontainers.image.documentation="https://quarkdown.com/docs/"
LABEL org.opencontainers.image.licenses="GPL-3.0"
================================================
FILE: LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Copyright (C) 2025 Giorgio Garofalo (iamgio) <https://github.com/iamgio/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.
================================================
FILE: README.md
================================================
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/iamgio/quarkdown/project-files/images/tbanner-light.svg">
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/iamgio/quarkdown/project-files/images/tbanner-dark.svg">
<img alt="Quarkdown banner" src="https://github.com/user-attachments/assets/68dfb3bf-9466-44f3-b220-7067322c4887">
</picture>
<br>
<a href="https://quarkdown.com/wiki"><img alt="Wiki" src="https://img.shields.io/badge/wiki-read-darkcyan"></a>
<a href="https://quarkdown.com/docs"><img alt="Docs" src="https://img.shields.io/badge/docs-read-blue"></a>
<a href="https://github.com/iamgio/quarkdown/releases/latest"><img alt="Release" src="https://img.shields.io/github/v/release/iamgio/quarkdown?color=mediumseagreen"></a>
<a href="https://marketplace.visualstudio.com/items?itemName=quarkdown.quarkdown-vscode"><img alt="Visual Studio Code Extension Version" src="https://img.shields.io/visual-studio-marketplace/v/quarkdown.quarkdown-vscode?label=vscode"></a>
<a href="https://pinterest.github.io/ktlint"><img alt="FMT: Ktlint" src="https://img.shields.io/badge/fmt-ktlint-7f52ff?logo=kotlin&logoColor=f5f5f5"></a>
<a href="https://www.codefactor.io/repository/github/iamgio/quarkdown"><img alt="CodeFactor" src="https://www.codefactor.io/repository/github/iamgio/quarkdown/badge/main"></a>
<br><br>
<a href="https://trendshift.io/repositories/13945" target="_blank"><img src="https://trendshift.io/api/badge/repositories/13945" alt="iamgio%2Fquarkdown | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
<br><br>
<strong>Releases</strong>
<br>
<a href="https://github.com/iamgio/quarkdown/releases/tag/latest">Latest</a>
|
<strong><a href="https://github.com/iamgio/quarkdown/releases/latest">Stable</a></strong>
<br>
<hr>
</p>
# Table of contents
1. [About](#about)
2. [Demo](#as-simple-as-you-expect)
3. [Targets](#targets)
4. [Comparison](#comparison)
5. [Getting started](#getting-started)
1. [Installation](#installation)
2. [Quickstart](#quickstart-)
3. [Creating a project](#creating-a-project)
4. [Compiling](#compiling)
6. [Mock document](#mock-document)
7. [Contributing](#contributing)
8. [Sponsors](#sponsors)
9. [Concept](#concept)
10. [License](#license)
# About
Quarkdown is a modern Markdown-based typesetting system designed for **versatility**. It allows a single project to compile seamlessly into a print-ready book, academic paper, knowledge base, or interactive presentation.
All through an incredibly powerful Turing-complete extension of Markdown, ensuring your ideas flow automatically into paper.
<p align="center">
<img src="https://raw.githubusercontent.com/iamgio/quarkdown/project-files/images/paged-demo.png" alt="Paper demo">
<p align="center"><em>Original credits: <a href="https://arxiv.org/abs/1706.03762v7">Attention Is All You Need</a></em></p>
</p>
<br>
Born as an extension of CommonMark and GFM, the Quarkdown Flavor brings **functions** to Markdown, along with many other syntax extensions.
<br>
> This is a function call:
> ```
> .somefunction {arg1} {arg2}
> Body argument
> ```
<br>
**Possibilities are unlimited** thanks to an ever-expanding [standard library](quarkdown-stdlib/src/main/kotlin/com/quarkdown/stdlib),
which offers layout builders, I/O, math, conditional statements and loops.
**Not enough?** You can still define your own functions and variables — all within Markdown.
You can even create awesome libraries for everyone to use.
<br>
> ```
> .function {greet}
> to from:
> **Hello, .to** from .from!
>
> .greet {world} from:{iamgio}
> ```
> Result: **Hello, world** from iamgio!
<br>
This out-of-the-box scripting support opens doors to complex and dynamic content that would be otherwise impossible
to achieve with vanilla Markdown.
Combined with live preview, :zap: fast compilation speed and a powerful [VS Code extension](https://marketplace.visualstudio.com/items?itemName=quarkdown.quarkdown-vscode), Quarkdown simply gets the work done,
whether it's an academic paper, book, knowledge base or interactive presentation.
<p align="center">
<img src="https://raw.githubusercontent.com/quarkdown-labs/quarkdown-vscode/refs/heads/project-files/live-preview.gif" alt="Live preview" />
</p>
---
<h2 align="center">Looking for something?</h2>
<p align="center">
<strong>
Check out the <a href="https://quarkdown.com/wiki" target="_blank">wiki</a>
</strong>
to get started and learn more about the language and its features!
</p>
---
## As simple as you expect...
<p align="center">
<img src="https://raw.githubusercontent.com/iamgio/quarkdown/project-files/images/code-paper.png" alt="Paper code demo">
<p align="center"><em>Inspired by: <a href="https://news.mit.edu/2025/x-ray-flashes-nearby-supermassive-black-hole-accelerate-mysteriously-0113">X-ray flashes from a nearby supermassive black hole accelerate mysteriously</a></em></p>
</p>
<h2 align="right">...as complex as you need.</h2>
<p align="center">
<img src="https://raw.githubusercontent.com/iamgio/quarkdown/project-files/images/code-chart.png" alt="Chart code demo">
</p>
# Targets
- **HTML**
- [X] **Plain**
Continuous flow like Notion/Obsidian, perfect for static websites and knowledge management - check out the author's [personal website](https://iamgio.eu/).
- [X] **Paged** <sup>via [paged.js](https://pagedjs.org)</sup>
Perfect for papers, articles and books - check out the [demo document](https://github.com/quarkdown-labs/generated/blob/main/mock/paperwhite_latex.pdf).
- [X] **Slides** <sup>via [reveal.js](https://revealjs.com)</sup>
Perfect for interactive presentations.
- [X] **Docs**
Perfect for wikis, technical documentation and large knowledge bases - check out [Quarkdown's wiki](https://quarkdown.com/wiki).
- **PDF**
- [X] All document types and features supported by HTML are also supported when exporting to PDF.
- **Plain text**
The desired document type can be set by calling the [`.doctype` function](https://quarkdown.com/wiki/document-types) within the source itself:
- `.doctype {plain}` (default)
- `.doctype {paged}`
- `.doctype {slides}`
- `.doctype {docs}`
# Comparison
| | Quarkdown | LaTeX | Typst | AsciiDoc | MDX |
|-----------------------|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|
| Concise and readable | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| Full document control[^control] | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :x: |
| Scripting | :white_check_mark: | Partial | :white_check_mark: | :x: | :white_check_mark: |
| Book/article export | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | Third-party |
| Presentation export | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | Third-party |
| Static site export | :white_check_mark: | :x: | Experimental | :white_check_mark: | :white_check_mark: |
| Docs/wiki export | :white_check_mark: | :x: | :x: | :white_check_mark: | :white_check_mark: |
| Learning curve | :green_circle: | :red_circle: | :orange_circle: | :green_circle: | :green_circle: |
| Targets | HTML, PDF, TXT | PDF, PostScript | HTML, PDF | HTML, PDF, ePub | HTML |
[^control]: The ability to customize the properties of the document and of its output artifact through the language itself.
<table>
<thead>
<tr>
<th>LaTeX</th>
<th>Quarkdown</th>
</tr>
</thead>
<tbody>
<tr>
<td>
```latex
\tableofcontents
\section{Section}
\subsection{Subsection}
\begin{enumerate}
\item \textbf{First} item
\item \textbf{Second} item
\end{itemize}
\begin{center}
This text is \textit{centered}.
\end{center}
\begin{figure}[!h]
\centering
\begin{subfigure}[b]
\includegraphics[width=0.3\linewidth]{img1.png}
\end{subfigure}
\begin{subfigure}[b]
\includegraphics[width=0.3\linewidth]{img2.png}
\end{subfigure}
\begin{subfigure}[b]
\includegraphics[width=0.3\linewidth]{img3.png}
\end{subfigure}
\end{figure}
```
</td>
<td>
```markdown
.tableofcontents
# Section
## Subsection
1. **First** item
2. **Second** item
.center
This text is _centered_.
.row alignment:{spacebetween}



```
</td>
</tr>
</tbody>
</table>
# Getting started
## Installation
### Install script (Linux/macOS)
```shell
curl -fsSL https://raw.githubusercontent.com/quarkdown-labs/get-quarkdown/refs/heads/main/install.sh | sudo env "PATH=$PATH" bash
```
Root privileges let the script install Quarkdown into `/opt/quarkdown` and its wrapper script into `/usr/local/bin/quarkdown`.
If missing, Java 17, Node.js and npm will be installed automatically using the system's package manager.
For more installation options, check out [get-quarkdown](https://github.com/quarkdown-labs/get-quarkdown).
### Homebrew (Linux/macOS)
```shell
brew install quarkdown-labs/quarkdown/quarkdown
```
### Install script (Windows)
```powershell
irm https://raw.githubusercontent.com/quarkdown-labs/get-quarkdown/refs/heads/main/install.ps1 | iex
```
### Scoop (Windows)
```shell
scoop bucket add java
scoop bucket add quarkdown https://github.com/quarkdown-labs/scoop-quarkdown
scoop install quarkdown
```
### GitHub Actions
See [setup-quarkdown](https://github.com/quarkdown-labs/setup-quarkdown) to easily integrate Quarkdown into your GitHub Actions workflows.
### Manual installation
<details>
<summary>Instructions for manual installation</summary>
Download `quarkdown.zip` from the [latest stable release](https://github.com/iamgio/quarkdown/releases/latest) and unzip it,
or build it with `gradlew installDist`.
Optionally, adding `<install_dir>/bin` to your `PATH` allows you easier access Quarkdown.
Requirements:
- Java 17 or higher
- (Only for PDF export) Node.js, npm, Puppeteer. See [*PDF export*](https://quarkdown.com/wiki/pdf-export) for details.
</details>
## Quickstart 🆕
New user? You'll find **everything you need** in the **[Quickstart guide](https://quarkdown.com/wiki/quickstart)** to bring life to your first document!
## Creating a project
**`quarkdown create [directory]`** will launch the prompt-based project wizard, making it quicker than ever
to set up a new Quarkdown project, with all [metadata](https://quarkdown.com/wiki/document-metadata) and initial content already present.
For more information about the project creator, check out its [wiki page](https://quarkdown.com/wiki/cli-project-creator).
Alternatively, you may manually create a `.qd` source file and start from there.
## Compiling
Running **`quarkdown c file.qd`** will compile the given file and save the output to file.
> If the project is composed by multiple source files, the target file must be the root one, i.e. the one that includes the other files.
>
> - [How to include other files?](https://quarkdown.com/wiki/including-other-quarkdown-files)
If you would like to familiarize yourself with Quarkdown instead, `quarkdown repl` lets you play with an interactive REPL mode.
#### Options
- **`-p`** or **`--preview`**: enables automatic content reloading after compiling.
If a [webserver](https://quarkdown.com/wiki/cli-webserver) is not running yet, it is started and the document is opened in the default browser.
This is required in order to render paged documents in the browser.
- **`-w`** or **`--watch`**: recompiles the source everytime a file from the source directory is changed.
> [!TIP]
> Combine `-p -w` to achieve ***live preview***!
- **`--pdf`**: produces a PDF file. Learn more in the wiki's [*PDF export*](https://quarkdown.com/wiki/pdf-export) page.
- `-o <dir>` or `--out <dir>`: sets the directory of the output files. Defaults to `./output`.
- `--out-name <name>`: sets the name of the output resource to be saved inside the output directory.
Defaults to the name of the document, set via [`.docname`](https://quarkdown.com/wiki/document-metadata).
*Note:* special characters will be replaced with dashes in the actual file name.
- `-l <dir>` or `--libs <dir>`: sets the directory where external libraries can be loaded from. Defaults to `<install dir>/lib/qd`. [(?)](https://quarkdown.com/wiki/importing-external-libraries)
- `-r <renderer>` or `--render <renderer>`: sets the target renderer. Defaults to `html`. Accepted values:
- `html`
- `html-pdf` (equivalent to `-r html --pdf`)
- `text` (plain text)
- `-b <browser>` or `--browser <browser>`: sets the browser to launch the preview with. Defaults to `default`. Accepted values:
- `default`
- `none`
- `xdg` (uses `xdg-open`). `default` falls back to this.
- `chrome`
- `chromium`
- `firefox`
- `edge` (Windows only)
- Any other name, backed by the `BROWSER_<NAME>` environment variable
- A full path to a browser executable
- `--server-port <port>`: optional customization of the local webserver's port. Defaults to `8089`.
- `--pipe`: outputs the generated content to stdout instead of saving it to file and suppresses other logs,
useful for piping to other commands.
- `--clean`: deletes the content of the output directory before producing new files. Destructive operation.
- `--strict`: forces the program to exit if an error occurs. When not in strict mode, errors are shown as boxes in the document.
- `--nowrap`: prevents the rendered output from being wrapped in a full document structure.
If enabled in HTML rendering, only the inner content of the `<body>` tag is produced.
- `--pretty`: produces pretty output code. This is useful for debugging or to read the output code more easily,
but it should be disabled in production as the results might be visually affected.
- `--no-media-storage`: turns the media storage system off. [(?)](https://quarkdown.com/wiki/media-storage)
- `--subdoc-naming <strategy>`: sets the subdocument output naming strategy [(?)](https://github.com/iamgio/quarkdown/wiki/subdocuments). Defaults to `file-name`. Accepted values:
- `file-name`: uses the subdocument's file name (human-readable, but prone to collisions)
- `collision-proof`: appends a hash to `file-name` to minimize name collisions
- `document-name`: uses the document name set via `.docname`, falling back to `file-name` if unset
- `-Dloglevel=<level>` (JVM property): sets the log level. If set to `warning` or higher, the output content is not printed out.
---
## Mock document
<p align="center">
<img width="550" src="https://raw.githubusercontent.com/iamgio/quarkdown/project-files/images/mock-demo.png" alt="Mock document demo">
</p>
***Mock***, written in Quarkdown, is a comprehensive collection of visual elements offered by the language,
making it ideal for exploring and understanding its key features — all while playing and experimenting hands-on with a concrete outcome in the form of pages or slides.
- The document's source files are available in the [`mock`](mock) directory, and can be compiled via `quarkdown c mock/main.qd -p`.
- The PDF artifacts generated for all possible theme combinations are available and can be viewed in the [`generated`](https://github.com/quarkdown-labs/generated) repo.
## Contributing
Contributions are welcome! Please check [CONTRIBUTING.md](CONTRIBUTING.md) to know how contribute via issues or pull requests.
## Sponsors
A special thanks to all the sponsors who [supported this project](https://github.com/sponsors/iamgio)!
<p align="center">
<a href="https://falconer.com"><img src="https://raw.githubusercontent.com/iamgio/quarkdown/project-files/images/sponsors/falconer.jpeg" alt="Falconer" width="350"></a>
</p>
<p align="center">
<a href="https://github.com/RayOffiah"><img src="https://avatars.githubusercontent.com/u/77050471?v=4" alt="RayOffiah" width="90"></a>
</p>
<p align="center">
<a href="https://github.com/vitto4"><img src="https://avatars.githubusercontent.com/u/128498605?v=4" alt="vitto4" width="60"></a>
</p>
<p align="center">
<a href="https://github.com/LunaBluee"><img src="https://avatars.githubusercontent.com/u/145209701?v=4" alt="LunaBluee" width="35"></a>
<a href="https://github.com/dcopia"><img src="https://avatars.githubusercontent.com/u/162327812?v=4" alt="dcopia" width="35"></a>
<a href="https://github.com/Pallandos"><img src="https://avatars.githubusercontent.com/u/146179143?v=4" alt="Pallandos" width="35"></a>
<a href="https://github.com/imogenxingren"><img src="https://avatars.githubusercontent.com/u/36161957?v=4" alt="imogenxingren" width="35"></a>
<a href="https://github.com/serkonda7"><img src="https://avatars.githubusercontent.com/u/40118727?v=4" alt="serkonda7" width="35"></a>
</p>
## Concept
The logo resembles the original [Markdown icon](https://github.com/dcurtis/markdown-mark), with focus on Quarkdown's completeness,
richness of features and customization options, emphasized by the revolving arrow all around the sphere.
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/iamgio/quarkdown/project-files/images/ticon-light.svg">
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/iamgio/quarkdown/project-files/images/ticon-dark.svg">
<img alt="Quarkdown icon" src="https://raw.githubusercontent.com/iamgio/quarkdown/project-files/images/ticon-dark.svg">
</picture>
</p>
What could be mistaken for a planet is actually a **quark** or, more specifically, a **down quark**,
an elementary particle that is a major constituent of matter: they give life to every complex structure we know of,
while also being one of the lightest objects in existence.
This is, indeed, the concept **Quarkdown** is built upon.
## License
By default, Quarkdown and its modules are licensed under [GNU GPLv3](./LICENSE), except for modules that include their own `LICENSE` file:
the CLI (`quarkdown-cli`) and Language Server (`quarkdown-lsp`) modules and binaries are licensed under GNU AGPLv3.
## Footnotes
================================================
FILE: build.gradle.kts
================================================
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.time.Year
plugins {
kotlin("jvm") version "2.3.10"
id("org.jetbrains.dokka") version "2.0.0"
id("org.jlleitschuh.gradle.ktlint") version "14.0.1"
id("com.github.ben-manes.versions") version "0.53.0"
id("se.patrikerdes.use-latest-versions") version "0.2.19"
application
}
group = "com.quarkdown"
version = file("version.txt").readText().trim()
allprojects {
repositories {
mavenCentral()
}
}
subprojects {
apply(plugin = "org.jetbrains.dokka")
apply(plugin = "org.jlleitschuh.gradle.ktlint")
apply(plugin = "com.github.ben-manes.versions")
apply(plugin = "se.patrikerdes.use-latest-versions")
}
// Fat JAR / Distribution dependencies
gradle.projectsEvaluated {
dependencies {
subprojects.forEach {
when {
it.extra.has("noRuntime") && it.extra["noRuntime"] == true -> {
compileOnly(it)
}
else -> {
implementation(it)
}
}
}
}
}
application {
mainClass.set("com.quarkdown.cli.QuarkdownCliKt")
}
ktlint {
version.set("1.7.1")
}
// Dokka
dokka {
dokkaPublications.html {
outputDirectory.set(
layout.buildDirectory
.file("docs")
.get()
.asFile,
)
}
}
/**
* Whether [project] uses the Quarkdoc plugin, which means its documentation must be included in the distribution zip.
*/
fun usesQuarkdoc(project: Project): Boolean {
val quarkdoc = project(":quarkdown-quarkdoc")
return project.configurations
.asSequence()
.flatMap { it.dependencies }
.filterIsInstance<ProjectDependency>()
.any { it.dependencyProject == quarkdoc }
}
val quarkdocGenerate =
tasks.register("quarkdocGenerate") {
group = "documentation"
description = "Generates the Quarkdoc documentation for modules that include the Quarkdoc plugin."
dependencies {
subprojects.filter(::usesQuarkdoc).forEach {
dokka(it)
}
}
dependsOn(tasks.dokkaGenerate)
}
tasks.register("quarkdocGenerateAll") {
group = "documentation"
description = "Generates the Quarkdoc documentation for all modules."
dependencies {
subprojects.forEach {
dokka(it)
}
}
dependsOn(tasks.dokkaGenerate)
}
allprojects {
fun asset(path: String): File = project(":quarkdown-quarkdoc").projectDir.resolve("src/main/resources/$path")
dokka {
pluginsConfiguration.html {
val year = Year.now().value
footerMessage.set("© $year Quarkdown")
customAssets.from(*asset("assets/images").listFiles()!!)
customStyleSheets.from(asset("styles/stylesheet.css"))
}
}
}
// Tasks
distributions.main {
contents {
// The module 'libs' contains .qd library files that are saved in lib/qd.
val librariesModule = project(":quarkdown-libs")
into("lib/qd") {
from(librariesModule.file("src/main/resources")) {
include("*.qd")
}
}
// Include the generated Dokka documentation, generated by quarkdocGenerate,
// in the 'docs' directory.
val dokkaOutputDir = layout.buildDirectory.file("docs")
from(dokkaOutputDir) {
into("docs")
}
}
}
tasks.installDist {
dependsOn(quarkdocGenerate)
}
tasks.distZip {
dependsOn(quarkdocGenerate)
archiveVersion.set("")
}
tasks.distTar {
dependsOn(quarkdocGenerate)
archiveVersion.set("")
}
tasks.test {
useJUnitPlatform()
dependsOn(tasks.ktlintCheck)
}
tasks.named<CreateStartScripts>("startScripts") {
classpath = files("lib/*") // Fixes the 'Input line is too long' error on Windows.
// Prepends subscripts to the generated start scripts.
doLast {
val dir = file("scripts")
val scripts = sequenceOf("bootstrap")
scripts.forEach { scriptName ->
val unixPrefix = dir.resolve("$scriptName.sh").readText() + "\n"
val windowsPrefix = dir.resolve("$scriptName.bat").readText() + "\n"
unixScript.writeText("#!/bin/sh\n\n" + unixPrefix + unixScript.readText())
windowsScript.writeText("@echo off\n\n" + windowsPrefix + windowsScript.readText())
}
}
}
tasks.wrapper {
gradleVersion = "8.3"
distributionType = Wrapper.DistributionType.ALL
}
tasks.withType<KotlinCompile> {
compilerOptions {
jvmTarget.set(JvmTarget.JVM_17)
}
}
tasks.register("printVersion") {
doLast {
println(project.version)
}
}
// Dependency updates
allprojects {
tasks.dependencyUpdates {
rejectVersionIf {
Regex("[.-](alpha|beta|rc|cr|m|preview|b|ea)", RegexOption.IGNORE_CASE) in candidate.version
}
}
tasks.useLatestVersions {
updateBlacklist =
listOf(
"org.jetbrains.kotlin",
"org.jetbrains.dokka",
)
}
}
================================================
FILE: demo/code/Point.java
================================================
public final class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
================================================
FILE: demo/csv/people.csv
================================================
"Username","Favorite food","Favorite beverage"
"john","Chicken","Orange juice"
"iamgio","Pasta","Iced tea"
"daniel","Sushi","Beer"
================================================
FILE: demo/demo.qd
================================================
.docname {Quarkdown demo}
.docauthor {iamgio}
.doctype {slides}
.doclang {English}
.theme {darko} layout:{minimal}
.autopagebreak maxdepth:{2}
.footer
.docauthor
**.docname**
[GitHub](https://github.com/iamgio/quarkdown)
.column
!(_x100)[Quarkdown logo](img/banner.svg)
Markdown with superpowers
# Versatile
**One source code, many use cases.**
Export your Quarkdown project as:
.function {poweredby}
credits:
.text {powered by .credits} size:{tiny} variant:{smallcaps}
- .fragment
beautiful slides for your next presentation, just like this one.
.poweredby {[reveal.js](https://revealjs.com/)}
- .fragment
a distinguished book.
.poweredby {[paged.js](https://pagedjs.org/)}
- .fragment
a plain document.
.fragment
.whitespace
*...in just one line, within your code.*
.row alignment:{center} gap:{5mm}
```
.doctype {slides}
```
```
.doctype {paged}
```
```
.doctype {plain}
```
# Same foundations...
.var {downarrow}
.container padding:{6px 0 16px 0}
.text {↓} weight:{bold} size:{large}
.var {rightarrow}
.text {->} weight:{bold} size:{large}
Quarkdown's base features follow [**CommonMark**](https://spec.commonmark.org/) and [**GitHub Flavored Markdown**](https://github.github.com/gfm/) specifications,
so that you'll feel at home typing code you're comfortable typing.
<!-- Shows a Quarkdown source as *both* its code AND its visual output. -->
<!-- Parameters: whether the output should be animated on interaction, -->
<!-- and whether the output should be displayed slightly above than expected (resets heading margin) -->
.function {sourceresult}
shrinkvertical? animated? horizontal? source:
.node
---
.var {snippet}
.code {markdown}
.source
.var {ishorizontal} {.horizontal::otherwise {no}}
.var {output}
.container alignment:{center} fullwidth:{yes}
.downarrow
.var {voffset} {.shrinkvertical::ifpresent {@lambda .1::multiply {-1}}::otherwise {0}}
.container textalignment:{center} margin:{.voffset 0 0 0} fullwidth:{yes}
.source
.ifnot {.ishorizontal}
.snippet
.let {.animated::otherwise {no}}
.if {.1}
.fragment
.output
.ifnot {.1}
.output
.if {.ishorizontal}
.row alignment:{spacearound}
.snippet
.rightarrow
.container textalignment:{center} width:{50%}
.source
.sourceresult shrinkvertical:{35} animated:{yes}
### Diving into _Quarkdown_
Somebody once said:
> Write once, run **anywhere**.
# ...brand-new everything
Go ahead to discover Quarkdown's capabilities.
# Functions
Call any function from the extensive [standard library](https://github.com/iamgio/quarkdown/tree/main/quarkdown-stdlib/src/main/kotlin/com/quarkdown/stdlib)
from your Markdown code.
```markdown
.somefunction {argument1} {argument2}
Body argument
```
.fragment
Or define your own:
```markdown
.function {greet}
to from:
**Hello, .to** from .from!
.greet {world} from:{Giorgio}
```
.fragment
.text {**Hello, world** from Giorgio!} size:{small}
## Full layout control
.sourceresult shrinkvertical:{50}
.row alignment:{center} gap:{1cm}
!(150x150)[Quarkdown](img/icon.png)
.column cross:{start}
.text {**Quarkdown is on GitHub!**} size:{large} variant:{smallcaps}
https://github.com/iamgio/quarkdown
## Multi-file project
.sourceresult shrinkvertical:{40}
.include {sources/other.qd}
.whitespace
.fragment
> Tip: functions declared in included files are imported as well.
> Use it to your advantage to make awesome libraries!
## File data: code
.sourceresult
The constructor of the class `Point` is as follows:
.code {java}
.read {code/Point.java} lines:{5..8}
## File data: CSV
.sourceresult
.csv {csv/people.csv}
## File data: Mermaid diagrams
.sourceresult
.mermaid
.read {mermaid/flow.mmd}
## Math
.sourceresult
.var {radius} {8}
If we try to calculate the **surface** of a circle of **radius .radius**,
we'll find out it's **.pow {.radius} to:{2}::multiply {.pi}::truncate {2}**
## Charts
.sourceresult horizontal:{yes}
.var {n} {100}
.xychart
.repeat {.n}
.1::pow {2}::divide {100}
.repeat {.n}
.1::logn::multiply {10}
<<<
.column gap:{16px}
## Scripting {#scripting-basic}
.text {Basic algorithm} size:{small}
.sourceresult
.row alignment:{spacearound}
.repeat {10}
n:
.if {.n::iseven}
**.n** is even
<<<
.column gap:{12px}
## Scripting {#scripting-fibonacci}
.text {Fibonacci sequence} size:{small}
.sourceresult shrinkvertical:{25}
.var {t1} {0}
.var {t2} {1}
.table
.foreach {0..8}
n:
| $ F_{.n} $ |
|:----------:|
| .t1 |
.var {tmp} {.sum {.t1} {.t2}}
.t1 {.t2}
.t2 {.tmp}
## Document customization
---
.container fullwidth:{yes}
.grid columns:{2} gap:{1cm}
**Metadata**
```markdown
.docname {Quarkdown demo}
.docauthor {iamgio}
.doctype {slides}
.doclang {english}
```
**Layout and aesthetics**
```markdown
.theme {darko} layout:{minimal}
.pageformat {A4} orientation:{landscape}
.slides transition:{zoom} speed:{fast}
```
**Fixed content on each page**
```markdown
.footer
.docauthor
**.docname**
[GitHub](https://github.com/iamgio/quarkdown)
```
## Intuitive error handling
.sourceresult shrinkvertical:{30}
.divide {x} by:{.pi}
.grid columns:{3} alignment:{right}
Hello, world!
# Enhanced base Markdown
**Not just functions.**
The Quarkdown flavor introduces new features to the standard Markdown syntax.
## TeX formulas
.sourceresult
Let $ F(u) $ be the ***Fourier Transform*** of the function $ f(x) $:
$ F(u) = \int^{+\infty}_{-\infty} f(x) e^{-i 2\pi x} dx $
.poweredby {[KaTeX](https://katex.org)}
## Alerts
.sourceresult shrinkvertical:{25}
> Note: did you know Quarkdown is a flexible tool to generate modern documents?
> Tip: you might want to try it out. Feedback and suggestions are welcome!
> Warning: it's a young project and some things may change in the near future.
## Footnotes (standard)
.sourceresult
Quarkdown[^qd] supports footnotes[^notes].
Take advantage of footnotes[^notes] to dive deeper into concepts.
[^qd]: A modern *typesetting system*.
[^notes]: This is what a footnote looks like.
## Footnotes (extension)
.sourceresult
Quarkdown[^: A modern *typesetting system*.] supports footnotes[^notes2: This is what a footnote looks like.].
Take advantage of footnotes[^notes2] to dive deeper into concepts.
## Quotation source
.sourceresult
> To be, or not to be, that is the question.
> - William Shakespeare, Hamlet
## Image size
.var {sizedimages}
<\!-- 200px width, auto height -->
!(200)[Quarkdown](img/banner.png)
<\!-- auto width, 2cm height -->
!(_*2cm)[Quarkdown](img/banner.png)
<\!-- 2-inch width, 2-centimeter height -->
!(2in*2cm)[Quarkdown](img/banner.png)
---
.code {markdown}
.sizedimages
.downarrow
.row alignment:{spaceevenly} cross:{center}
.sizedimages
## Labeled figure
.sourceresult shrinkvertical:{30}
!(150x_)[Quarkdown](https://iamgio.eu/quarkdown/img/icon-light.png "The Quarkdown icon")
## Color preview
.sourceresult
The color magenta's hexadecimal representation is `#FF00FF`.
The following are equivalent:
- `rgb(255, 0, 255)`
- `hsl(300, 100, 50)`
- `hsv(300, 100, 100)`
# It's a wrap
You've seen the **key features** of Quarkdown - the door to making stunning documents is now open.
The project is [open source](https://github.com/iamgio/quarkdown), still in development and **open to feedback and contributions**!
.box
The **source code** of this presentation is available [**here**](https://github.com/iamgio/quarkdown/tree/main/demo).
Future plans include tutorials, wikis and docs. But for now, happy coding!
.tableofcontents maxdepth:{2}
================================================
FILE: demo/mermaid/flow.mmd
================================================
flowchart LR
A([Start]) --> B[Enter username and password]
B --> C{Correct?}
C -- Yes --> D[Redirect to dashboard]
C -- No --> E[Show error message]
D --> F([END])
E --> F
================================================
FILE: demo/sources/other.qd
================================================
### Hello there!
This content was **included from another source**.
================================================
FILE: docs/_nav.qd
================================================
###! Getting started
- [Quickstart](quickstart.qd)
###! Documentation
- [Stable ↗](https://quarkdown.com/docs/quarkdown-stdlib/)
- [Latest build ↗](https://quarkdown.com/docs/latest/quarkdown-stdlib/)
###! Functions
- [Syntax of a function call](syntax-of-a-function-call.qd)
- [Chaining calls](syntax-of-a-function-call.qd#chaining-calls)
- [Block vs. inline calls](syntax-of-a-function-call.qd#block-vs-inline-function-calls)
- [Declaring functions](declaring-functions.qd)
- [Dynamic typing](typing.qd)
- [Localization](localization.qd)
###! Document setup
- [Document metadata](document-metadata.qd)
- [Document types](document-types.qd)
- [Theme](themes.qd)
- [Fonts](font-configuration.qd)
- [Page format](page-format.qd)
- [Multi-column layout](multi-column-layout.qd)
- [Page margin content](page-margin-content.qd)
- [Page counter](page-counter.qd)
- [Persistent headings](persistent-headings.qd)
- [Numbering](numbering.qd)
- [Paragraph style](paragraph-style.qd)
- [Caption position](caption-position.qd)
- [Table of contents](table-of-contents.qd)
- [Bibliography](bibliography.qd)
- [Footnotes](footnotes.qd)
###! Markdown enhancements
- [Figures](figure.qd)
- [Image size](image-size.qd)
- [TeX formulae](tex-formulae.qd)
- [Table caption](table-caption.qd)
- [Code caption](code-caption.qd)
- [Headings](headings.qd)
- [Decorative headings](headings.qd#decorative-headings)
- [Alerts (quote types)](quote-types.qd)
- [Quotation source](quotation-source.qd)
- [Cross-references](cross-references.qd)
- [Page breaks](page-break.qd)
- [Automatic break](page-break.qd#automatic-break)
- [Text symbols](text-symbols.qd)
- [Icons](icons.qd)
- [Emojis](emojis.qd)
###! Layout
- [Stacks: rows, columns, grids](stacks.qd)
- [Container](container.qd)
- [Align](align.qd)
- [Float](float.qd)
- [Figure](custom-figure.qd)
- [Clip](clip.qd)
- [Box](box.qd)
- [File tree](file-tree.qd)
- [Collapsible](collapsible.qd)
- [Landscape](landscape-content.qd)
- [Whitespace](whitespace.qd)
###! Multi-file projects
- [Including other Quarkdown files](including-other-quarkdown-files.qd)
- [Referencing other Quarkdown files](subdocuments.qd)
- [Including vs. referencing](inclusion-vs-subdocuments.qd)
- [Importing external libraries](importing-external-libraries.qd)
###! Variables & scripting
- [Variables](variables.qd)
- [Optionality](none.qd)
- [Math](math.qd)
- [Conditional statements](conditional-statements.qd)
- [Loops](loops.qd)
- [Let](let.qd)
- [Destructuring](destructuring.qd)
###! Data & tables
- [Table manipulation](table-manipulation.qd)
- [Table generation](table-generation.qd)
- [Text content from file](file-data.qd#file-text-content)
- [Table from CSV data](file-data.qd#table-from-csv)
###! Charts & diagrams
- [XY chart](xy-chart.qd)
- [Mermaid diagrams](mermaid-diagrams.qd)
###! Text & code
- [Advanced text formatting](text.qd)
- [Advanced code block](code.qd)
- [Explicit line breaks](line-breaks.qd)
- [TeX macros](tex-macros.qd)
###! Slides
- [Slides configuration](slides-configuration.qd)
- [Interactive fragment](slides-fragment.qd)
- [Speaker notes](slides-speaker-notes.qd)
###! Native content
- [HTML](html.qd)
- [CSS](css.qd)
###! Value types
- String
- Number
- [Markdown content](markdown-content.qd)
- [Boolean](boolean.qd)
- [None](none.qd)
- [Enumeration entry](enumeration-entry.qd)
- [Iterable](iterable.qd)
- [Dictionary](dictionary.qd)
- [Range](range.qd)
- [Lambda](lambda.qd)
- [Size(s)](sizes.qd)
- [Color](color.qd)
- [Dynamic](typing.qd)
###! Built-in libraries
- [Docs: documentation projects](docs-library.qd)
- [Paper: abstract, definitions, theorems](paper-library.qd)
###! Resources & logging
- [Media storage](media-storage.qd)
- [Logging](logging.qd)
###! CLI tools
- [Compiler](cli-compiler.qd)
- [Exporting to PDF](pdf-export.qd)
- [Project creator](cli-project-creator.qd)
- [Webserver](cli-webserver.qd)
###! Inside Quarkdown
- [Quarkdown's pipeline](pipeline.qd)
- [Lexing](pipeline---lexing.qd)
- [Parsing](pipeline---parsing.qd)
- [Function call expansion](pipeline---function-call-expansion.qd)
- [Tree traversal](pipeline---tree-traversal.qd)
- [Rendering](pipeline---rendering.qd)
- [Post-rendering](pipeline---post-rendering.qd)
- [How does live preview work?](inside-live-preview.qd)
================================================
FILE: docs/_setup.qd
================================================
.doclang {English}
.theme {galactic} layout:{hyperlegible}
.numbering
- example: 1
.html {.read {assets/analytics.html}}
.css {.read {assets/style.css}}
.var {repourl} {https://github.com/iamgio/quarkdown}
.function {repolink}
content href:
.text {.content} url:{.repourl/.href}
.function {docslink}
href:
.html {<sup><a href="https://quarkdown.com/docs/.href" target="_blank">docs ↗</a></sup>}
.function {example}
type? content:
.numbered key:{example}
num:
.box {Example .num} type:{.type::otherwise {tip}}
.content
.function {quarkdownoutput}
content:
.container classname:{quarkdown-output} fullwidth:{yes}
.content
.function {exampleoutput}
output prelude? type? quarkdowncode:
.example type:{.type}
.if {.prelude::isnone::not}
.prelude
.code lang:{markdown} linenumbers:{no}
.quarkdowncode
.container classname:{quarkdown-output} fullwidth:{yes}
.output
.function {examplemirror}
prelude? type? quarkdowncode:
.exampleoutput output:{.quarkdowncode} prelude:{.prelude} type:{.type} quarkdowncode:{.quarkdowncode}
.pagemargin {topleft}
.row gap:{12px}
[](https://quarkdown.com)
.read {../version.txt}::text classname:{version} url:{.repourl/releases/tag/latest}
.pagemargin {topright}
.row
[Docs](/docs)
---
[.icon {github}](https://github.com/iamgio/quarkdown)
================================================
FILE: docs/align.qd
================================================
.docname {Align}
.include {docs}
The **`.align`** block function sets the horizontal alignment of content, including multiline text alignment.
The primary parameter accepts the alignment type: `start`, `center`, or `end`. For convenience, **`.center`** is a shorthand for `.align {center}`.
.examplemirror
.align {end}
#! My document
.loremipsum
.examplemirror
.center
#! My document
.loremipsum
================================================
FILE: docs/assets/analytics.html
================================================
<script defer src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon='{"token": "7ff9d84e763543269faa5a5ae685ef9d"}'></script>
================================================
FILE: docs/assets/people.csv
================================================
"Username","Birth year","Favorite food","Favorite drink"
"john","1992","Chicken","Orange juice"
"iamgio","2002","Pasta","Iced tea"
"daniel","1986","Sushi","Beer"
================================================
FILE: docs/assets/people2.csv
================================================
Name, Favorite drink, Age *(as of 2026)*
Alice, Coffee, .subtract {2026} {1995}
Bob, *Pepsi*, .subtract {2026} {2001}
================================================
FILE: docs/assets/point.ts
================================================
export class Point {
x: number;
y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
}
================================================
FILE: docs/assets/sales.csv
================================================
Year, A Sales, B Sales
2017, 85, 230
2018, 100, 190
2019, 135, 180
2020, 180, 175
2021, 240, 200
2022, 320, 250
2023, 430, 290
2024, 580, 350
2025, 800, 470
================================================
FILE: docs/assets/style.css
================================================
.page-margin-top-left a {
display: flex;
}
header .version {
opacity: 0.6;
transform: translateY(2px);
}
.quarkdown-output {
padding: 12px 16px;
border-radius: 8px;
background-color: var(--box-header-background-color);
}
.quarkdown-output:empty::after {
content: "(No output)";
color: var(--qd-main-color-muted);
}
.quarkdown-output :is(h1, h2, h3, h4, h5, h6) {
padding: 0 !important;
border: none !important;
}
.quarkdown-output :is(h1, h2, h3, h4, h5, h6):first-child {
margin-top: 0 !important;
}
.quarkdown-output .file-tree:only-child {
margin-top: 0 !important;
margin-bottom: 0 !important;
}
.quarkdown-output img[src*="sky"] {
max-width: 50%;
}
.box:has(.quarkdown-output) pre {
margin-bottom: 16px !important;
}
================================================
FILE: docs/bibliography/file.bib
================================================
@article{einstein,
author = "Albert Einstein",
title = "Zur Elektrodynamik bewegter Körper. (German)
[On the electrodynamics of moving bodies]",
journal = "Annalen der Physik",
volume = "322",
number = "10",
pages = "891--921",
year = "1905",
DOI = "http://dx.doi.org/10.1002/andp.19053221004"
}
@book{hawking,
author = "Stephen Hawking",
title = "A Brief History of Time",
publisher = "Bantam Books",
year = "1988",
ISBN = "978-0553109535"
}
@book{latexcompanion,
author = "Michel Goossens and Frank Mittelbach and Alexander Samarin",
title = "The LaTeX Companion",
year = "1993",
publisher = "Addison-Wesley",
address = "Reading, Massachusetts"
}
================================================
FILE: docs/bibliography/source.qd
================================================
Einstein's publication .cite {einstein} in 1905 revolutionized the field of physics.
Similarly, Hawking's book .cite {hawking} has had a profound impact
on our understanding of cosmology and black holes.
---
.bibliography {/Users/gio/Dev/qd/quarkdown/docs/bibliography/file.bib} style:{ieee}
================================================
FILE: docs/bibliography.qd
================================================
.docname {Bibliography}
.include {docs}
Quarkdown provides CSL-powered bibliography support for the following bibliography formats:
- [BibTeX](https://www.bibtex.org) (`.bib`)
- CSL JSON (`.json`)
- YAML (`.yaml`/`.yml`)
- EndNote (`.enl`)
- RIS (`.ris`)
To get started, call the **`.bibliography {file}`** .docslink {quarkdown-stdlib/com.quarkdown.stdlib.module.bibliography/bibliography.html} function, where `file` is the path to your bibliography file, with extension. You can find some BibTeX examples [here](https://www.bibtex.com/e/entry-types/).
.examplemirror
.bibliography {bibliography/file.bib}
## Citations
You can cite one or more entries from the bibliography using the **`.cite {key}`** function.
Consider the following BibTeX entries:
```text
@article{einstein,
author = "Albert Einstein",
...
}
@book{hawking,
author = "Stephen Hawking",
...
}
```
You can cite them using their keys. Multiple keys can be specified as a comma-separated list
to produce a single combined citation label, whose format depends on the active [citation style](#style).
.examplemirror
Einstein's publication .cite {einstein} in 1905 revolutionized the field of physics.
Similarly, Hawking's book .cite {hawking} has had a profound impact
on our understanding of cosmology and black holes.
These works .cite {einstein, hawking} are foundational to modern physics.
## Style
The optional `style` parameter configures the look and format of the bibliography and its citation references.
It accepts a [CSL](https://citationstyles.org) (Citation Style Language) style identifier.
Quarkdown ships with a selection of citation styles from the [CSL Style Repository](https://github.com/citation-style-language/styles),
including `ieee` (default), `apa`, `chicago-author-date`, `nature`, `modern-language-association`, and many more.
```markdown
.bibliography {bibliography.bib} style:{apa}
```
.collapse {Full list of supported styles}
.code lang:{text} linenumbers:{no}
.read {../quarkdown-core/csl-styles.txt}
## Title
By default, the title is [localized](localization.qd) to the current locale set via `.doclang`, if supported. You can set a custom title using the `title` parameter.
.examplemirror
.bibliography {bibliography/file.bib} title:{My bibliography}
### Heading options
The heading that precedes the bibliography can be further customized with the following parameters:
| Parameter | Description | Accepts | Default |
|-----------------|-----------------------------------------------------------------------------------------------------------------------------------------|---------|---------|
| `headingdepth` | Depth of the heading that precedes the bibliography. | Integer | `1` |
| `breakpage` | Whether the heading triggers an automatic [page break](page-break.qd#automatic-break). | Boolean | `yes` |
| `numberheading` | Whether the heading should be [numbered](numbering.qd) and have its position tracked in the document hierarchy. | Boolean | `no` |
| `indexheading` | Whether the heading should be included in the document's [table of contents](table-of-contents.qd). Implicitly enables `numberheading`. | Boolean | `no` |
For example, depending on the current [auto page break](page-break.qd#automatic-break) configuration, the title may cause a page break. You can prevent this:
```markdown
.bibliography {file.bib} title:{My bibliography} breakpage:{no}
```
================================================
FILE: docs/boolean.qd
================================================
.docname {Boolean}
.include {docs}
Boolean values are represented by the following literals, which are **case insensitive**:
| Boolean value | Literals |
|---------------|---------------|
| **`true`** | `true`, `yes` |
| **`false`** | `false`, `no` |
Using the `yes` and `no` literals is encouraged because they contribute to a more natural language flow.
```markdown
.code linenumbers:{no}
My code
```
## Operators
The following operator functions return a `Boolean` value:
- `.not {bool}`: Negates a boolean. [Chaining](syntax-of-a-function-call.qd#chaining-calls) is recommended: `.bool::not`
- `.islower {a} {than}`: Returns `true` if `a` is less than `than`
- `.isgreater {a} {than}`: Returns `true` if `a` is greater than `than`
- `.isequal {a} {to}`: Returns `true` if `a` equals `to`
================================================
FILE: docs/box.qd
================================================
.docname {Box}
.include {docs}
The **`.box`** .docslink {quarkdown-stdlib/com.quarkdown.stdlib.module.Layout/box.html} function creates a special box container with an inline *title* and block *content*.
.examplemirror
.box {Box title}
Welcome to the **Quarkdown wiki**!
Here you'll learn how to get started with your first document.
You can omit the title:
.examplemirror
.box
Welcome to the **Quarkdown wiki**!
Here you'll learn how to get started with your first document.
## Box types
A box can have a type, which defaults to `callout` if not specified. The available types are:
- `callout`
- `tip`
- `note`
- `warning`
- `error`
.examplemirror
.box {Box title} type:{tip}
This is a tip box!
.box {Box title} type:{note}
This is a note box!
.box {Box title} type:{warning}
This is a warning box!
## Automatic localization
If you omit the title, set [`.doclang`](document-metadata.qd), and the locale is supported, the box title is automatically [localized](localization.qd).
.examplemirror
.box type:{tip}
This is a tip box!
.box type:{note}
This is a note box!
.box type:{warning}
This is a warning box!
> Tip: Boxes and [typed quotes](quote-types.qd) are two different ways to create typed alerts.
================================================
FILE: docs/caption-position.qd
================================================
.docname {Caption position}
.include {docs}
The **`.captionposition`** .docslink {quarkdown-stdlib/com.quarkdown.stdlib.module.Document/captionposition.html} function sets the global position of captions relative to the elements they describe.
This applies to:
- Figures
- [Figure Markdown extension](figure.qd)
- [`.figure`](custom-figure.qd)
- [Mermaid diagrams](mermaid-diagrams.qd) and derivatives such as [XY charts](xy-chart.qd)
- Tables
- [Table caption Markdown extension](table-caption.qd)
- [Tables from CSV](file-data.qd#table-from-csv)
- Code blocks
- [Code caption Markdown extension](code-caption.qd)
- [`.code`](code.qd)
---
The primary parameter, called `default`, sets the global style for all captioned elements. Additional parameters `figures`, `tables`, and `code` override the default position for those specific element types.
Each parameter is optional and accepts `top` or `bottom` values. Documents use `.captionposition {bottom}` by default.
.example
```markdown
.captionposition {bottom}

| Name | Favorite food | Favorite beverage |
|------|---------------|-------------------|
| John | Chicken | Orange juice |
| Jane | Pasta | Iced tea |
| Joe | Sushi | Beer |
"Survey results."
```

.example
```markdown
.captionposition {top}
```

.example
```markdown
.captionposition {bottom} tables:{bottom}
```

> Photo credits: [Pixabay](https://www.pexels.com/photo/blue-skies-53594/)
================================================
FILE: docs/cli-compiler.qd
================================================
.docname {CLI - Compiler}
.include {docs}
**`quarkdown c <file>`** is the command for compiling a main source file into a browser-renderable output.
For all available options, refer to the [README's *Compiling* section](https://github.com/iamgio/quarkdown?tab=readme-ov-file#compiling).
================================================
FILE: docs/cli-project-creator.qd
================================================
.docname {CLI - Project creator}
.include {docs}
The **project creator** is a CLI project wizard that makes it fast to set up a new Quarkdown project.
**`quarkdown create [directory]`** launches the wizard and generates the project files in the given directory (it will
be created if it does not exist). Not specifying a value for `directory` generates the files in the working directory.
The following information will be prompted via standard input, unless the corresponding option is set via command-line
arguments:
| Data | Additional info | Corresponding option | Generated Quarkdown function |
|---------------------------|----------------------------------------------------|----------------------|-----------------------------------------------|
| Project name | | `--name` | [`.docname`](document-metadata.qd) |
| Authors | Separated by commas | `--authors` | [`.docauthors`](document-metadata.qd#authors) |
| Document type | `paged`/`slides`/`plain` | `--type` | [`.doctype`](document-metadata.qd) |
| Document language | [Valid language tag or full name](localization.qd) | `--lang` | [`.doclang`](document-metadata.qd) |
| Color theme (unprompted) | | `--color-theme` | [`.theme`](themes.qd) |
| Layout theme (unprompted) | | `--layout-theme` | [`.theme`](themes.qd) |
Additional options:
- `--empty`: does not include sample initial content
- `--main-file <name>`: sets the name of the main `.qd` source file. Defaults to the name of the parent directory.
================================================
FILE: docs/cli-webserver.qd
================================================
.docname {CLI - Webserver}
.include {docs}
Quarkdown's webserver allows direct communication between the compiler and the browser, making [live previewing](inside-live-preview.qd) possible.
You can start the server via **`quarkdown start`**.
> [!IMPORTANT]
> A webserver is **mandatory** in order to show *paged* documents, because of a paged.js requirement.
> [!TIP]
> `quarkdown c ... -p` is shorthand for `quarkdown c ... && quarkdown start -f <generated file> -b default`
## Options
- **`-f <file>`** or **`--file <file>`**: (*mandatory*) the file the server should point to. It would preferably be the output directory of the compilation.
- **`-p <port>`** or **`--port <port>`**: the webserver's port. If unset, defaults to `8089`.
- **`-b <browser>`** or **`--browser <browser>`**: optional browser to open the served page on.
================================================
FILE: docs/clip.qd
================================================
.docname {Clip}
.include {docs}
The **`.clip {shape}`** block function clips its content to a defined shape.
Supported shapes:
- `circle`
.examplemirror

.clip {circle}

## Figures
When clipping a [figure](figure.qd), only the content is affected, leaving the caption intact:
.examplemirror

.clip {circle}

## General content
Clipping works with any content, not just images. Here a [container](container.qd) is used:
.examplemirror
.clip {circle}
.container padding:{2cm} background:{teal}
#! Hello!
================================================
FILE: docs/code-caption.qd
================================================
.docname {Code caption}
.include {docs}
Quarkdown introduces code captions, which you can set by adding a caption directly in the code block declaration. Place the caption after the language identifier, wrapped in double quotes, single quotes, or parentheses. This syntax is the same as the image *title* attribute and [table captions](table-caption.qd).
.examplemirror
```python "Fibonacci function"
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
```
Equivalently, via the [`.code`](code.qd) function:
.examplemirror
.code lang:{python} caption:{Fibonacci function}
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
## Numbering
You can also **number** code blocks, to display a sequential number alongside the caption. See [Numbering](numbering.qd) for more information.
================================================
FILE: docs/code.qd
================================================
.docname {Code}
.include {docs}
You can create code blocks using the standard Markdown specification: either with 4-space or 1-tab indentation, or with triple backticks or tildes.
.examplemirror
```javascript
function greet(name) {
return `Hello, ${name}!`;
}
```
Quarkdown also provides a more powerful **`.code`** .docslink {quarkdown-stdlib/com.quarkdown.stdlib.module.Text/code.html} block function.
.examplemirror
.code lang:{javascript}
function greet(name) {
return `Hello, ${name}!`;
}
## `.code` vs. standard code blocks
### Content processing
Standard code blocks render their content as-is without any processing. The `.code` function, on the other hand, accepts any Quarkdown string as its body parameter, which means you can **evaluate functions** before displaying their output as code. This is particularly useful when combining `.code` with [`.read`](file-data.qd) to load a code snippet from a file:
.examplemirror
.code
.read {assets/point.ts}
### Language specification
Standard fenced code blocks specify their language right after the opening delimiter, for example ` ```markdown `.
The `.code` function specifies the language through the optional `lang` argument, for example `.code {markdown}` or `.code lang:{markdown}`. If unspecified, auto-detection is attempted.
.examplemirror
.code lang:{typescript}
.read {assets/point.ts}
### Line numbers
Standard code blocks always show line numbers by default. The `.code` function lets you toggle line numbers using the optional `linenumbers` [`Boolean`](boolean.qd) argument, which defaults to `yes` (equivalent to `true`).
.examplemirror
.code linenumbers:{no}
.read {assets/point.ts}
### Focused lines
The `.code` function allows you to focus on a [`Range`](range.qd) of lines, starting from `1`. Line numbers must be enabled for this feature to work.
.examplemirror
.code focus:{5..8}
.read {assets/point.ts}
## Inline code
Just as `.code` is a dynamic alternative to triple backticks (`` ``` ``), **`.codespan {text}`** is a dynamic alternative to inline backticks (`` `text` ``). This allows function calls within its content.
================================================
FILE: docs/collapsible.qd
================================================
.docname {Collapsible}
.include {docs}
The **`.collapse`** function creates an interactive collapsible block that users can toggle by clicking.
The function requires an [inline](markdown-content.qd#inline-content) title, which is always displayed, and [block](markdown-content.qd#block-content) content, which appears when expanded.
.examplemirror
.collapse {A _collapsible_ block. **Click me!**}
You found this hidden content.
**Surprise!**
You can change the initial state of the block using the optional `open` [`Boolean`](boolean.qd) argument, which defaults to `false` (collapsed).
.examplemirror
.collapse {A _collapsible_ block. **Click me!**} open:{yes}
Not so hidden content anymore!
================================================
FILE: docs/color.qd
================================================
.docname {Color}
.include {docs}
You can define a `Color` value in any of the following ways:
- **Hexadecimal:** `#hex`
- `#4290F5`
- **RGB:** `rgb(red 0-255, green 0-255, blue 0-255)`
- `rgb(66, 144, 245)`
- **RGBA:** `rgba(red 0-255, green 0-255, blue 0-255, alpha 0-1)`
- `rgba(66, 144, 245, 0.8)`
- **HSV:** `hsv(hue, saturation 0-100, value 0-100)`
- `hsv(214, 73, 96)`
- **HSL:** `hsl(hue, saturation 0-100, lightness 0-100)`
- `hsl(214, 90, 61)`
- **Named:** A [CSS3 color](https://www.w3schools.com/cssref/css_colors.php) name, case-insensitive, without dashes
- `blue`, `darkorange`, `white`
When you write a color in a code span (wrapped in backticks), Quarkdown automatically displays a small preview box next to it. This works for all color formats except named colors.
================================================
FILE: docs/conditional-statements.qd
================================================
.docname {Conditional statements}
.include {docs}
The **`.if`** function creates a conditional statement:
1. The first parameter is the condition ([`Boolean`](boolean.qd)) to evaluate.
2. The second parameter is a parameter-less [lambda](lambda.qd) that runs only if the condition is true.
.examplemirror
.if {yes}
Hello, Quarkdown!
## Nesting
The function returns the lambda's result if the condition is satisfied, or nothing otherwise. This means the function *propagates* its content up the call stack.
.examplemirror
<!-- Read this from bottom to top -->
.if {yes}
.if {no}
.if {yes}
.if {yes}
Hello!
This behavior lets you use the function as part of any expression. For example, you can use it to conditionally include content inside layout functions, such as [stacks](stacks.qd).
.examplemirror
.row gap:{1cm}
A
.if {.iseven {3}}
B
C
## Negation
The **`.ifnot`** function is a shorthand that inverts `.if`'s behavior, returning a value only if the condition is *not* satisfied.
Quarkdown does not yet have an *else* statement, but you can emulate one using the [`.let`](let.qd) function:
.examplemirror
.let {.iseven {3}}
condition:
.if {.condition}
3 is even!
.ifnot {.condition}
3 is odd!
> Tip: `.ifnot {.condition}` is equivalent to `.if {.condition::not}`
================================================
FILE: docs/container.qd
================================================
.docname {Container}
.include {docs}
The **`.container`** .docslink {quarkdown-stdlib/com.quarkdown.stdlib.module.Layout/container.html} function creates a highly customizable block of content, and resets the current layout rules back to normal.
## Layout reset
.examplemirror {Imagine you want to create a row with two columns, each containing a heading and some text. A beginner might try the following *wrong* approach. As explained in the [Stacks](stacks.qd) page, stack functions rely on the strict Markdown concept of a block, an isolated chunk of the document, to determine which elements they handle.} type:{warning}
<!-- WRONG! -->
.row alignment:{center} gap:{1cm}
##! Left
Text on left column.
##! Right
Text on right column.
.examplemirror {You might then try using columns. This works, but the concept is not quite right. You do not want a *layout rule*; you just want to reset the document flow back to normal. This is exactly what the container does: it groups elements together according to the natural flow of the document.} type:{warning}
<!-- Could be improved -->
.row alignment:{center} gap:{1cm}
.column cross:{start}
##! Left
Text on left column.
.column cross:{start}
##! Right
Text on right column.
.examplemirror {The correct way to achieve the desired layout is to use containers. Each container resets the layout rules, allowing the row to treat them as separate blocks of content.}
<!-- Correct! -->
.row alignment:{center} gap:{1cm}
.container
##! Left
Text on left column.
.container
##! Right
Text on right column.
## Styling
The following optional parameters are available:
| Parameter | Description | Accepts | Default |
|-----------|-------------|---------|---------|
| `width` | Box width constraint. | [`Size`](sizes.qd) | No constraint |
| `height` | Box height constraint. | [`Size`](sizes.qd) | No constraint |
| `fullwidth` | Whether to take up the parent's full width. Overridden by `width`. | [`Boolean`](boolean.qd) | False |
| `foreground` | Text color. | [`Color`](color.qd) | Document's default |
| `background` | Background color. | [`Color`](color.qd) | None |
| `border` | Border color. | [`Color`](color.qd) | Browser's default if `borderwidth` is set, none otherwise |
| `borderwidth` | Border size. | [`Sizes`](sizes.qd) | Browser's default if `border` is set, none otherwise |
| `borderstyle` | Border type. | `normal`, `dashed`, `dotted`, `double` | `normal` if `border` or `borderwidth` is set, none otherwise |
| `margin ` | Whitespace outside the content. | [`Sizes`](sizes.qd) | None |
| `padding ` | Whitespace around the content. | [`Sizes`](sizes.qd) | None |
| `radius` | Corner or border radius. | [`Sizes`](sizes.qd) | None |
| `alignment` | Content alignment. | `start`, `center`, `end` | Browser's default |
| `textalignment` | Text alignment. | `start`, `center`, `end`, `justify` | Browser's default |
| `fontsize`, `fontweight`, `fontstyle`, `fontvariant`, `textdecoration`, `textcase` | Text transformation. See [Advanced text formatting](text.qd) for details. | | None |
| `classname` | Custom CSS class name. | String | None |
.examplemirror
.container fullwidth:{yes} borderstyle:{dashed} padding:{1cm} fontsize:{medium} fontstyle:{italic} fontvariant:{smallcaps}
This is a styled container. Fancy, isn't it?
Quarkdown can truly give life to complex layouts with ease.
================================================
FILE: docs/cross-references.qd
================================================
.docname {Cross references}
.include {docs}
In typesetting, cross-references are references to other parts of the document, such as figures, tables, sections, and equations.
In Quarkdown, you create a cross-reference using the **`.ref {id}`** function, where `id` is the cross-reference ID of the target element. The function can appear either before or after the target element.
> Note: Cross-referencing works best when elements are numbered, and you have set a supported document language.
> See [Numbering](numbering.qd) and [Localization](localization.qd) for details.
You typically set the ID using the `{#id}` syntax. The exact location depends on the element type, as the following sections explain.
### Sections
.exampleoutput {}
Once you install Quarkdown, check out .ref {getting-started} for a quick guide.
## Getting started {#getting-started}
> Tip: In HTML rendering, the reference ID of headings also becomes the HTML `id` attribute, which makes them suitable for linking.
### Figures
.exampleoutput {}
The Quarkdown logo is shown in .ref {logo}.
 {#logo}
### Tables
.exampleoutput {}
As shown in .ref {data}, coffee is the most popular beverage.
| Person | Beverage |
|---------|----------|
| Alice | Tea |
| Bob | Coffee |
| Charlie | Coffee |
{#data}
.example
With a [caption](table-caption.qd):
```markdown
| Person | Beverage |
|---------|----------|
| Alice | Tea |
| Bob | Coffee |
| Charlie | Coffee |
"Beverage preferences" {#data}
```
### Equations
.exampleoutput {}
Einstein's famous equation is shown in .ref {energy}.
$ E = mc^2 $ {#energy}
.example
For multi-line equations:
```markdown
$$$ {#energy}
E = mc^2
$$$
```
> Tip: See [TeX Formulae](tex-formulae.qd) for more information on writing equations in Quarkdown.
### Code blocks (listings)
.exampleoutput {}
See the main function in .ref {main}.
```kotlin {#main}
fun main() {
println("Hello, World!")
}
```
.example
With a [caption](code-caption.qd):
~~~markdown
```kotlin "Hello World in Kotlin" {#main}
fun main() {
println("Hello, World!")
}
```
~~~
### Custom numbered elements
> The `.numbered` function is explained in detail in [Numbering](numbering.qd#custom-numbered-elements).
.exampleoutput {}
In Example .ref {my-example} you can see a custom numbered element.
.numbered {examples} ref:{my-example}
number:
**Example .number:** this is a custom numbered element.
================================================
FILE: docs/css.qd
================================================
.docname {CSS}
.include {docs}
The **`.css`** .docslink {quarkdown-stdlib/com.quarkdown.stdlib.module.Injection/css.html} function lets you apply CSS styles to the document.
> [!WARNING]
> CSS styles only apply to HTML and HTML-PDF documents. They have no effect on other output formats.
>
> See the [HTML](html.qd) page for more details on this topic.
```css
.css
body {
background-color: green;
}
h1 {
color: pink;
}
```
You can also load CSS styles from a file using the [`.read`](file-data.qd) function:
```markdown
.css {.read {styles.css}}
```
> [!NOTE]
> Unlike [`.code`](code.qd), the `.css` function does not allow function calls inside its body argument because they would be ambiguous with CSS syntax.
>
> For this reason, you must inline the `.read` call as shown in the previous example.
## Custom classes
You can assign custom CSS class names to specific elements using the `classname` parameter, which is available in [`.container`](container.qd) for blocks and [`.text`](text.qd) for inline elements.
.examplemirror
.container classname:{my-custom-class}
This is a block with a custom class.
- Item 1
- Item 2
- Item 3
This is an .text {inline text} classname:{my-custom-class} with a custom class.
.css
.my-custom-class {
padding: 8px;
border-radius: 8px;
background: linear-gradient(to right, blue 0%, forestgreen 100%);
}
## Custom reusable elements
You can leverage [custom functions](declaring-functions.qd) to create reusable elements with custom classes.
.examplemirror
.function {mytext}
content:
.text {.content} classname:{my-custom-class}
This is a .mytext {text} and here is .mytext {another}.
## Overriding properties
If you want to *override* Quarkdown's default styles, we recommend using the **`.cssproperties`** .docslink {quarkdown-stdlib/com.quarkdown.stdlib.module.Injection/cssproperties.html} function.
This function takes a [dictionary](dictionary.qd) of strings, where each item is a `--qd-*` CSS property and its value.
You can find a complete list of available properties in the [global theme source](https://github.com/iamgio/quarkdown/blob/main/quarkdown-html/src/main/scss/global.scss). Unknown properties are safely ignored.
.example
```yaml
.cssproperties
- background-color: green
- heading-color: pink
- block-margin: 12px
```
.box {Why is this preferred over `\.css`?}
Quarkdown's themes use CSS custom properties for more granular control and easier overrides. For instance, the same property may be applied differently depending on the document type.
When you call functions like [`.pageformat`](page-format.qd) or [`.paragraphstyle`](paragraph-style.qd), they apply their effects by injecting the corresponding `--qd-*` properties.
Overriding a `--qd-*` property rather than its raw CSS equivalent provides smoother control and reduces the risk of future breaking changes.
================================================
FILE: docs/custom-figure.qd
================================================
.docname {Custom figure}
.include {docs}
.numbering
- figures: 1
The **`.figure {caption?} {body}`** function generalizes the [image figures](figure.qd) syntax extension by allowing any content to be treated as a *figure* block. This means the content:
- Can have a caption
- Can be numbered - see [Numbering](numbering.qd)
.examplemirror
.figure caption:{My caption.}
.container padding:{1cm} background:{teal}
Hello, world!
================================================
FILE: docs/declaring-functions.qd
================================================
.docname {Declaring functions}
.include {docs}
You can declare functions using the **`.function`** .docslink {quarkdown-stdlib/com.quarkdown.stdlib.module.Flow/function.html} function (in Quarkdown, everything is a function!).
It accepts two arguments: the function name and its body. The function can then be invoked as a normal function call - see [Syntax of a function call](syntax-of-a-function-call.qd).
.examplemirror
.function {helloworld}
Hello, world!
.helloworld
## Parameters
The body parameter is a [lambda](lambda.qd), and each parameter of the function is a parameter of the lambda block. You can access each argument within the function body as a [variable](variables.qd), which in Quarkdown is essentially a function with no parameters.
.examplemirror
.function {greet}
to from:
Hello, .to from .from!
.greet {world} {John}
> Tip: You can name arguments to improve readability:
>
> ```markdown
> .greet {world} from:{John}
> ```
### Optional parameters
If a function parameter ends with a question mark `?`, it becomes optional. When you do not provide the corresponding argument, it receives the value [`None`](none.qd).
.examplemirror
.function {greet}
to from?:
Hello, .to from .from!
.greet {world}
.greet {world} {John}
`None` provides several useful [operations](none.qd#operations), such as `.otherwise` for placeholders that emulate default parameter values.
.examplemirror
.function {greet}
to from?:
Hello, .to from .from::otherwise {unnamed}!
.greet {world}
.greet {world} {John}
### Block parameters
Block arguments always correspond to the last parameter of a function. There is no special syntax to declare them; just define the function as usual.
.examplemirror
.function {myexample}
title content:
.box {.title}
.content
.myexample {Example title}
This is the content of the example.
## Returning values
In Quarkdown, there are no return statements. Every reached instruction becomes part of the output - see [Conditional statements](conditional-statements.qd).
.examplemirror
.function {myfunction}
.if {.iseven {3}}
A
B
.myfunction
Functions can return any Markdown content.
.examplemirror
.function {greet}
to from:
**Hello, .to** from .from!
.greet {world} from:{John}
Quarkdown is [weakly typed](typing.qd), so functions can return any type of value.
.examplemirror
.function {area}
width height:
.multiply {.width} by:{.height}
The area of the rectangle is **.area {4} {2}**.
.examplemirror
.function {isadult}
age:
.age::isgreater than:{18}
.if {.isadult age:{20}}
You're an adult!
================================================
FILE: docs/destructuring.qd
================================================
.docname {Destructuring}
.include {docs}
Destructuring splits a [lambda](lambda.qd) parameter into its individual components. For instance, a [pair](iterable.qd#pair) has two components, while a generic [iterable](iterable.qd) can have many.
The following types support destructuring:
- [`Iterable`](iterable.qd), including [`Pair`](iterable.qd#pair)
- [`Dictionary`](dictionary.qd), as an iterable of pairs
A value is destructured into `N` components when all of the following conditions are met:
- The type supports destructuring
- The lambda expects a single argument, such as with [`.foreach`](loops.qd)
- You supply `N > 1` lambda parameters
When Quarkdown destructures the lambda argument, it operates on the individual components rather than the element itself.
## Example: `.foreach`
In this example, we define a [Dictionary](dictionary.qd) and iterate over its destructured key-value components.
.examplemirror
.var {mydictionary}
.dictionary
- a: 1
- b: 2
- c: 3
.foreach {.mydictionary}
key value:
**.key** has value **.value**
## Example: `.sorted`
In this example, we define a [Dictionary](dictionary.qd) and iterate over its destructured key-value components using `.foreach`, but only after sorting its entries by value using [`.sorted`](iterable.qd#operations), which takes a lambda that defines the ordering criteria.
> Note: Remember that `@lambda` is required when declaring an [inline lambda](lambda.qd#inline-lambda).
.examplemirror
.var {mydictionary}
.dictionary
- a: 3
- b: 1
- c: 2
.foreach {.mydictionary::sorted by:{@lambda name value: .value}}
name value:
.name
================================================
FILE: docs/dictionary.qd
================================================
.docname {Dictionary}
.include {docs}
In Quarkdown, a dictionary is a collection of key-value pairs without duplicate keys. Keys are always strings, while values can be any type.
The dictionary syntax resembles YAML and uses Markdown lists:
```yaml
- key1: value1
- key2: value2
- key3: value3
```
Since this syntax overlaps with [Iterable](iterable.qd) syntax, you can wrap the dictionary declaration in a **`.dictionary`** function to remove ambiguity when both types are accepted.
.examplemirror prelude:{[`\.foreach`](loops.qd) accepts both iterables and dictionaries, so we explicitly create a dictionary to iterate over key-value pairs, and [destructure](destructuring.qd) them into separate variables.}
.var {mydictionary}
.dictionary
- key1: value1
- key2: value2
- key3: value3
.foreach {.mydictionary}
key value:
**.key**: .value
You can nest dictionaries when the function supports it, such as [`.localization`](localization.qd#creating-your-own-localized-strings):
```yaml
- English:
- greeting: Hello
- food: Fish and chips
- Italian:
- greeting: Ciao
- food: Pasta
```
Trailing colons before nested dictionaries are optional:
```yaml
- English
- greeting: Hello
- food: Fish and chips
- Italian
- greeting: Ciao
- food: Pasta
```
## Operations
You can pass a dictionary to any function that accepts an [iterable](iterable.qd#operations), where it is treated as an iterable of pairs.
For a complete list of dictionary operations, see the [Dictionary documentation](https://quarkdown.com/docs/quarkdown-stdlib/com.quarkdown.stdlib.module.Dictionary) in the standard library.
================================================
FILE: docs/docs-library.qd
================================================
.docname {Docs library}
.include {docs}
The built-in .repolink {`docs`} {blob/main/quarkdown-libs/src/main/resources/docs.qd} library is written in Quarkdown and provides the standard structure for a [`docs` document](document-types.qd#docs-docs), with sidebars, navigation, and a table of contents.
This library is the recommended way to set up a documentation project, and it is what this wiki uses. It wraps the raw `.doctype {docs}` setup into a simple, customizable include.
> Note: When creating a project via [`quarkdown create`](cli-project-creator.qd), the generated project is already set up to use the `docs` library.
The first step is to [import](importing-external-libraries.qd) the library:
```markdown
.include {docs}
```
> Note: You do not need to call `.doctype {docs}` yourself. The library handles it.
## Project structure
A project that uses the `docs` library is expected to have a similar structure:
.filetree
- **_setup.qd**
- **_nav.qd**
- **main.qd**
- page-1.qd
- page-2.qd
- ...
- **`_setup.qd`**, containing shared configuration such as [themes](themes.qd), [fonts](font-configuration.qd), custom [functions](declaring-functions.qd) and [variables](variables.qd). This file is included automatically by the library.
- **`_nav.qd`** containing the navigation links that populate the page list sidebar. This file is included automatically by the library.
- **`main.qd`**, the home page of the documentation, and entry point of the compilation.
- Each other `.qd` file is a [subdocument](subdocuments.qd), and should include the library at the top:
```markdown
.docname {My page}
.include {docs}
Content goes here.
```
The library takes care of the following:
1. Setting the document type to `docs`
2. Including `_setup.qd` from the project root
3. Placing the navigation from `_nav.qd` in the left sidebar via [`.pagemargin`](page-margin-content.qd) and [`.navigation`](https://quarkdown.com/docs/quarkdown-stdlib/com.quarkdown.stdlib.module.Document/navigation-container.html)
4. Placing a [table of contents](table-of-contents.qd) in the right sidebar
5. Adding a [decorative heading](headings.qd#decorative-headings) from [`.docname`](document-metadata.qd)
## Setup file
The `_setup.qd` file is a good place for project-wide configuration shared across all subdocuments.
.example
> `_setup.qd`
```markdown
.doclang {English}
.theme {darko} layout:{minimal}
.pagemargin {topright}
[GitHub](https://github.com/iamgio/quarkdown)
```
## Navigation file
The `_nav.qd` file contains the links that appear in the page list sidebar. It consists of a list of links to subdocuments, optionally grouped by [decorative headings](headings.qd#decorative-headings):
.example
> `_nav.qd`
```markdown
###! Getting started
- [Quickstart](quickstart.qd)
###! Topics
- [Page 1](page-1.qd)
- [Page 2](page-2.qd)
- [Section A](page-2.qd#section-a)
```
The current page is automatically highlighted in the sidebar.
## Customization
By default, the page list appears in the left sidebar and the table of contents in the right sidebar.
You can swap or change these positions by overriding two variables in your `_setup.qd` file:
| Variable | Default | Description |
|--------------------|------------|---------------------------------------------------------------------|
| `pagelistposition` | `lefttop` | [Position](page-margin-content.qd) of the page list sidebar |
| `tocposition` | `righttop` | [Position](page-margin-content.qd) of the table of contents sidebar |
.example
> `_setup.qd`
```markdown
.theme {darko}
.pagelistposition {righttop}
.tocposition {lefttop}
```
## Orphan pages
Note that, by design, Quarkdown does not compile orphan source files. In order to be compiled as a [subdocument](subdocuments.qd), a source file must be referenced by another file, be it in `_nav.qd` or in the content of another page.
================================================
FILE: docs/document-metadata.qd
================================================
.docname {Document metadata}
.include {docs}
You can set document information using the following functions. By convention, you should call these functions at the beginning of your Quarkdown source.
| Name | Accepts | Default |
|-------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------|
| `.docname` | The name of the document. | `Untitled Quarkdown Document` |
| `.docdescription` | A short description of the document. | (empty) |
| `.docauthors` | The authors of the document. | (empty) |
| `.dockeywords` | Keywords associated with the document, as an [iterable](iterable.qd). | (empty) |
| `.doctype` | Type of output document: `plain`, `slides`, `paged`, `docs`. See [Document types](document-types.qd) for more information. | `plain` |
| `.doclang` | The language of the document: either a case-insensitive English full name (such as `English`, `Italian`, `French (Canada)`) or an IETF BCP 47 language tag (such as `en`, `it`, `fr-CA`). .br This setting defines the target locale for content localization, locale-specific styles like Chinese fonts for Chinese locales, and the HTML `lang` attribute for hyphenation and accessibility. See [Localization](localization.qd) for more. | (none) |
## Modify-or-echo
All these functions have a *modify or echo* behavior: if you call them without an argument, they return the previously set value:
.exampleoutput {This document is named **Quarkdown**!}
.docname {Quarkdown}
This document is named **.docname**!
## Authors
The `.docauthors` function sets the document's authors.
```markdown
.docauthors
- John Doe
- Jane Doe
```
The function takes a [Dictionary](dictionary.qd) as its value, where each key is the author's name and values are nested dictionaries containing author in
gitextract_3z3aa1yn/ ├── .dockerignore ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.yml │ │ ├── config.yml │ │ └── enhancement.yml │ ├── PULL_REQUEST_TEMPLATE.md │ ├── actions/ │ │ ├── bump-scoop/ │ │ │ └── action.yml │ │ ├── deploy-wiki/ │ │ │ └── action.yml │ │ ├── setup-environment/ │ │ │ └── action.yml │ │ └── update-emoji-list/ │ │ ├── action.yml │ │ └── generate.qd │ └── workflows/ │ ├── deploy-wiki.yml │ ├── generate-pdf/ │ │ ├── color.txt │ │ ├── generate-theme-combinations.js │ │ └── layout.txt │ ├── generate-pdf.yml │ ├── gradle-deploy.yml │ ├── gradle-test.yml │ └── update-emoji-list.yml ├── .gitignore ├── .run/ │ ├── CLI_Docs.run.xml │ ├── CLI_Mock.run.xml │ ├── Lint_format.run.xml │ ├── Test_full_suite.run.xml │ └── Test_minimal_suite.run.xml ├── CHANGELOG.md ├── CLAUDE.md ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── README.md ├── build.gradle.kts ├── demo/ │ ├── code/ │ │ └── Point.java │ ├── csv/ │ │ └── people.csv │ ├── demo.qd │ ├── mermaid/ │ │ └── flow.mmd │ └── sources/ │ └── other.qd ├── docs/ │ ├── _nav.qd │ ├── _setup.qd │ ├── align.qd │ ├── assets/ │ │ ├── analytics.html │ │ ├── people.csv │ │ ├── people2.csv │ │ ├── point.ts │ │ ├── sales.csv │ │ └── style.css │ ├── bibliography/ │ │ ├── file.bib │ │ └── source.qd │ ├── bibliography.qd │ ├── boolean.qd │ ├── box.qd │ ├── caption-position.qd │ ├── cli-compiler.qd │ ├── cli-project-creator.qd │ ├── cli-webserver.qd │ ├── clip.qd │ ├── code-caption.qd │ ├── code.qd │ ├── collapsible.qd │ ├── color.qd │ ├── conditional-statements.qd │ ├── container.qd │ ├── cross-references.qd │ ├── css.qd │ ├── custom-figure.qd │ ├── declaring-functions.qd │ ├── destructuring.qd │ ├── dictionary.qd │ ├── docs-library.qd │ ├── document-metadata.qd │ ├── document-types.qd │ ├── emojis.qd │ ├── enumeration-entry.qd │ ├── figure.qd │ ├── file-data.qd │ ├── file-tree.qd │ ├── float.qd │ ├── font-configuration.qd │ ├── footnotes.qd │ ├── headings.qd │ ├── html.qd │ ├── icons.qd │ ├── image-size.qd │ ├── importing-external-libraries.qd │ ├── including-other-quarkdown-files.qd │ ├── inclusion-vs-subdocuments.qd │ ├── inside-live-preview.qd │ ├── iterable.qd │ ├── lambda.qd │ ├── landscape-content.qd │ ├── let.qd │ ├── line-breaks.qd │ ├── localization.qd │ ├── logging.qd │ ├── loops.qd │ ├── main.qd │ ├── markdown-content.qd │ ├── math.qd │ ├── media-storage.qd │ ├── mermaid-diagrams.qd │ ├── multi-column-layout/ │ │ └── source.qd │ ├── multi-column-layout.qd │ ├── none.qd │ ├── numbering.qd │ ├── page-break.qd │ ├── page-counter.qd │ ├── page-format.qd │ ├── page-margin-content.qd │ ├── paper-library.qd │ ├── paragraph-style.qd │ ├── pdf-export.qd │ ├── persistent-headings.qd │ ├── pipeline---function-call-expansion.qd │ ├── pipeline---lexing.qd │ ├── pipeline---parsing.qd │ ├── pipeline---post-rendering.qd │ ├── pipeline---rendering.qd │ ├── pipeline---tree-traversal.qd │ ├── pipeline.qd │ ├── quickstart.qd │ ├── quotation-source.qd │ ├── quote-types.qd │ ├── range.qd │ ├── sizes.qd │ ├── slides-configuration.qd │ ├── slides-fragment.qd │ ├── slides-speaker-notes.qd │ ├── stacks.qd │ ├── subdocuments.qd │ ├── syntax-of-a-function-call.qd │ ├── table-caption.qd │ ├── table-generation.qd │ ├── table-manipulation.qd │ ├── table-of-contents.qd │ ├── tex-formulae.qd │ ├── tex-macros.qd │ ├── text-symbols.qd │ ├── text.qd │ ├── themes.qd │ ├── typing.qd │ ├── variables.qd │ ├── whitespace.qd │ └── xy-chart.qd ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat ├── mock/ │ ├── README.md │ ├── alignment.qd │ ├── bibliography/ │ │ └── bibliography.bib │ ├── bibliography.qd │ ├── boxes.qd │ ├── code/ │ │ └── Wrapper.java │ ├── code.qd │ ├── collapsibles.qd │ ├── colorpreview.qd │ ├── crossreferences.qd │ ├── errors.qd │ ├── footnotes.qd │ ├── headings.qd │ ├── icons.qd │ ├── images.qd │ ├── lists.qd │ ├── localization.qd │ ├── main.qd │ ├── math.qd │ ├── mermaid/ │ │ ├── class.mmd │ │ ├── flow.mmd │ │ ├── git.mmd │ │ ├── pie.mmd │ │ └── sequence.mmd │ ├── mermaid.qd │ ├── paragraphs.qd │ ├── quotes.qd │ ├── separators.qd │ ├── setup.qd │ ├── stacks.qd │ ├── tables.qd │ └── textformatting.qd ├── quarkdown-cli/ │ ├── LICENSE │ ├── build.gradle.kts │ └── src/ │ ├── main/ │ │ ├── kotlin/ │ │ │ └── com/ │ │ │ └── quarkdown/ │ │ │ └── cli/ │ │ │ ├── CliOptions.kt │ │ │ ├── PipelineInitialization.kt │ │ │ ├── QuarkdownCli.kt │ │ │ ├── creator/ │ │ │ │ ├── ProjectCreator.kt │ │ │ │ ├── command/ │ │ │ │ │ └── CreateProjectCommand.kt │ │ │ │ ├── content/ │ │ │ │ │ ├── DefaultProjectCreatorInitialContentSupplier.kt │ │ │ │ │ ├── DefaultTheme.kt │ │ │ │ │ ├── DocsProjectCreatorInitialContentSupplier.kt │ │ │ │ │ ├── EmptyProjectCreatorInitialContentSupplier.kt │ │ │ │ │ └── ProjectCreatorInitialContentSupplier.kt │ │ │ │ └── template/ │ │ │ │ ├── DefaultProjectCreatorTemplateProcessorFactory.kt │ │ │ │ ├── DocsProjectCreatorTemplateProcessorFactory.kt │ │ │ │ ├── ProjectCreatorTemplatePlaceholders.kt │ │ │ │ └── ProjectCreatorTemplateProcessorFactory.kt │ │ │ ├── exec/ │ │ │ │ ├── CompileCommand.kt │ │ │ │ ├── Execute.kt │ │ │ │ ├── ExecuteCommand.kt │ │ │ │ ├── ExecutionOutcome.kt │ │ │ │ ├── ReplCommand.kt │ │ │ │ └── strategy/ │ │ │ │ ├── FileExecutionStrategy.kt │ │ │ │ ├── PipelineExecutionStrategy.kt │ │ │ │ └── ReplExecutionStrategy.kt │ │ │ ├── lib/ │ │ │ │ └── QdLibraries.kt │ │ │ ├── lsp/ │ │ │ │ └── LanguageServerCommand.kt │ │ │ ├── renderer/ │ │ │ │ └── RendererRetriever.kt │ │ │ ├── server/ │ │ │ │ ├── BrowserLauncherOption.kt │ │ │ │ ├── StartWebServerCommand.kt │ │ │ │ ├── WebServerOptions.kt │ │ │ │ └── WebServerStarter.kt │ │ │ ├── util/ │ │ │ │ ├── IOUtils.kt │ │ │ │ └── MillisStopwatch.kt │ │ │ └── watcher/ │ │ │ └── DirectoryWatcher.kt │ │ └── resources/ │ │ └── creator/ │ │ ├── docs/ │ │ │ ├── _nav.qd │ │ │ ├── main.qd.jte │ │ │ ├── page-1.qd │ │ │ ├── page-2.qd │ │ │ └── page-3.qd │ │ ├── initialcontent.qd.jte │ │ └── main.qd.jte │ └── test/ │ └── kotlin/ │ └── com/ │ └── quarkdown/ │ └── cli/ │ ├── BrowserLauncherSelectionTest.kt │ ├── CompileCommandTest.kt │ ├── ProjectCreatorCommandTest.kt │ ├── ProjectCreatorTest.kt │ ├── TempDirectory.kt │ ├── VersionTest.kt │ └── WatcherTest.kt ├── quarkdown-core/ │ ├── build.gradle.kts │ ├── csl-styles.txt │ └── src/ │ ├── main/ │ │ ├── kotlin/ │ │ │ └── com/ │ │ │ └── quarkdown/ │ │ │ └── core/ │ │ │ ├── ExitCodes.kt │ │ │ ├── ast/ │ │ │ │ ├── AstRoot.kt │ │ │ │ ├── InlineContent.kt │ │ │ │ ├── MarkdownContent.kt │ │ │ │ ├── Node.kt │ │ │ │ ├── attributes/ │ │ │ │ │ ├── AstAttributes.kt │ │ │ │ │ ├── id/ │ │ │ │ │ │ ├── Identifiable.kt │ │ │ │ │ │ └── IdentifierProvider.kt │ │ │ │ │ ├── link/ │ │ │ │ │ │ └── ResolvedLinkUrlProperty.kt │ │ │ │ │ ├── localization/ │ │ │ │ │ │ ├── LocalizedKind.kt │ │ │ │ │ │ └── LocalizedKindKeys.kt │ │ │ │ │ ├── location/ │ │ │ │ │ │ ├── LocationLabelProperty.kt │ │ │ │ │ │ ├── LocationTrackableNode.kt │ │ │ │ │ │ ├── SectionLocation.kt │ │ │ │ │ │ └── SectionLocationProperty.kt │ │ │ │ │ ├── presence/ │ │ │ │ │ │ ├── CodePresenceProperty.kt │ │ │ │ │ │ ├── MathPresenceProperty.kt │ │ │ │ │ │ ├── MermaidPresenceProperty.kt │ │ │ │ │ │ └── ThirdPartyPresenceProperties.kt │ │ │ │ │ └── reference/ │ │ │ │ │ ├── ReferenceNode.kt │ │ │ │ │ └── ResolvedReferenceProperty.kt │ │ │ │ ├── base/ │ │ │ │ │ ├── LinkNode.kt │ │ │ │ │ ├── TextNode.kt │ │ │ │ │ ├── block/ │ │ │ │ │ │ ├── BlankNode.kt │ │ │ │ │ │ ├── BlockQuote.kt │ │ │ │ │ │ ├── Code.kt │ │ │ │ │ │ ├── FootnoteDefinition.kt │ │ │ │ │ │ ├── Heading.kt │ │ │ │ │ │ ├── HeadingFactory.kt │ │ │ │ │ │ ├── HeadingMarker.kt │ │ │ │ │ │ ├── HorizontalRule.kt │ │ │ │ │ │ ├── Html.kt │ │ │ │ │ │ ├── LinkDefinition.kt │ │ │ │ │ │ ├── Newline.kt │ │ │ │ │ │ ├── Paragraph.kt │ │ │ │ │ │ ├── Table.kt │ │ │ │ │ │ └── list/ │ │ │ │ │ │ ├── List.kt │ │ │ │ │ │ ├── ListItem.kt │ │ │ │ │ │ ├── ListItemVariant.kt │ │ │ │ │ │ └── TaskListItemVariant.kt │ │ │ │ │ └── inline/ │ │ │ │ │ ├── CheckBox.kt │ │ │ │ │ ├── CodeSpan.kt │ │ │ │ │ ├── Comment.kt │ │ │ │ │ ├── Emphasis.kt │ │ │ │ │ ├── Image.kt │ │ │ │ │ ├── LineBreak.kt │ │ │ │ │ ├── Link.kt │ │ │ │ │ ├── ReferenceFootnote.kt │ │ │ │ │ ├── SubdocumentLink.kt │ │ │ │ │ └── Text.kt │ │ │ │ ├── dsl/ │ │ │ │ │ ├── AstBuilder.kt │ │ │ │ │ ├── BlockAstBuilder.kt │ │ │ │ │ ├── InlineAstBuilder.kt │ │ │ │ │ ├── ListAstBuilder.kt │ │ │ │ │ └── TableAstBuilder.kt │ │ │ │ ├── iterator/ │ │ │ │ │ ├── AstIterator.kt │ │ │ │ │ ├── AstIteratorHook.kt │ │ │ │ │ └── ObservableAstIterator.kt │ │ │ │ ├── media/ │ │ │ │ │ └── StoredMediaProperty.kt │ │ │ │ └── quarkdown/ │ │ │ │ ├── CaptionableNode.kt │ │ │ │ ├── FunctionCallNode.kt │ │ │ │ ├── bibliography/ │ │ │ │ │ ├── BibliographyCitation.kt │ │ │ │ │ └── BibliographyView.kt │ │ │ │ ├── block/ │ │ │ │ │ ├── Box.kt │ │ │ │ │ ├── Clipped.kt │ │ │ │ │ ├── Collapse.kt │ │ │ │ │ ├── Container.kt │ │ │ │ │ ├── Figure.kt │ │ │ │ │ ├── FileTree.kt │ │ │ │ │ ├── Landscape.kt │ │ │ │ │ ├── Math.kt │ │ │ │ │ ├── MermaidDiagram.kt │ │ │ │ │ ├── NavigationContainer.kt │ │ │ │ │ ├── Numbered.kt │ │ │ │ │ ├── PageBreak.kt │ │ │ │ │ ├── SlidesFragment.kt │ │ │ │ │ ├── SlidesSpeakerNote.kt │ │ │ │ │ ├── Stacked.kt │ │ │ │ │ ├── SubdocumentGraph.kt │ │ │ │ │ ├── list/ │ │ │ │ │ │ ├── FocusListItemVariant.kt │ │ │ │ │ │ ├── LocationTargetListItemVariant.kt │ │ │ │ │ │ └── TableOfContentsItemVariant.kt │ │ │ │ │ └── toc/ │ │ │ │ │ ├── TableOfContentsUtils.kt │ │ │ │ │ └── TableOfContentsView.kt │ │ │ │ ├── inline/ │ │ │ │ │ ├── IconImage.kt │ │ │ │ │ ├── InlineCollapse.kt │ │ │ │ │ ├── LastHeading.kt │ │ │ │ │ ├── MathSpan.kt │ │ │ │ │ ├── PageCounter.kt │ │ │ │ │ ├── TextSymbol.kt │ │ │ │ │ ├── TextTransform.kt │ │ │ │ │ └── Whitespace.kt │ │ │ │ ├── invisible/ │ │ │ │ │ ├── PageMarginContentInitializer.kt │ │ │ │ │ ├── PageNumberFormatter.kt │ │ │ │ │ ├── PageNumberReset.kt │ │ │ │ │ └── SlidesConfigurationInitializer.kt │ │ │ │ └── reference/ │ │ │ │ ├── CrossReference.kt │ │ │ │ └── CrossReferenceableNode.kt │ │ │ ├── bibliography/ │ │ │ │ ├── Bibliography.kt │ │ │ │ └── style/ │ │ │ │ ├── BibliographyEntryLabelProviderStrategy.kt │ │ │ │ ├── BibliographyStyle.kt │ │ │ │ └── csl/ │ │ │ │ ├── CslBibliographyStyle.kt │ │ │ │ ├── CslTokenConverter.kt │ │ │ │ ├── FormattedBibliographyEntry.kt │ │ │ │ └── QuarkdownCslFormat.kt │ │ │ ├── context/ │ │ │ │ ├── BaseContext.kt │ │ │ │ ├── ChildContext.kt │ │ │ │ ├── Context.kt │ │ │ │ ├── ContextOptions.kt │ │ │ │ ├── MutableContext.kt │ │ │ │ ├── ScopeContext.kt │ │ │ │ ├── SharedContext.kt │ │ │ │ ├── SubdocumentContext.kt │ │ │ │ ├── file/ │ │ │ │ │ └── FileSystem.kt │ │ │ │ ├── hooks/ │ │ │ │ │ ├── LinkUrlResolverHook.kt │ │ │ │ │ ├── MediaStorerHook.kt │ │ │ │ │ ├── SubdocumentRegistrationHook.kt │ │ │ │ │ ├── TableOfContentsGeneratorHook.kt │ │ │ │ │ ├── location/ │ │ │ │ │ │ ├── LocationAwareLabelStorerHook.kt │ │ │ │ │ │ ├── LocationAwarenessHook.kt │ │ │ │ │ │ └── NumberedEvaluatorHook.kt │ │ │ │ │ ├── presence/ │ │ │ │ │ │ └── ThirdPartyPresenceHook.kt │ │ │ │ │ └── reference/ │ │ │ │ │ ├── BibliographyCitationResolverHook.kt │ │ │ │ │ ├── CrossReferenceResolverHook.kt │ │ │ │ │ ├── FootnoteResolverHook.kt │ │ │ │ │ ├── LinkDefinitionResolverHook.kt │ │ │ │ │ └── ReferenceDefinitionResolverHook.kt │ │ │ │ ├── localization/ │ │ │ │ │ └── ContextLocalization.kt │ │ │ │ ├── subdocument/ │ │ │ │ │ └── SubdocumentsData.kt │ │ │ │ └── toc/ │ │ │ │ └── TableOfContents.kt │ │ │ ├── document/ │ │ │ │ ├── DocumentAuthor.kt │ │ │ │ ├── DocumentInfo.kt │ │ │ │ ├── DocumentTheme.kt │ │ │ │ ├── DocumentType.kt │ │ │ │ ├── layout/ │ │ │ │ │ ├── DocumentLayoutInfo.kt │ │ │ │ │ ├── caption/ │ │ │ │ │ │ ├── CaptionPosition.kt │ │ │ │ │ │ └── CaptionPositionInfo.kt │ │ │ │ │ ├── font/ │ │ │ │ │ │ └── FontInfo.kt │ │ │ │ │ ├── page/ │ │ │ │ │ │ ├── PageFormatInfo.kt │ │ │ │ │ │ ├── PageMarginPosition.kt │ │ │ │ │ │ ├── PageOrientation.kt │ │ │ │ │ │ ├── PageSide.kt │ │ │ │ │ │ └── PageSizeFormat.kt │ │ │ │ │ └── paragraph/ │ │ │ │ │ └── ParagraphStyleInfo.kt │ │ │ │ ├── numbering/ │ │ │ │ │ ├── DocumentNumbering.kt │ │ │ │ │ ├── NumberingCounterSymbol.kt │ │ │ │ │ ├── NumberingFixedSymbol.kt │ │ │ │ │ ├── NumberingFormat.kt │ │ │ │ │ └── NumberingSymbol.kt │ │ │ │ ├── size/ │ │ │ │ │ ├── BoundingBox.kt │ │ │ │ │ ├── Size.kt │ │ │ │ │ └── Sizes.kt │ │ │ │ ├── slides/ │ │ │ │ │ └── Transition.kt │ │ │ │ ├── sub/ │ │ │ │ │ ├── Subdocument.kt │ │ │ │ │ └── SubdocumentOutputNaming.kt │ │ │ │ └── tex/ │ │ │ │ └── TexInfo.kt │ │ │ ├── flavor/ │ │ │ │ ├── LexerFactory.kt │ │ │ │ ├── MarkdownFlavor.kt │ │ │ │ ├── ParserFactory.kt │ │ │ │ ├── RendererFactory.kt │ │ │ │ ├── TreeIteratorFactory.kt │ │ │ │ ├── base/ │ │ │ │ │ ├── BaseMarkdownFlavor.kt │ │ │ │ │ ├── BaseMarkdownLexerFactory.kt │ │ │ │ │ ├── BaseMarkdownParserFactory.kt │ │ │ │ │ ├── BaseMarkdownRendererFactory.kt │ │ │ │ │ └── BaseMarkdownTreeIteratorFactory.kt │ │ │ │ └── quarkdown/ │ │ │ │ ├── QuarkdownFlavor.kt │ │ │ │ ├── QuarkdownLexerFactory.kt │ │ │ │ ├── QuarkdownParserFactory.kt │ │ │ │ ├── QuarkdownRendererFactory.kt │ │ │ │ └── QuarkdownTreeIteratorFactory.kt │ │ │ ├── function/ │ │ │ │ ├── Function.kt │ │ │ │ ├── FunctionParameter.kt │ │ │ │ ├── Naming.kt │ │ │ │ ├── call/ │ │ │ │ │ ├── CallDepth.kt │ │ │ │ │ ├── FunctionCall.kt │ │ │ │ │ ├── FunctionCallArgument.kt │ │ │ │ │ ├── FunctionCallNodeExpander.kt │ │ │ │ │ ├── UncheckedFunctionCall.kt │ │ │ │ │ ├── binding/ │ │ │ │ │ │ ├── AllArgumentsBinder.kt │ │ │ │ │ │ ├── ArgumentsBinder.kt │ │ │ │ │ │ ├── InjectedArgumentsBinder.kt │ │ │ │ │ │ └── RegularArgumentsBinder.kt │ │ │ │ │ └── validate/ │ │ │ │ │ ├── DocumentTypeFunctionCallValidator.kt │ │ │ │ │ └── FunctionCallValidator.kt │ │ │ │ ├── error/ │ │ │ │ │ ├── FunctionCallRuntimeException.kt │ │ │ │ │ ├── FunctionException.kt │ │ │ │ │ ├── InvalidArgumentCountException.kt │ │ │ │ │ ├── InvalidFunctionCallException.kt │ │ │ │ │ ├── MismatchingArgumentTypeException.kt │ │ │ │ │ ├── NoSuchElementException.kt │ │ │ │ │ ├── ParameterAlreadyBoundException.kt │ │ │ │ │ ├── UnnamedArgumentAfterNamedException.kt │ │ │ │ │ ├── UnresolvedParameterException.kt │ │ │ │ │ ├── UnresolvedReferenceException.kt │ │ │ │ │ └── internal/ │ │ │ │ │ └── InvalidExpressionEvalException.kt │ │ │ │ ├── expression/ │ │ │ │ │ ├── ComposedExpression.kt │ │ │ │ │ ├── Expression.kt │ │ │ │ │ ├── SafeExpression.kt │ │ │ │ │ └── visitor/ │ │ │ │ │ ├── AppendExpressionVisitor.kt │ │ │ │ │ ├── EvalExpressionVisitor.kt │ │ │ │ │ └── ExpressionVisitor.kt │ │ │ │ ├── library/ │ │ │ │ │ ├── Library.kt │ │ │ │ │ ├── LibraryExporter.kt │ │ │ │ │ ├── LibraryRegistrant.kt │ │ │ │ │ ├── loader/ │ │ │ │ │ │ ├── FunctionLibraryLoader.kt │ │ │ │ │ │ ├── LibraryLoader.kt │ │ │ │ │ │ ├── MultiFunctionLibraryLoader.kt │ │ │ │ │ │ └── MultiLibraryLoader.kt │ │ │ │ │ └── module/ │ │ │ │ │ └── QuarkdownModule.kt │ │ │ │ ├── reflect/ │ │ │ │ │ ├── DynamicValueConverter.kt │ │ │ │ │ ├── InjectedValue.kt │ │ │ │ │ ├── KFunctionAdapter.kt │ │ │ │ │ ├── ReflectionUtils.kt │ │ │ │ │ └── annotation/ │ │ │ │ │ ├── Injected.kt │ │ │ │ │ ├── Name.kt │ │ │ │ │ ├── NoAutoArgumentUnwrapping.kt │ │ │ │ │ ├── OnlyForDocumentType.kt │ │ │ │ │ └── QuarkdocAnnotations.kt │ │ │ │ └── value/ │ │ │ │ ├── AdaptableValue.kt │ │ │ │ ├── BooleanValue.kt │ │ │ │ ├── Destructurable.kt │ │ │ │ ├── DictionaryValue.kt │ │ │ │ ├── DynamicValue.kt │ │ │ │ ├── EnumValue.kt │ │ │ │ ├── GeneralCollectionValue.kt │ │ │ │ ├── IterableValue.kt │ │ │ │ ├── LambdaValue.kt │ │ │ │ ├── MarkdownContentValue.kt │ │ │ │ ├── NodeValue.kt │ │ │ │ ├── NoneValue.kt │ │ │ │ ├── NumberValue.kt │ │ │ │ ├── ObjectValue.kt │ │ │ │ ├── OrderedCollectionValue.kt │ │ │ │ ├── PairValue.kt │ │ │ │ ├── StringValue.kt │ │ │ │ ├── UnorderedCollectionValue.kt │ │ │ │ ├── Value.kt │ │ │ │ ├── VoidValue.kt │ │ │ │ ├── data/ │ │ │ │ │ ├── EvaluableString.kt │ │ │ │ │ ├── Lambda.kt │ │ │ │ │ └── Range.kt │ │ │ │ ├── factory/ │ │ │ │ │ ├── IllegalRawValueException.kt │ │ │ │ │ └── ValueFactory.kt │ │ │ │ └── output/ │ │ │ │ ├── OutputValueVisitor.kt │ │ │ │ ├── OutputValueVisitorFactory.kt │ │ │ │ └── node/ │ │ │ │ ├── BlockNodeOutputValueVisitor.kt │ │ │ │ ├── InlineNodeOutputValueVisitor.kt │ │ │ │ ├── NodeOutputValueVisitor.kt │ │ │ │ └── NodeOutputValueVisitorFactory.kt │ │ │ ├── graph/ │ │ │ │ ├── Graph.kt │ │ │ │ ├── Graphs.kt │ │ │ │ ├── PersistentDirectedGraph.kt │ │ │ │ └── VisitableOnceGraph.kt │ │ │ ├── lexer/ │ │ │ │ ├── AbstractLexer.kt │ │ │ │ ├── Lexer.kt │ │ │ │ ├── Token.kt │ │ │ │ ├── TokenCoordinates.kt │ │ │ │ ├── TokenData.kt │ │ │ │ ├── patterns/ │ │ │ │ │ ├── BaseMarkdownBlockTokenRegexPatterns.kt │ │ │ │ │ ├── BaseMarkdownInlineTokenRegexPatterns.kt │ │ │ │ │ ├── FunctionCallPatterns.kt │ │ │ │ │ ├── PatternHelpers.kt │ │ │ │ │ ├── QuarkdownBlockTokenRegexPatterns.kt │ │ │ │ │ ├── QuarkdownInlineTokenRegexPatterns.kt │ │ │ │ │ └── TextSymbolReplacement.kt │ │ │ │ ├── regex/ │ │ │ │ │ ├── RegexBuilder.kt │ │ │ │ │ ├── RegexLexer.kt │ │ │ │ │ ├── StandardRegexLexer.kt │ │ │ │ │ └── pattern/ │ │ │ │ │ ├── NamedRegexPattern.kt │ │ │ │ │ ├── RegexPatternGroup.kt │ │ │ │ │ ├── TokenRegexPattern.kt │ │ │ │ │ └── WalkedToken.kt │ │ │ │ └── tokens/ │ │ │ │ ├── BlockTokens.kt │ │ │ │ ├── FunctionCallToken.kt │ │ │ │ └── InlineTokens.kt │ │ │ ├── localization/ │ │ │ │ ├── Locale.kt │ │ │ │ ├── LocaleLoader.kt │ │ │ │ ├── LocalizationExceptions.kt │ │ │ │ ├── LocalizationTable.kt │ │ │ │ └── jvm/ │ │ │ │ ├── JVMLocale.kt │ │ │ │ └── JVMLocaleLoader.kt │ │ │ ├── log/ │ │ │ │ ├── DebugFormatter.kt │ │ │ │ └── Log.kt │ │ │ ├── media/ │ │ │ │ ├── LocalMedia.kt │ │ │ │ ├── Media.kt │ │ │ │ ├── MediaVisitor.kt │ │ │ │ ├── RemoteMedia.kt │ │ │ │ ├── ResolvableMedia.kt │ │ │ │ ├── export/ │ │ │ │ │ └── MediaOutputResourceConverter.kt │ │ │ │ └── storage/ │ │ │ │ ├── MutableMediaStorage.kt │ │ │ │ ├── ReadOnlyMediaStorage.kt │ │ │ │ ├── StoredMedia.kt │ │ │ │ ├── name/ │ │ │ │ │ ├── MediaNameProviderStrategy.kt │ │ │ │ │ └── SanitizedMediaNameProvider.kt │ │ │ │ └── options/ │ │ │ │ ├── MediaStorageOptions.kt │ │ │ │ ├── MediaTypeEnabledChecker.kt │ │ │ │ └── ReadOnlyMediaStorageOptions.kt │ │ │ ├── misc/ │ │ │ │ ├── color/ │ │ │ │ │ ├── Color.kt │ │ │ │ │ ├── NamedColor.kt │ │ │ │ │ └── decoder/ │ │ │ │ │ ├── ColorDecoder.kt │ │ │ │ │ ├── ColorDecoderUtils.kt │ │ │ │ │ ├── HexColorDecoder.kt │ │ │ │ │ ├── HsvHslColorDecoder.kt │ │ │ │ │ ├── NamedColorDecoder.kt │ │ │ │ │ └── RgbaColorDecoder.kt │ │ │ │ └── font/ │ │ │ │ ├── FontFamily.kt │ │ │ │ └── resolver/ │ │ │ │ ├── FontFamilyResolver.kt │ │ │ │ └── JVMFontFamilyResolver.kt │ │ │ ├── parser/ │ │ │ │ ├── BlockTokenParser.kt │ │ │ │ ├── FunctionCallRefiner.kt │ │ │ │ ├── InlineTokenParser.kt │ │ │ │ └── walker/ │ │ │ │ ├── GrammarUtils.kt │ │ │ │ ├── WalkerParser.kt │ │ │ │ ├── WalkerParsingResult.kt │ │ │ │ └── funcall/ │ │ │ │ ├── FunctionCallGrammar.kt │ │ │ │ ├── FunctionCallWalkerParser.kt │ │ │ │ └── WalkedFunctionCall.kt │ │ │ ├── pipeline/ │ │ │ │ ├── Pipeline.kt │ │ │ │ ├── PipelineChainFactory.kt │ │ │ │ ├── PipelineHooks.kt │ │ │ │ ├── PipelineOptions.kt │ │ │ │ ├── Pipelines.kt │ │ │ │ ├── error/ │ │ │ │ │ ├── BasePipelineErrorHandler.kt │ │ │ │ │ ├── IOPipelineException.kt │ │ │ │ │ ├── PipelineErrorHandler.kt │ │ │ │ │ ├── PipelineException.kt │ │ │ │ │ ├── StrictPipelineErrorHandler.kt │ │ │ │ │ └── UnattachedPipelineException.kt │ │ │ │ ├── output/ │ │ │ │ │ ├── ArtifactType.kt │ │ │ │ │ ├── BinaryOutputArtifact.kt │ │ │ │ │ ├── LazyOutputArtifact.kt │ │ │ │ │ ├── OutputArtifact.kt │ │ │ │ │ ├── OutputResource.kt │ │ │ │ │ ├── OutputResourceGroup.kt │ │ │ │ │ ├── OutputResourceVisitor.kt │ │ │ │ │ ├── TextOutputArtifact.kt │ │ │ │ │ └── visitor/ │ │ │ │ │ ├── CopyOutputResourceVisitor.kt │ │ │ │ │ └── FileResourceExporter.kt │ │ │ │ ├── stage/ │ │ │ │ │ ├── PeekPipelineStage.kt │ │ │ │ │ ├── PipelineStage.kt │ │ │ │ │ ├── PipelineStageChain.kt │ │ │ │ │ └── SharedPipelineData.kt │ │ │ │ └── stages/ │ │ │ │ ├── AfterAllRenderingPeek.kt │ │ │ │ ├── AttachmentStage.kt │ │ │ │ ├── AttributesUpdateStage.kt │ │ │ │ ├── FunctionCallExpansionStage.kt │ │ │ │ ├── LexingStage.kt │ │ │ │ ├── LibrariesRegistrationStage.kt │ │ │ │ ├── ParsingStage.kt │ │ │ │ ├── PostRenderingStage.kt │ │ │ │ ├── RenderingStage.kt │ │ │ │ ├── ResourceGenerationStage.kt │ │ │ │ └── TreeTraversalStage.kt │ │ │ ├── property/ │ │ │ │ ├── AssociatedProperties.kt │ │ │ │ ├── Property.kt │ │ │ │ └── PropertyContainer.kt │ │ │ ├── rendering/ │ │ │ │ ├── NodeRenderer.kt │ │ │ │ ├── PostRenderer.kt │ │ │ │ ├── RenderingComponents.kt │ │ │ │ ├── UnsupportedRenderException.kt │ │ │ │ ├── representable/ │ │ │ │ │ ├── RenderRepresentable.kt │ │ │ │ │ └── RenderRepresentableVisitor.kt │ │ │ │ └── tag/ │ │ │ │ ├── MultiTagBuilder.kt │ │ │ │ ├── TagBuilder.kt │ │ │ │ └── TagNodeRenderer.kt │ │ │ ├── template/ │ │ │ │ └── TemplateProcessor.kt │ │ │ ├── util/ │ │ │ │ ├── CollectionUtils.kt │ │ │ │ ├── EnumUtils.kt │ │ │ │ ├── EscapeUtils.kt │ │ │ │ ├── IOUtils.kt │ │ │ │ ├── RangeUtils.kt │ │ │ │ ├── ScopedCounter.kt │ │ │ │ ├── StringCase.kt │ │ │ │ ├── StringUtils.kt │ │ │ │ ├── URLUtils.kt │ │ │ │ └── node/ │ │ │ │ ├── NodeUtils.kt │ │ │ │ └── conversion/ │ │ │ │ └── list/ │ │ │ │ ├── MarkdownListConverter.kt │ │ │ │ ├── MarkdownListToCollectionValue.kt │ │ │ │ ├── MarkdownListToDictionaryValue.kt │ │ │ │ ├── MarkdownListToIterable.kt │ │ │ │ └── MarkdownListToList.kt │ │ │ └── visitor/ │ │ │ ├── node/ │ │ │ │ └── NodeVisitor.kt │ │ │ └── token/ │ │ │ ├── BlockTokenVisitor.kt │ │ │ ├── InlineTokenVisitor.kt │ │ │ ├── TokenVisitor.kt │ │ │ └── TokenVisitorAdapter.kt │ │ └── resources/ │ │ └── log4j2.xml │ ├── test/ │ │ ├── kotlin/ │ │ │ └── com/ │ │ │ └── quarkdown/ │ │ │ └── core/ │ │ │ ├── AstDslTest.kt │ │ │ ├── BibliographyCitationResolutionTest.kt │ │ │ ├── BlockParserTest.kt │ │ │ ├── ChildContextIsolationTest.kt │ │ │ ├── ChildContextTest.kt │ │ │ ├── CrossReferenceResolutionTest.kt │ │ │ ├── CslBibliographyStyleTest.kt │ │ │ ├── DocumentLayoutInfoTest.kt │ │ │ ├── FileResourceExporterNameSanitizationTest.kt │ │ │ ├── FontTest.kt │ │ │ ├── FootnoteResolutionTest.kt │ │ │ ├── FunctionNodeExpansionTest.kt │ │ │ ├── GraphTest.kt │ │ │ ├── InlineParserTest.kt │ │ │ ├── LambdaTest.kt │ │ │ ├── LexerTest.kt │ │ │ ├── LocaleTest.kt │ │ │ ├── LocalizationTest.kt │ │ │ ├── MediaTest.kt │ │ │ ├── MiscTest.kt │ │ │ ├── NumberingFormatTest.kt │ │ │ ├── NumberingTest.kt │ │ │ ├── PipelineStageTest.kt │ │ │ ├── PropertiesTest.kt │ │ │ ├── StandaloneFunctionTest.kt │ │ │ ├── SubdocumentRegistrationTest.kt │ │ │ ├── TableOfContentsTest.kt │ │ │ ├── TemplateProcessorTest.kt │ │ │ ├── TreeTraversalTest.kt │ │ │ ├── ValueFactoryTest.kt │ │ │ └── util/ │ │ │ └── ScopedCounterTest.kt │ │ └── resources/ │ │ ├── bib/ │ │ │ ├── article.bib │ │ │ ├── bibliography.bib │ │ │ ├── book.bib │ │ │ ├── misc.bib │ │ │ └── online.bib │ │ ├── function/ │ │ │ └── hello.txt │ │ ├── lexing/ │ │ │ ├── blocks.md │ │ │ ├── comment.md │ │ │ ├── emphasis.md │ │ │ ├── entity.md │ │ │ ├── escape.md │ │ │ ├── inline.md │ │ │ ├── inlinefunction.md │ │ │ ├── linebreak.md │ │ │ └── textreplacement.md │ │ ├── parsing/ │ │ │ ├── blockcode.md │ │ │ ├── blockquote.md │ │ │ ├── fencescode.md │ │ │ ├── figure.md │ │ │ ├── footnotedefinition.md │ │ │ ├── functioncall-chain.md │ │ │ ├── functioncall.md │ │ │ ├── heading.md │ │ │ ├── hr.md │ │ │ ├── inline/ │ │ │ │ ├── codespan.md │ │ │ │ ├── emphasis.md │ │ │ │ ├── entity.md │ │ │ │ ├── escape.md │ │ │ │ ├── image.md │ │ │ │ ├── link.md │ │ │ │ ├── mathspan.md │ │ │ │ ├── reffootnote-all-in-one.md │ │ │ │ ├── reffootnote.md │ │ │ │ ├── refimage.md │ │ │ │ ├── reflink.md │ │ │ │ ├── strikethrough.md │ │ │ │ ├── strong.md │ │ │ │ ├── strongemphasis.md │ │ │ │ └── subdocumentlink.md │ │ │ ├── linkdefinition.md │ │ │ ├── math_multiline.md │ │ │ ├── math_oneline.md │ │ │ ├── orderedlist.md │ │ │ ├── pagebreak.md │ │ │ ├── paragraph.md │ │ │ ├── setextheading.md │ │ │ ├── table.md │ │ │ └── unorderedlist.md │ │ ├── subdoc/ │ │ │ ├── subdoc-1.qd │ │ │ └── subdoc-2.qd │ │ └── template/ │ │ └── template.jte │ └── testFixtures/ │ └── kotlin/ │ └── com/ │ └── quarkdown/ │ └── core/ │ └── TestUtils.kt ├── quarkdown-html/ │ ├── .gitignore │ ├── README.md │ ├── build.gradle.kts │ ├── package.json │ ├── playwright.config.ts │ ├── src/ │ │ ├── main/ │ │ │ ├── kotlin/ │ │ │ │ └── com/ │ │ │ │ └── quarkdown/ │ │ │ │ └── rendering/ │ │ │ │ └── html/ │ │ │ │ ├── HtmlIdentifierProvider.kt │ │ │ │ ├── HtmlTagBuilder.kt │ │ │ │ ├── css/ │ │ │ │ │ ├── CssBuilder.kt │ │ │ │ │ ├── CssPageSelectors.kt │ │ │ │ │ ├── CssRepresentableVisitor.kt │ │ │ │ │ └── StylesheetBuilder.kt │ │ │ │ ├── extension/ │ │ │ │ │ ├── HtmlRendererExtension.kt │ │ │ │ │ └── HtmlRendererFactoryVisitor.kt │ │ │ │ ├── node/ │ │ │ │ │ ├── BaseHtmlNodeRenderer.kt │ │ │ │ │ ├── QuarkdownHtmlNodeRenderer.kt │ │ │ │ │ └── SidebarRenderer.kt │ │ │ │ ├── pdf/ │ │ │ │ │ ├── HtmlPdfExportOptions.kt │ │ │ │ │ ├── HtmlPdfExporter.kt │ │ │ │ │ ├── PdfHtmlPostRendererDecorator.kt │ │ │ │ │ ├── PuppeteerNodeModule.kt │ │ │ │ │ └── PuppeteerPdfGeneratorScript.kt │ │ │ │ ├── post/ │ │ │ │ │ ├── HtmlOnlyPostRenderer.kt │ │ │ │ │ ├── HtmlPostRenderer.kt │ │ │ │ │ ├── HtmlSubdocumentPostRenderer.kt │ │ │ │ │ ├── document/ │ │ │ │ │ │ ├── CssFontFacesImporter.kt │ │ │ │ │ │ ├── HtmlDocumentBuilder.kt │ │ │ │ │ │ └── HtmlDocumentStylesheet.kt │ │ │ │ │ └── resources/ │ │ │ │ │ ├── MediaPostRendererResource.kt │ │ │ │ │ ├── PostRendererResource.kt │ │ │ │ │ ├── ProxiedPostRendererResource.kt │ │ │ │ │ ├── ScriptPostRendererResource.kt │ │ │ │ │ ├── SearchIndexPostRendererResource.kt │ │ │ │ │ └── ThemePostRendererResource.kt │ │ │ │ └── search/ │ │ │ │ ├── SearchIndex.kt │ │ │ │ └── SearchIndexGenerator.kt │ │ │ ├── resources/ │ │ │ │ └── pdf/ │ │ │ │ └── pdf.js │ │ │ ├── scss/ │ │ │ │ ├── color/ │ │ │ │ │ ├── beaver.scss │ │ │ │ │ ├── darko.scss │ │ │ │ │ ├── galactic.scss │ │ │ │ │ └── paperwhite.scss │ │ │ │ ├── components/ │ │ │ │ │ ├── _alignment.scss │ │ │ │ │ ├── _bibliography.scss │ │ │ │ │ ├── _block.scss │ │ │ │ │ ├── _blockquote.scss │ │ │ │ │ ├── _box.scss │ │ │ │ │ ├── _clip.scss │ │ │ │ │ ├── _code.scss │ │ │ │ │ ├── _collapsible.scss │ │ │ │ │ ├── _container.scss │ │ │ │ │ ├── _docs.scss │ │ │ │ │ ├── _empty.scss │ │ │ │ │ ├── _figure.scss │ │ │ │ │ ├── _filetree.scss │ │ │ │ │ ├── _float.scss │ │ │ │ │ ├── _focus.scss │ │ │ │ │ ├── _font.scss │ │ │ │ │ ├── _footnote.scss │ │ │ │ │ ├── _heading.scss │ │ │ │ │ ├── _hr.scss │ │ │ │ │ ├── _landscape.scss │ │ │ │ │ ├── _link.scss │ │ │ │ │ ├── _list.scss │ │ │ │ │ ├── _location.scss │ │ │ │ │ ├── _math.scss │ │ │ │ │ ├── _mermaid.scss │ │ │ │ │ ├── _multicolumn.scss │ │ │ │ │ ├── _page-break.scss │ │ │ │ │ ├── _page-margin.scss │ │ │ │ │ ├── _paged.scss │ │ │ │ │ ├── _paragraph.scss │ │ │ │ │ ├── _search.scss │ │ │ │ │ ├── _sidebar.scss │ │ │ │ │ ├── _size.scss │ │ │ │ │ ├── _smooth-scroll.scss │ │ │ │ │ ├── _stack.scss │ │ │ │ │ ├── _table.scss │ │ │ │ │ ├── _toc.scss │ │ │ │ │ ├── _viewport.scss │ │ │ │ │ └── util/ │ │ │ │ │ ├── _heading-selectors.scss │ │ │ │ │ ├── _icon.scss │ │ │ │ │ ├── _location-selectors.scss │ │ │ │ │ ├── _media-queries.scss │ │ │ │ │ └── _misc-selectors.scss │ │ │ │ ├── global.scss │ │ │ │ ├── layout/ │ │ │ │ │ ├── beamer.scss │ │ │ │ │ ├── hyperlegible.scss │ │ │ │ │ ├── latex.scss │ │ │ │ │ ├── minimal.scss │ │ │ │ │ └── util/ │ │ │ │ │ ├── _beamer-toc.scss │ │ │ │ │ ├── _docs-headings-border.scss │ │ │ │ │ ├── _docs-navigation.scss │ │ │ │ │ ├── _gh-tables.scss │ │ │ │ │ ├── _latex-tables.scss │ │ │ │ │ ├── _latex-toc.scss │ │ │ │ │ ├── _minimal-footer.scss │ │ │ │ │ ├── _minimal-tables.scss │ │ │ │ │ ├── _minimal-toc.scss │ │ │ │ │ ├── _progressive-heading-margins.scss │ │ │ │ │ └── _progressive-heading-sizes.scss │ │ │ │ └── locale/ │ │ │ │ └── zh.scss │ │ │ └── typescript/ │ │ │ ├── capabilities.ts │ │ │ ├── chunker/ │ │ │ │ └── page-chunker.ts │ │ │ ├── document/ │ │ │ │ ├── __tests__/ │ │ │ │ │ └── document-handler.spec.ts │ │ │ │ ├── document-handler.ts │ │ │ │ ├── global-handlers.ts │ │ │ │ ├── handlers/ │ │ │ │ │ ├── __tests__/ │ │ │ │ │ │ ├── code-highlighter.spec.ts │ │ │ │ │ │ ├── footnotes-document-handler.spec.ts │ │ │ │ │ │ ├── inline-collapsibles.spec.ts │ │ │ │ │ │ ├── math-renderer.spec.ts │ │ │ │ │ │ ├── mermaid-renderer.spec.ts │ │ │ │ │ │ ├── page-margins-docs.spec.ts │ │ │ │ │ │ ├── page-margins-document-handler.spec.ts │ │ │ │ │ │ ├── page-numbers-document-handler.spec.ts │ │ │ │ │ │ ├── persistent-headings.spec.ts │ │ │ │ │ │ └── remaining-height.spec.ts │ │ │ │ │ ├── capabilities/ │ │ │ │ │ │ ├── code-highlighter.ts │ │ │ │ │ │ ├── math-renderer.ts │ │ │ │ │ │ └── mermaid-renderer.ts │ │ │ │ │ ├── docs/ │ │ │ │ │ │ ├── __tests__/ │ │ │ │ │ │ │ └── sibling-pages-buttons.spec.ts │ │ │ │ │ │ ├── page-list-autoscroll.ts │ │ │ │ │ │ ├── search-field-focus.ts │ │ │ │ │ │ ├── search-field.ts │ │ │ │ │ │ ├── sibling-pages-buttons.ts │ │ │ │ │ │ ├── toc-active-tracking.ts │ │ │ │ │ │ └── util/ │ │ │ │ │ │ ├── __tests__/ │ │ │ │ │ │ │ └── page-list-analyzer.spec.ts │ │ │ │ │ │ └── page-list-analyzer.ts │ │ │ │ │ ├── footnotes/ │ │ │ │ │ │ ├── footnotes-docs.ts │ │ │ │ │ │ ├── footnotes-document-handler.ts │ │ │ │ │ │ ├── footnotes-paged.ts │ │ │ │ │ │ ├── footnotes-plain.ts │ │ │ │ │ │ └── footnotes-slides.ts │ │ │ │ │ ├── inline-collapsibles.ts │ │ │ │ │ ├── landscape-size-swapper.ts │ │ │ │ │ ├── page-margins/ │ │ │ │ │ │ ├── page-margins-docs.ts │ │ │ │ │ │ ├── page-margins-document-handler.ts │ │ │ │ │ │ ├── page-margins-paged.ts │ │ │ │ │ │ └── page-margins-slides.ts │ │ │ │ │ ├── page-numbers.ts │ │ │ │ │ ├── paged/ │ │ │ │ │ │ └── split-code-blocks-fix-paged.ts │ │ │ │ │ ├── persistent-headings.ts │ │ │ │ │ ├── remaining-height.ts │ │ │ │ │ ├── show-on-ready.ts │ │ │ │ │ └── sidebar.ts │ │ │ │ ├── paged-like-quarkdown-document.ts │ │ │ │ ├── quarkdown-document.ts │ │ │ │ └── type/ │ │ │ │ ├── docs-document.ts │ │ │ │ ├── paged-document.ts │ │ │ │ ├── plain-document.ts │ │ │ │ └── slides-document.ts │ │ │ ├── footnotes/ │ │ │ │ ├── footnote-dom.ts │ │ │ │ ├── footnote-lookup.ts │ │ │ │ └── footnote-pair.ts │ │ │ ├── index.ts │ │ │ ├── live/ │ │ │ │ └── live-preview.ts │ │ │ ├── navigation/ │ │ │ │ └── active-tracking.ts │ │ │ ├── queue/ │ │ │ │ ├── async-execution-queue.ts │ │ │ │ └── execution-queues.ts │ │ │ ├── search/ │ │ │ │ ├── __tests__/ │ │ │ │ │ ├── search-highlight.spec.ts │ │ │ │ │ ├── search-result-expander.spec.ts │ │ │ │ │ ├── search-result-renderer.spec.ts │ │ │ │ │ └── search.spec.ts │ │ │ │ ├── search-highlight.ts │ │ │ │ ├── search-result-expander.ts │ │ │ │ ├── search-result-renderer.ts │ │ │ │ └── search.ts │ │ │ ├── types/ │ │ │ │ └── pagedjs.d.ts │ │ │ └── util/ │ │ │ ├── __tests__/ │ │ │ │ ├── escape.spec.ts │ │ │ │ └── page-number.spec.ts │ │ │ ├── browser.ts │ │ │ ├── escape.ts │ │ │ ├── hash.ts │ │ │ ├── id.ts │ │ │ ├── meta.ts │ │ │ ├── numbering.ts │ │ │ └── visibility.ts │ │ └── test/ │ │ ├── e2e/ │ │ │ ├── __util/ │ │ │ │ ├── compile.ts │ │ │ │ ├── css.ts │ │ │ │ ├── free-port.ts │ │ │ │ ├── global-setup.ts │ │ │ │ ├── global-teardown.ts │ │ │ │ ├── live-preview-runner.ts │ │ │ │ ├── paths.ts │ │ │ │ └── runner.ts │ │ │ ├── alerts/ │ │ │ │ ├── box/ │ │ │ │ │ ├── box.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ └── quote/ │ │ │ │ ├── main.qd │ │ │ │ └── quote.spec.ts │ │ │ ├── alignment/ │ │ │ │ ├── container/ │ │ │ │ │ ├── container.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ └── doctype/ │ │ │ │ ├── doctype.spec.ts │ │ │ │ └── main.qd │ │ │ ├── captions/ │ │ │ │ ├── customized/ │ │ │ │ │ ├── customized.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ ├── default/ │ │ │ │ │ ├── default.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ └── index.ts │ │ │ ├── code/ │ │ │ │ ├── caption/ │ │ │ │ │ ├── caption.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ ├── default/ │ │ │ │ │ ├── default.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ ├── focus/ │ │ │ │ │ ├── focus.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ ├── no-line-numbers/ │ │ │ │ │ ├── main.qd │ │ │ │ │ └── no-line-numbers.spec.ts │ │ │ │ ├── numbered/ │ │ │ │ │ ├── main.qd │ │ │ │ │ └── numbered.spec.ts │ │ │ │ └── page-split/ │ │ │ │ ├── main.qd │ │ │ │ └── page-split.spec.ts │ │ │ ├── colors/ │ │ │ │ ├── colors.spec.ts │ │ │ │ └── main.qd │ │ │ ├── cross-reference/ │ │ │ │ ├── default/ │ │ │ │ │ ├── default.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ └── localized/ │ │ │ │ ├── localized.spec.ts │ │ │ │ └── main.qd │ │ │ ├── css/ │ │ │ │ ├── properties/ │ │ │ │ │ ├── main.qd │ │ │ │ │ └── properties.spec.ts │ │ │ │ └── raw/ │ │ │ │ ├── main.qd │ │ │ │ └── raw.spec.ts │ │ │ ├── docs/ │ │ │ │ ├── content-width/ │ │ │ │ │ ├── content-width.spec.ts │ │ │ │ │ ├── long-code.qd │ │ │ │ │ ├── main.qd │ │ │ │ │ └── simple.qd │ │ │ │ ├── layout/ │ │ │ │ │ ├── layout.spec.ts │ │ │ │ │ ├── main.qd │ │ │ │ │ └── scroll.spec.ts │ │ │ │ ├── lib/ │ │ │ │ │ ├── customization/ │ │ │ │ │ │ ├── _nav.qd │ │ │ │ │ │ ├── _setup.qd │ │ │ │ │ │ ├── main.qd │ │ │ │ │ │ ├── page-1.qd │ │ │ │ │ │ └── structure.spec.ts │ │ │ │ │ └── default/ │ │ │ │ │ ├── _nav.qd │ │ │ │ │ ├── _setup.qd │ │ │ │ │ ├── main.qd │ │ │ │ │ ├── nested/ │ │ │ │ │ │ └── nested-page.qd │ │ │ │ │ ├── page-1.qd │ │ │ │ │ ├── page-2.qd │ │ │ │ │ └── structure.spec.ts │ │ │ │ ├── long-pagelist/ │ │ │ │ │ ├── autoscroll.spec.ts │ │ │ │ │ ├── main.qd │ │ │ │ │ └── page.qd │ │ │ │ └── multi-page/ │ │ │ │ ├── main.qd │ │ │ │ ├── page-1.qd │ │ │ │ ├── page-2.qd │ │ │ │ ├── page-3.qd │ │ │ │ ├── pagelist.spec.ts │ │ │ │ ├── setup.qd │ │ │ │ ├── sibling-pages.spec.ts │ │ │ │ ├── toc-active-tracking.spec.ts │ │ │ │ └── toc.spec.ts │ │ │ ├── doctype/ │ │ │ │ ├── default/ │ │ │ │ │ ├── default.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ └── responsiveness/ │ │ │ │ ├── main.qd │ │ │ │ └── responsiveness.spec.ts │ │ │ ├── filetree/ │ │ │ │ ├── filetree.spec.ts │ │ │ │ └── main.qd │ │ │ ├── font/ │ │ │ │ ├── customization-full/ │ │ │ │ │ ├── customization-full.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ ├── customization-localized/ │ │ │ │ │ ├── customization-localized.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ ├── customization-minimal-no-headings/ │ │ │ │ │ ├── customization-minimal-no-headings.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ ├── customization-minimal-on-headings/ │ │ │ │ │ ├── customization-minimal-on-headings.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ ├── default/ │ │ │ │ │ ├── default.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ ├── index.ts │ │ │ │ └── localized-default/ │ │ │ │ ├── localized-default.spec.ts │ │ │ │ └── main.qd │ │ │ ├── footnote/ │ │ │ │ ├── multiple/ │ │ │ │ │ ├── main.qd │ │ │ │ │ └── multiple.spec.ts │ │ │ │ └── single/ │ │ │ │ ├── main.qd │ │ │ │ └── single.spec.ts │ │ │ ├── hr/ │ │ │ │ ├── hr.spec.ts │ │ │ │ └── main.qd │ │ │ ├── icon/ │ │ │ │ ├── icon.spec.ts │ │ │ │ └── main.qd │ │ │ ├── list/ │ │ │ │ ├── issue_customization-not-affecting-list/ │ │ │ │ │ ├── bulletin.yml │ │ │ │ │ ├── customization-not-affecting-list.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ └── issue_overjustified-list-in-page-break/ │ │ │ │ ├── bulletin.yml │ │ │ │ ├── main.qd │ │ │ │ └── overjustified-list-in-page-break.spec.ts │ │ │ ├── live-preview/ │ │ │ │ ├── live-preview.spec.ts │ │ │ │ ├── main.qd │ │ │ │ └── sub.qd │ │ │ ├── margin-reset/ │ │ │ │ └── first-in-page/ │ │ │ │ ├── first-in-page.spec.ts │ │ │ │ └── main.qd │ │ │ ├── math/ │ │ │ │ ├── issue_misaligned-in-block/ │ │ │ │ │ ├── bulletin.yml │ │ │ │ │ ├── main.qd │ │ │ │ │ └── misaligned-in-parent.spec.ts │ │ │ │ ├── issue_paged-overflow/ │ │ │ │ │ ├── bulletin.yml │ │ │ │ │ ├── issue_paged-overflow.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ ├── main.qd │ │ │ │ └── math.spec.ts │ │ │ ├── media/ │ │ │ │ ├── main.qd │ │ │ │ └── media.spec.ts │ │ │ ├── mermaid/ │ │ │ │ ├── class/ │ │ │ │ │ ├── class.mmd │ │ │ │ │ ├── class.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ ├── index.ts │ │ │ │ ├── pie/ │ │ │ │ │ ├── main.qd │ │ │ │ │ ├── pie.mmd │ │ │ │ │ └── pie.spec.ts │ │ │ │ └── xy/ │ │ │ │ ├── main.qd │ │ │ │ └── xy.spec.ts │ │ │ ├── multicolumn/ │ │ │ │ ├── all-columns-by-page-fill/ │ │ │ │ │ ├── all-columns-by-page-fill.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ ├── full-span/ │ │ │ │ │ ├── full-span.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ └── only-first-column/ │ │ │ │ ├── main.qd │ │ │ │ └── only-first-column.spec.ts │ │ │ ├── numbering/ │ │ │ │ ├── default/ │ │ │ │ │ ├── default.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ └── localized/ │ │ │ │ ├── localized.spec.ts │ │ │ │ └── main.qd │ │ │ ├── page-break/ │ │ │ │ ├── main.qd │ │ │ │ └── page-break.spec.ts │ │ │ ├── page-format/ │ │ │ │ ├── alignment-global/ │ │ │ │ │ ├── alignment-global.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ ├── alignment-local/ │ │ │ │ │ ├── alignment-local.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ ├── border/ │ │ │ │ │ ├── border.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ ├── index.ts │ │ │ │ ├── margins/ │ │ │ │ │ ├── main.qd │ │ │ │ │ └── margins.spec.ts │ │ │ │ ├── scoped/ │ │ │ │ │ ├── range/ │ │ │ │ │ │ ├── main.qd │ │ │ │ │ │ └── range.spec.ts │ │ │ │ │ ├── range-side/ │ │ │ │ │ │ ├── main.qd │ │ │ │ │ │ └── range-side.spec.ts │ │ │ │ │ └── side/ │ │ │ │ │ ├── main.qd │ │ │ │ │ └── side.spec.ts │ │ │ │ └── size/ │ │ │ │ ├── format/ │ │ │ │ │ ├── format.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ ├── format-and-width/ │ │ │ │ │ ├── format-and-width.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ ├── height/ │ │ │ │ │ ├── height.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ ├── width/ │ │ │ │ │ ├── main.qd │ │ │ │ │ └── width.spec.ts │ │ │ │ └── width-and-height/ │ │ │ │ ├── main.qd │ │ │ │ └── width-and-height.spec.ts │ │ │ ├── page-margins/ │ │ │ │ ├── all-pages/ │ │ │ │ │ ├── all-pages.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ ├── format-page-numbers/ │ │ │ │ │ ├── format-page-numbers.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ ├── index.ts │ │ │ │ ├── mirror/ │ │ │ │ │ ├── main.qd │ │ │ │ │ └── mirror.spec.ts │ │ │ │ ├── page-counter/ │ │ │ │ │ ├── main.qd │ │ │ │ │ └── page-counter.spec.ts │ │ │ │ ├── persistent-headings/ │ │ │ │ │ ├── main.qd │ │ │ │ │ └── persistent-headings.spec.ts │ │ │ │ └── scoped/ │ │ │ │ ├── main.qd │ │ │ │ └── scoped.spec.ts │ │ │ ├── paragraph/ │ │ │ │ ├── customization/ │ │ │ │ │ ├── customization.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ ├── localized-configuration/ │ │ │ │ │ ├── localized-configuration.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ ├── spacing/ │ │ │ │ │ ├── base/ │ │ │ │ │ │ ├── base.spec.ts │ │ │ │ │ │ └── main.qd │ │ │ │ │ ├── with-container/ │ │ │ │ │ │ ├── main.qd │ │ │ │ │ │ └── with-container.spec.ts │ │ │ │ │ └── with-float/ │ │ │ │ │ ├── main.qd │ │ │ │ │ └── with-float.spec.ts │ │ │ │ └── typography/ │ │ │ │ ├── main.qd │ │ │ │ └── typography.spec.ts │ │ │ ├── quarkdown.ts │ │ │ ├── sidebar/ │ │ │ │ ├── empty/ │ │ │ │ │ ├── empty.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ ├── issue_border-in-minimal-theme/ │ │ │ │ │ ├── border-in-minimal-theme.spec.ts │ │ │ │ │ ├── bulletin.yml │ │ │ │ │ └── main.qd │ │ │ │ ├── main.qd │ │ │ │ └── sidebar.spec.ts │ │ │ ├── slides/ │ │ │ │ └── chunking/ │ │ │ │ ├── chunking.spec.ts │ │ │ │ └── main.qd │ │ │ ├── stack/ │ │ │ │ ├── default/ │ │ │ │ │ ├── default.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ ├── gap/ │ │ │ │ │ ├── gap.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ ├── grid-row-column-gap/ │ │ │ │ │ ├── grid-row-column-gap.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ └── index.ts │ │ │ ├── text-formatting/ │ │ │ │ ├── case/ │ │ │ │ │ ├── case.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ ├── decoration/ │ │ │ │ │ ├── decoration.spec.ts │ │ │ │ │ └── main.qd │ │ │ │ ├── size/ │ │ │ │ │ ├── main.qd │ │ │ │ │ └── size.spec.ts │ │ │ │ ├── style/ │ │ │ │ │ ├── main.qd │ │ │ │ │ └── style.spec.ts │ │ │ │ ├── variant/ │ │ │ │ │ ├── main.qd │ │ │ │ │ └── variant.spec.ts │ │ │ │ └── weight/ │ │ │ │ ├── main.qd │ │ │ │ └── weight.spec.ts │ │ │ └── toc/ │ │ │ ├── format-page-numbers/ │ │ │ │ ├── format-page-numbers.spec.ts │ │ │ │ └── main.qd │ │ │ ├── index.ts │ │ │ ├── latex/ │ │ │ │ ├── latex.spec.ts │ │ │ │ └── main.qd │ │ │ ├── minimal/ │ │ │ │ ├── main.qd │ │ │ │ └── minimal.spec.ts │ │ │ └── page-numbers/ │ │ │ ├── main.qd │ │ │ └── page-numbers.spec.ts │ │ ├── kotlin/ │ │ │ └── com/ │ │ │ └── quarkdown/ │ │ │ └── rendering/ │ │ │ └── html/ │ │ │ ├── HtmlIdentifiersTest.kt │ │ │ ├── HtmlNodeRendererTest.kt │ │ │ ├── HtmlPostRendererTest.kt │ │ │ ├── HtmlSecurityTest.kt │ │ │ ├── HtmlToPdfTest.kt │ │ │ ├── MediaTest.kt │ │ │ ├── SearchIndexGeneratorTest.kt │ │ │ └── SidebarRendererTest.kt │ │ └── resources/ │ │ ├── issues/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── data/ │ │ │ │ └── bibliography/ │ │ │ │ └── bibliography.bib │ │ │ ├── landscape.qd │ │ │ ├── math-page-overflow.qd │ │ │ ├── mermaid-size.qd │ │ │ ├── mirrored-bibliography.qd │ │ │ ├── misaligned-math-fraction.qd │ │ │ ├── misaligned-math-in-box.qd │ │ │ ├── misaligned-math-in-quote.qd │ │ │ ├── multiple-font-configurations.qd │ │ │ └── template/ │ │ │ └── template.qd │ │ ├── media/ │ │ │ └── file.txt │ │ └── rendering/ │ │ ├── block/ │ │ │ ├── blockquote.html │ │ │ ├── code.html │ │ │ ├── footnote.html │ │ │ ├── heading.html │ │ │ ├── math.html │ │ │ ├── orderedlist.html │ │ │ ├── paragraph.html │ │ │ ├── table.html │ │ │ └── unorderedlist.html │ │ ├── inline/ │ │ │ ├── codespan.html │ │ │ ├── emphasis.html │ │ │ ├── image.html │ │ │ ├── link.html │ │ │ ├── math.html │ │ │ ├── reffootnote.html │ │ │ ├── refimage.html │ │ │ ├── reflink.html │ │ │ ├── strikethrough.html │ │ │ ├── strong.html │ │ │ └── strongemphasis.html │ │ └── quarkdown/ │ │ ├── bibliography.html │ │ ├── box.html │ │ ├── clipped.html │ │ ├── collapse.html │ │ ├── container.html │ │ ├── figure.html │ │ ├── filetree.html │ │ ├── fullspan.html │ │ ├── inlinecollapse.html │ │ ├── lastheading.html │ │ ├── navigationcontainer.html │ │ └── texttransform.html │ ├── tsconfig.json │ └── vitest.config.ts ├── quarkdown-interaction/ │ ├── README.md │ ├── build.gradle.kts │ └── src/ │ ├── main/ │ │ └── kotlin/ │ │ └── com/ │ │ └── quarkdown/ │ │ └── interaction/ │ │ ├── Env.kt │ │ ├── executable/ │ │ │ ├── ExecutableWrapper.kt │ │ │ ├── NodeJsWrapper.kt │ │ │ ├── NodeModule.kt │ │ │ ├── NodeNpmHelper.kt │ │ │ ├── NpmWrapper.kt │ │ │ └── WithDefaultPath.kt │ │ └── os/ │ │ └── OsUtils.kt │ └── test/ │ └── kotlin/ │ └── com/ │ └── quarkdown/ │ └── interaction/ │ └── NodeNpmWrapperTest.kt ├── quarkdown-libs/ │ ├── README.md │ ├── build.gradle.kts │ └── src/ │ └── main/ │ └── resources/ │ ├── docs.qd │ └── paper.qd ├── quarkdown-lsp/ │ ├── LICENSE │ ├── README.md │ ├── build.gradle.kts │ └── src/ │ ├── main/ │ │ └── kotlin/ │ │ └── com/ │ │ └── quarkdown/ │ │ └── lsp/ │ │ ├── QuarkdownLanguageServer.kt │ │ ├── QuarkdownLanguageServerLauncher.kt │ │ ├── QuarkdownTextDocumentService.kt │ │ ├── QuarkdownWorkspaceService.kt │ │ ├── TextDocument.kt │ │ ├── cache/ │ │ │ ├── CacheableFunctionCatalogue.kt │ │ │ ├── DocumentCache.kt │ │ │ └── DocumentedFunction.kt │ │ ├── completion/ │ │ │ ├── CompletionItemConverters.kt │ │ │ ├── CompletionSupplier.kt │ │ │ ├── CompletionSuppliersFactory.kt │ │ │ └── function/ │ │ │ ├── AbstractFunctionCompletionSupplier.kt │ │ │ ├── FunctionCallInsertionSnippet.kt │ │ │ ├── name/ │ │ │ │ ├── ChainedFunctionNameCompletionSupplier.kt │ │ │ │ ├── FunctionNameCompletionSupplier.kt │ │ │ │ └── RegularFunctionNameCompletionSupplier.kt │ │ │ └── parameter/ │ │ │ ├── FunctionParameterAllowedValuesCompletionSupplier.kt │ │ │ └── FunctionParameterNameCompletionSupplier.kt │ │ ├── diagnostics/ │ │ │ ├── AbstractFunctionCallDiagnosticsSupplier.kt │ │ │ ├── DiagnosticsSupplier.kt │ │ │ ├── DiagnosticsSuppliersFactory.kt │ │ │ ├── SimpleDiagnostic.kt │ │ │ ├── cause/ │ │ │ │ ├── DiagnosticCause.kt │ │ │ │ ├── DuplicateParameterNameDiagnosticCause.kt │ │ │ │ ├── UnallowedValueDiagnosticCause.kt │ │ │ │ └── UnresolvedParameterNameDiagnosticCause.kt │ │ │ └── function/ │ │ │ ├── FunctionDuplicateParameterNameDiagnosticsSupplier.kt │ │ │ ├── FunctionParameterValueDiagnosticsSupplier.kt │ │ │ └── FunctionUnresolvedParameterNameDiagnosticsSupplier.kt │ │ ├── documentation/ │ │ │ ├── FunctionDocumentation.kt │ │ │ └── HtmlToMarkdown.kt │ │ ├── highlight/ │ │ │ ├── SemanticTokensEncoder.kt │ │ │ ├── SemanticTokensSupplier.kt │ │ │ ├── SemanticTokensSuppliersFactory.kt │ │ │ ├── TokenData.kt │ │ │ ├── TokenType.kt │ │ │ └── function/ │ │ │ ├── FunctionCallTokensSupplier.kt │ │ │ └── ValueQualifier.kt │ │ ├── hover/ │ │ │ ├── HoverSupplier.kt │ │ │ ├── HoverSuppliersFactory.kt │ │ │ └── function/ │ │ │ └── FunctionDocumentationHoverSupplier.kt │ │ ├── ontype/ │ │ │ ├── OnTypeFormattingEditSupplier.kt │ │ │ ├── OnTypeFormattingSuppliersFactory.kt │ │ │ └── TrailingSpacesRemoverOnTypeFormattingEditSupplier.kt │ │ ├── pattern/ │ │ │ └── QuarkdownPatterns.kt │ │ ├── subservices/ │ │ │ ├── CompletionSubservice.kt │ │ │ ├── DiagnosticsSubservice.kt │ │ │ ├── HoverSubservice.kt │ │ │ ├── OnTypeFormattingSubservice.kt │ │ │ ├── SemanticTokensSubservice.kt │ │ │ └── TextDocumentSubservice.kt │ │ ├── tokenizer/ │ │ │ ├── FunctionCall.kt │ │ │ ├── FunctionCallTokenizer.kt │ │ │ └── TokenSearch.kt │ │ └── util/ │ │ ├── FunctionParameterLookupUtils.kt │ │ ├── ParsingUtils.kt │ │ └── PositionUtils.kt │ └── test/ │ ├── kotlin/ │ │ └── com/ │ │ └── quarkdown/ │ │ └── lsp/ │ │ ├── DocumentCacheTest.kt │ │ ├── FunctionCallTokenizerTest.kt │ │ ├── FunctionCallTokensSupplierTest.kt │ │ ├── FunctionCompletionSupplierTest.kt │ │ ├── FunctionDocumentationHoverSupplierTest.kt │ │ ├── HtmlToMarkdownTest.kt │ │ ├── PositionTest.kt │ │ ├── TrailingSpacesRemoverFormattingEditSupplierTest.kt │ │ └── diagnostics/ │ │ ├── DiagnosticsTestUtils.kt │ │ ├── FunctionDuplicateParameterNameDiagnosticsSupplierTest.kt │ │ ├── FunctionParameterValueDiagnosticsSupplierTest.kt │ │ └── FunctionUnresolvedParameterNameDiagnosticsSupplierTest.kt │ └── resources/ │ ├── docs/ │ │ ├── com.quarkdown.stdlib.module.Data/ │ │ │ └── csv.html │ │ └── com.quarkdown.stdlib.module.Layout/ │ │ ├── align.html │ │ ├── clip.html │ │ └── column.html │ └── html-to-markdown/ │ ├── align.html │ └── align.md ├── quarkdown-plaintext/ │ ├── README.md │ ├── build.gradle.kts │ └── src/ │ ├── main/ │ │ └── kotlin/ │ │ └── com/ │ │ └── quarkdown/ │ │ └── rendering/ │ │ └── plaintext/ │ │ ├── extension/ │ │ │ └── PlainTextRendererExtension.kt │ │ ├── node/ │ │ │ └── PlainTextNodeRenderer.kt │ │ └── post/ │ │ └── PlainTextPostRenderer.kt │ └── test/ │ └── kotlin/ │ └── com/ │ └── quarkdown/ │ └── rendering/ │ └── plaintext/ │ ├── PlainTextNodeRendererTest.kt │ └── PlainTextPostRendererTest.kt ├── quarkdown-quarkdoc/ │ ├── README.md │ ├── build.gradle.kts │ └── src/ │ ├── main/ │ │ ├── kotlin/ │ │ │ └── com/ │ │ │ └── quarkdown/ │ │ │ └── quarkdoc/ │ │ │ └── dokka/ │ │ │ ├── QuarkdocDokkaPlugin.kt │ │ │ ├── kdoc/ │ │ │ │ ├── DeepDocumentationMapper.kt │ │ │ │ ├── DocTagDsl.kt │ │ │ │ ├── DocumentationMapper.kt │ │ │ │ ├── DocumentationMapperDsl.kt │ │ │ │ ├── DocumentationReferencesTransformer.kt │ │ │ │ └── SimpleDocumentationMapper.kt │ │ │ ├── page/ │ │ │ │ ├── DocumentTypeConstraintsPageTransformer.kt │ │ │ │ ├── DocumentablePageTransformer.kt │ │ │ │ ├── LikelyChainedPageTransformer.kt │ │ │ │ ├── NewSectionDocumentablePageTransformer.kt │ │ │ │ └── WikiLinkPageTransformer.kt │ │ │ ├── signature/ │ │ │ │ ├── KotlinSignatureReflectionHelper.kt │ │ │ │ ├── LineBreakingStrategy.kt │ │ │ │ └── QuarkdownSignatureProvider.kt │ │ │ ├── transformers/ │ │ │ │ ├── QuarkdocDocumentableReplacerTransformer.kt │ │ │ │ ├── QuarkdocParameterDocumentationTransformer.kt │ │ │ │ ├── enumeration/ │ │ │ │ │ ├── EnumParameterEntryListerTransformer.kt │ │ │ │ │ ├── EnumStorage.kt │ │ │ │ │ ├── EnumStorer.kt │ │ │ │ │ ├── QuarkdocEnum.kt │ │ │ │ │ └── adapters/ │ │ │ │ │ ├── DokkaEnumAdapter.kt │ │ │ │ │ ├── QuarkdocEnumAdapters.kt │ │ │ │ │ └── ReflectionEnumAdapter.kt │ │ │ │ ├── misc/ │ │ │ │ │ └── DocumentTypeConstraintsTransformer.kt │ │ │ │ ├── module/ │ │ │ │ │ ├── ModuleAsPackageTransformer.kt │ │ │ │ │ ├── ModulesStorer.kt │ │ │ │ │ └── QuarkdownModulesStorage.kt │ │ │ │ ├── name/ │ │ │ │ │ ├── DocumentableNameTransformer.kt │ │ │ │ │ ├── DocumentationNameTransformer.kt │ │ │ │ │ ├── RenamingsStorage.kt │ │ │ │ │ └── RenamingsStorer.kt │ │ │ │ ├── optional/ │ │ │ │ │ └── AdditionalParameterPropertiesTransformer.kt │ │ │ │ ├── suppress/ │ │ │ │ │ └── SuppressInjectedTransformer.kt │ │ │ │ └── type/ │ │ │ │ └── ValueTypeTransformer.kt │ │ │ └── util/ │ │ │ ├── Annotation.kt │ │ │ ├── ContentBuilder.kt │ │ │ ├── DocTagCopy.kt │ │ │ ├── Dri.kt │ │ │ ├── Enum.kt │ │ │ ├── Extra.kt │ │ │ ├── KDoc.kt │ │ │ ├── Package.kt │ │ │ ├── Scraping.kt │ │ │ └── Source.kt │ │ └── resources/ │ │ ├── META-INF/ │ │ │ └── services/ │ │ │ └── org.jetbrains.dokka.plugability.DokkaPlugin │ │ └── styles/ │ │ └── stylesheet.css │ └── test/ │ └── kotlin/ │ └── com/ │ └── quarkdown/ │ └── quarkdoc/ │ └── dokka/ │ ├── AdditionalParameterPropertiesTransformerTest.kt │ ├── DocumentTypeConstraintsTransformerTest.kt │ ├── EnumParameterEntryListerTransformerTest.kt │ ├── LikelyChainedTransformerTest.kt │ ├── ModuleTransformerTest.kt │ ├── NameTransformerTest.kt │ ├── QuarkdocDokkaTest.kt │ ├── QuarkdownSignatureTest.kt │ ├── SuppressInjectedTransformerTest.kt │ ├── ValueTypeTransformerTest.kt │ └── WikiLinkTransformerTest.kt ├── quarkdown-quarkdoc-reader/ │ ├── README.md │ ├── build.gradle.kts │ └── src/ │ ├── main/ │ │ └── kotlin/ │ │ └── com/ │ │ └── quarkdown/ │ │ └── quarkdoc/ │ │ └── reader/ │ │ ├── DocsContentExtractor.kt │ │ ├── DocsFunction.kt │ │ ├── DocsWalker.kt │ │ ├── anchors/ │ │ │ ├── Anchors.kt │ │ │ └── AnchorsHtml.kt │ │ └── dokka/ │ │ ├── DokkaHtmlContentExtractor.kt │ │ └── DokkaHtmlWalker.kt │ └── test/ │ ├── kotlin/ │ │ └── com/ │ │ └── quarkdown/ │ │ └── quarkdoc/ │ │ └── reader/ │ │ └── DokkaReaderTest.kt │ └── resources/ │ ├── content/ │ │ ├── capitalize.html │ │ ├── container.html │ │ ├── index.html │ │ ├── isnone.html │ │ ├── lowercase.html │ │ └── uppercase.html │ └── extract/ │ └── lowercase.html ├── quarkdown-server/ │ ├── README.md │ ├── build.gradle.kts │ └── src/ │ ├── main/ │ │ ├── kotlin/ │ │ │ └── com/ │ │ │ └── quarkdown/ │ │ │ └── server/ │ │ │ ├── LocalFileWebServer.kt │ │ │ ├── Server.kt │ │ │ ├── ServerEndpoints.kt │ │ │ ├── ServerFreePortScanner.kt │ │ │ ├── browser/ │ │ │ │ ├── BrowserLauncher.kt │ │ │ │ ├── DefaultBrowserLauncher.kt │ │ │ │ ├── EnvBrowserLauncher.kt │ │ │ │ ├── NoneBrowserLauncher.kt │ │ │ │ ├── PathBrowserLauncher.kt │ │ │ │ └── XdgBrowserLauncher.kt │ │ │ ├── endpoints/ │ │ │ │ ├── LivePreviewEndpoint.kt │ │ │ │ └── ReloadEndpoint.kt │ │ │ ├── message/ │ │ │ │ ├── ServerMessage.kt │ │ │ │ └── ServerMessageSession.kt │ │ │ └── stop/ │ │ │ ├── KtorStoppableAdapter.kt │ │ │ └── Stoppable.kt │ │ └── resources/ │ │ ├── live-preview/ │ │ │ └── wrapper.html.jte │ │ └── simplelogger.properties │ └── test/ │ ├── kotlin/ │ │ └── com/ │ │ └── quarkdown/ │ │ └── server/ │ │ ├── LivePreviewEndpointTest.kt │ │ ├── LocalFileWebServerTest.kt │ │ └── ServerFreePortScannerTest.kt │ └── resources/ │ └── test.html ├── quarkdown-stdlib/ │ ├── build.gradle.kts │ └── src/ │ ├── main/ │ │ ├── kotlin/ │ │ │ └── com/ │ │ │ └── quarkdown/ │ │ │ └── stdlib/ │ │ │ ├── Bibliography.kt │ │ │ ├── Collection.kt │ │ │ ├── Data.kt │ │ │ ├── Dictionary.kt │ │ │ ├── Document.kt │ │ │ ├── Ecosystem.kt │ │ │ ├── Emoji.kt │ │ │ ├── Flow.kt │ │ │ ├── Icon.kt │ │ │ ├── Injection.kt │ │ │ ├── Layout.kt │ │ │ ├── Library.kt │ │ │ ├── Localization.kt │ │ │ ├── Logger.kt │ │ │ ├── Logical.kt │ │ │ ├── Math.kt │ │ │ ├── Mermaid.kt │ │ │ ├── MiscElements.kt │ │ │ ├── Optionality.kt │ │ │ ├── Primitives.kt │ │ │ ├── Reference.kt │ │ │ ├── Slides.kt │ │ │ ├── Stdlib.kt │ │ │ ├── String.kt │ │ │ ├── TableComputation.kt │ │ │ ├── Text.kt │ │ │ ├── external/ │ │ │ │ └── QdLibraryExporter.kt │ │ │ └── internal/ │ │ │ ├── Css.kt │ │ │ ├── FileTree.kt │ │ │ ├── Font.kt │ │ │ ├── RootFileSystem.kt │ │ │ ├── Sorting.kt │ │ │ └── Types.kt │ │ └── resources/ │ │ ├── lib/ │ │ │ └── localization.qd │ │ └── text/ │ │ └── lorem-ipsum.txt │ └── test/ │ ├── kotlin/ │ │ └── com/ │ │ └── quarkdown/ │ │ └── stdlib/ │ │ ├── DataTest.kt │ │ ├── FileTreeTest.kt │ │ ├── FlowTest.kt │ │ ├── LocalizationTest.kt │ │ ├── TextTest.kt │ │ └── internal/ │ │ ├── CssTest.kt │ │ └── SortingTest.kt │ └── resources/ │ └── data/ │ ├── code.html │ ├── drinks.csv │ ├── listfiles/ │ │ ├── a.txt │ │ ├── b.txt │ │ ├── c.txt │ │ └── d/ │ │ └── d.txt │ ├── people.csv │ └── test.txt ├── quarkdown-test/ │ ├── README.md │ ├── build.gradle.kts │ └── src/ │ └── test/ │ ├── kotlin/ │ │ └── com/ │ │ └── quarkdown/ │ │ └── test/ │ │ ├── BibliographyTest.kt │ │ ├── BoxesTest.kt │ │ ├── CaptionTest.kt │ │ ├── CodeTest.kt │ │ ├── CommentsTest.kt │ │ ├── CrossReferenceTest.kt │ │ ├── DocsLibraryTest.kt │ │ ├── DocumentTest.kt │ │ ├── EcosystemTest.kt │ │ ├── EmojiTest.kt │ │ ├── FileTreeTest.kt │ │ ├── FontTest.kt │ │ ├── FootnoteTest.kt │ │ ├── FormatPageNumberTest.kt │ │ ├── FunctionCallChainingTest.kt │ │ ├── FunctionCallTest.kt │ │ ├── HeadingTest.kt │ │ ├── HtmlOutputResourceTest.kt │ │ ├── IOTest.kt │ │ ├── InjectionTest.kt │ │ ├── IterableTest.kt │ │ ├── LayoutTest.kt │ │ ├── LinkTest.kt │ │ ├── LocalizationTest.kt │ │ ├── MathTest.kt │ │ ├── MediaStorageTest.kt │ │ ├── MermaidTest.kt │ │ ├── NodesTest.kt │ │ ├── NonStrictErrorHandlingTest.kt │ │ ├── NumberingTest.kt │ │ ├── OptionalityTest.kt │ │ ├── PageBreakTest.kt │ │ ├── PageMarginsTest.kt │ │ ├── PaperLibTest.kt │ │ ├── PersistentHeadingTest.kt │ │ ├── ScriptingTest.kt │ │ ├── SecurityTest.kt │ │ ├── SidebarTest.kt │ │ ├── StrictErrorHandlingTest.kt │ │ ├── StringTest.kt │ │ ├── SubdocumentTest.kt │ │ ├── TableComputationTest.kt │ │ ├── TableOfContentsTest.kt │ │ ├── TablesTest.kt │ │ ├── TextTest.kt │ │ ├── UtilitiesTest.kt │ │ └── util/ │ │ ├── Launcher.kt │ │ ├── LibraryUtils.kt │ │ └── OutputResourceUtils.kt │ └── resources/ │ └── data/ │ ├── bib/ │ │ └── bibliography.bib │ ├── code.txt │ ├── css/ │ │ └── style.css │ ├── csv/ │ │ ├── people.csv │ │ ├── sales.csv │ │ └── sums.csv │ ├── include/ │ │ ├── absolute-image.md │ │ ├── basic-source.md │ │ ├── document-info-modification.md │ │ ├── dynamic-value.md │ │ ├── function-definition.md │ │ ├── function-with-content.md │ │ ├── mutable-data.md │ │ ├── read-relative-path-in-scope.md │ │ ├── read-relative-path.md │ │ ├── reference-image.md │ │ ├── relative-image.md │ │ ├── shared-function-usage.md │ │ ├── stdlib-call.md │ │ ├── subdocument-linker.qd │ │ ├── transitive-include.md │ │ └── url-image.md │ ├── libraries/ │ │ ├── content.qd │ │ ├── file-reader.qd │ │ └── hello.qd │ ├── mermaid/ │ │ └── class.mmd │ ├── search-index/ │ │ ├── search-index-no-headings-no-metadata.json │ │ ├── search-index-no-headings-with-metadata.json │ │ ├── search-index-with-headings.json │ │ └── search-index-with-page-margin.json │ └── subdoc/ │ ├── circular-1.qd │ ├── circular-2.qd │ ├── docs/ │ │ ├── _nav.qd │ │ ├── _setup.qd │ │ ├── page-1.qd │ │ ├── page-2.qd │ │ └── page-3.qd │ ├── gateway.qd │ ├── headings-1.qd │ ├── headings-2.qd │ ├── include-lib-1.qd │ ├── include-lib-2.qd │ ├── include-stdlib.qd │ ├── media-storage.qd │ ├── media.qd │ ├── metadata.qd │ ├── nav-includer.qd │ ├── nav.qd │ ├── path-to-root/ │ │ ├── subdoc/ │ │ │ └── subdoc.qd │ │ └── utils/ │ │ └── path-to-root.qd │ ├── recursive.qd │ ├── simple-1.qd │ ├── simple-2.qd │ └── stdlib-call.qd ├── scripts/ │ ├── bootstrap.bat │ └── bootstrap.sh ├── settings.gradle.kts └── version.txt
SYMBOL INDEX (426 symbols across 113 files)
FILE: .github/workflows/generate-pdf/generate-theme-combinations.js
constant PROJECT_DIR (line 4) | const PROJECT_DIR = 'mock';
constant MAIN_FILE (line 5) | const MAIN_FILE = PROJECT_DIR + '/main.qd';
constant WORKFLOW_DIR (line 6) | const WORKFLOW_DIR = '.github/workflows/generate-pdf';
constant COLOR_FILE (line 7) | const COLOR_FILE = WORKFLOW_DIR + '/color.txt';
constant LAYOUT_FILE (line 8) | const LAYOUT_FILE = WORKFLOW_DIR + '/layout.txt';
function getLines (line 10) | function getLines(file) {
function createNewFileName (line 17) | function createNewFileName(color, layout) {
function generateThemeVariants (line 21) | function generateThemeVariants() {
FILE: demo/code/Point.java
class Point (line 1) | public final class Point {
method Point (line 5) | public Point(int x, int y) {
method getX (line 10) | public int getX() {
method getY (line 14) | public int getY() {
FILE: docs/assets/point.ts
class Point (line 1) | class Point {
method constructor (line 5) | constructor(x: number, y: number) {
FILE: mock/code/Wrapper.java
class Wrapper (line 1) | public final class Wrapper<T> {
method Wrapper (line 4) | public Wrapper(T value) {
method getValue (line 8) | public final T getValue() {
FILE: quarkdown-html/src/main/resources/pdf/pdf.js
function createArgs (line 10) | function createArgs() {
function getClientHeight (line 61) | async function getClientHeight(body) {
FILE: quarkdown-html/src/main/typescript/chunker/page-chunker.ts
class PageChunker (line 34) | class PageChunker {
method constructor (line 39) | constructor(container: HTMLElement) {
method generateChunks (line 48) | private generateChunks(createElement: () => HTMLElement): void {
method apply (line 75) | private apply(): void {
method chunk (line 114) | chunk(chunkTagName: string = "section"): void {
FILE: quarkdown-html/src/main/typescript/document/__tests__/document-handler.spec.ts
class TestDoc (line 8) | class TestDoc {}
class TestHandler (line 10) | class TestHandler extends DocumentHandler {
method constructor (line 12) | constructor(doc: any) { super(doc as any); }
method init (line 13) | init() { this.inited = true; }
FILE: quarkdown-html/src/main/typescript/document/document-handler.ts
type ConditionalDocumentHandler (line 10) | type ConditionalDocumentHandler = DocumentHandler | boolean;
function filterConditionalHandlers (line 17) | function filterConditionalHandlers(handlers: ConditionalDocumentHandler[...
method constructor (line 30) | constructor(protected readonly quarkdownDocument: TDoc) {
method pushToQueue (line 55) | pushToQueue() {
FILE: quarkdown-html/src/main/typescript/document/global-handlers.ts
function getGlobalHandlers (line 11) | function getGlobalHandlers(document: QuarkdownDocument): ConditionalDocu...
FILE: quarkdown-html/src/main/typescript/document/handlers/__tests__/code-highlighter.spec.ts
class DummyDoc (line 15) | class DummyDoc {}
FILE: quarkdown-html/src/main/typescript/document/handlers/__tests__/footnotes-document-handler.spec.ts
class DummyDoc (line 4) | class DummyDoc {
class Concrete (line 7) | class Concrete extends FootnotesDocumentHandler {
FILE: quarkdown-html/src/main/typescript/document/handlers/__tests__/inline-collapsibles.spec.ts
class DummyDoc (line 4) | class DummyDoc {
FILE: quarkdown-html/src/main/typescript/document/handlers/__tests__/math-renderer.spec.ts
class DummyDoc (line 7) | class DummyDoc {
FILE: quarkdown-html/src/main/typescript/document/handlers/__tests__/mermaid-renderer.spec.ts
class DummyDoc (line 11) | class DummyDoc {
FILE: quarkdown-html/src/main/typescript/document/handlers/__tests__/page-margins-docs.spec.ts
class DummyDocument (line 6) | class DummyDocument implements QuarkdownDocument {
method getParentViewport (line 7) | getParentViewport(): HTMLElement | undefined {
method setupPreRenderingHook (line 11) | setupPreRenderingHook(): void {
method setupPostRenderingHook (line 14) | setupPostRenderingHook(): void {
method initializeRendering (line 17) | initializeRendering(): void {
method getHandlers (line 20) | getHandlers(): DocumentHandler[] {
FILE: quarkdown-html/src/main/typescript/document/handlers/__tests__/page-margins-document-handler.spec.ts
class DummyDocument (line 5) | class DummyDocument implements PagedLikeQuarkdownDocument<QuarkdownPage> {
method constructor (line 6) | constructor(private readonly pages: QuarkdownPage[] = [], private read...
method getPages (line 9) | getPages(): QuarkdownPage[] {
method getPageNumber (line 13) | getPageNumber(_page: QuarkdownPage): number {
method getDisplayPageNumber (line 17) | getDisplayPageNumber(_page: QuarkdownPage): string {
method getPageType (line 21) | getPageType(page: QuarkdownPage): 'left' | 'right' {
method getPage (line 26) | getPage(_element: HTMLElement): QuarkdownPage | undefined {
method setDisplayPageNumber (line 30) | setDisplayPageNumber(_page: QuarkdownPage, _pageNumber: string): void {
method getParentViewport (line 33) | getParentViewport(_element: Element): HTMLElement | undefined {
method setupPreRenderingHook (line 37) | setupPreRenderingHook(): void {
method setupPostRenderingHook (line 40) | setupPostRenderingHook(): void {
method initializeRendering (line 43) | initializeRendering(): void {
method getHandlers (line 46) | getHandlers() {
class RecordingHandler (line 51) | class RecordingHandler extends PageMarginsDocumentHandler {
method apply (line 54) | apply(initializer: HTMLElement, page: QuarkdownPage, marginPositionNam...
method querySelectorAll (line 75) | querySelectorAll(selector: string) {
FILE: quarkdown-html/src/main/typescript/document/handlers/__tests__/page-numbers-document-handler.spec.ts
class DummyDocument (line 5) | class DummyDocument implements PagedLikeQuarkdownDocument<HTMLElement> {
method constructor (line 6) | constructor(private readonly pages: HTMLElement[]) {
method getPages (line 9) | getPages(): HTMLElement[] {
method getPageNumber (line 13) | getPageNumber(page: HTMLElement): number {
method getDisplayPageNumber (line 17) | getDisplayPageNumber(page: HTMLElement): string {
method getPageType (line 21) | getPageType(): "left" | "right" {
method getPage (line 25) | getPage(element: HTMLElement): HTMLElement | undefined {
method setDisplayPageNumber (line 29) | setDisplayPageNumber(page: HTMLElement, pageNumber: string): void {
method getParentViewport (line 33) | getParentViewport(): HTMLElement | undefined {
method setupPreRenderingHook (line 37) | setupPreRenderingHook(): void {
method setupPostRenderingHook (line 40) | setupPostRenderingHook(): void {
method initializeRendering (line 43) | initializeRendering(): void {
method getHandlers (line 46) | getHandlers() {
class Concrete (line 51) | class Concrete extends PageNumbers {
FILE: quarkdown-html/src/main/typescript/document/handlers/__tests__/persistent-headings.spec.ts
class DummyDoc (line 8) | class DummyDoc implements PagedLikeQuarkdownDocument {
method getHandlers (line 9) | getHandlers(): ConditionalDocumentHandler[] {
method getParentViewport (line 13) | getParentViewport(element: Element): HTMLElement | undefined {
method initializeRendering (line 17) | initializeRendering(): void {
method setupPostRenderingHook (line 21) | setupPostRenderingHook(): void {
method setupPreRenderingHook (line 24) | setupPreRenderingHook(): void {
method getPageNumber (line 28) | getPageNumber(_: HTMLElement): number {
method getDisplayPageNumber (line 32) | getDisplayPageNumber(_: HTMLElement): string {
method getPageType (line 36) | getPageType(_: HTMLElement): "left" | "right" {
method getPages (line 40) | getPages(): HTMLElement[] {
FILE: quarkdown-html/src/main/typescript/document/handlers/__tests__/remaining-height.spec.ts
class DocStub (line 4) | class DocStub {
method getParentViewport (line 5) | getParentViewport(el: HTMLElement): HTMLElement | null {
method toJSON (line 29) | toJSON() {
method toJSON (line 41) | toJSON() {
FILE: quarkdown-html/src/main/typescript/document/handlers/capabilities/code-highlighter.ts
class CodeHighlighter (line 24) | class CodeHighlighter extends DocumentHandler {
method init (line 25) | init() {
method onPostRendering (line 29) | async onPostRendering() {
method initLineNumbers (line 39) | private initLineNumbers() {
method focusCodeLines (line 70) | private focusCodeLines() {
method extractFocusRange (line 85) | private extractFocusRange(codeBlock: HTMLElement): { start: number; en...
method applyFocusToLines (line 98) | private applyFocusToLines(codeBlock: HTMLElement, focusRange: { start:...
method isLineInFocusRange (line 121) | private isLineInFocusRange(lineNumber: number, focusRange: { start: nu...
FILE: quarkdown-html/src/main/typescript/document/handlers/capabilities/math-renderer.ts
type Window (line 12) | interface Window {
class MathRenderer (line 28) | class MathRenderer extends DocumentHandler {
method onPreRendering (line 29) | async onPreRendering() {
FILE: quarkdown-html/src/main/typescript/document/handlers/capabilities/mermaid-renderer.ts
class MermaidRenderer (line 16) | class MermaidRenderer extends DocumentHandler {
method init (line 17) | init() {
method onPreRendering (line 22) | async onPreRendering() {
method loadFromCacheOrRender (line 41) | private async loadFromCacheOrRender(element: HTMLElement) {
method calculateNewDiagramScale (line 72) | private calculateNewDiagramScale(svg: SVGSVGElement) {
method realignDiagramContents (line 88) | private realignDiagramContents() {
FILE: quarkdown-html/src/main/typescript/document/handlers/docs/__tests__/sibling-pages-buttons.spec.ts
class DummyDoc (line 4) | class DummyDoc {
FILE: quarkdown-html/src/main/typescript/document/handlers/docs/page-list-autoscroll.ts
constant PAGE_LIST_SELECTOR (line 4) | const PAGE_LIST_SELECTOR = 'nav[data-role="page-list"]';
constant CURRENT_PAGE_SELECTOR (line 5) | const CURRENT_PAGE_SELECTOR = "[aria-current]";
constant STORAGE_KEY (line 6) | const STORAGE_KEY = "qd-page-list-scroll";
class PageListAutoscroll (line 16) | class PageListAutoscroll extends DocumentHandler {
method onPostRendering (line 17) | async onPostRendering() {
method restoreScrollPosition (line 36) | private restoreScrollPosition(aside: HTMLElement) {
method scrollToCurrentPage (line 43) | private scrollToCurrentPage(aside: HTMLElement, currentPage: HTMLEleme...
method saveScrollPositionOnScroll (line 54) | private saveScrollPositionOnScroll(aside: HTMLElement) {
FILE: quarkdown-html/src/main/typescript/document/handlers/docs/search-field-focus.ts
constant SEARCH_SHORTCUT_KEY (line 3) | const SEARCH_SHORTCUT_KEY = "/";
class SearchFieldFocus (line 9) | class SearchFieldFocus extends DocumentHandler {
method onPostRendering (line 10) | async onPostRendering() {
FILE: quarkdown-html/src/main/typescript/document/handlers/docs/search-field.ts
constant SEARCH_INPUT_ID (line 7) | const SEARCH_INPUT_ID = "search-input";
constant SEARCH_RESULTS_ID (line 8) | const SEARCH_RESULTS_ID = "search-results";
constant SEARCH_INDEX_META_NAME (line 9) | const SEARCH_INDEX_META_NAME = "quarkdown:search-index";
constant DEBOUNCE_MS (line 11) | const DEBOUNCE_MS = 150;
constant MAX_RESULTS (line 12) | const MAX_RESULTS = 10;
class SearchField (line 18) | class SearchField extends DocumentHandler {
method onPostRendering (line 25) | async onPostRendering() {
method getSearchIndexPath (line 41) | private getSearchIndexPath(): string | null {
method initializeSearch (line 49) | private async initializeSearch(indexPath: string): Promise<void> {
method createResultsContainer (line 60) | private createResultsContainer(): void {
method bindEvents (line 74) | private bindEvents(): void {
method onInputChange (line 84) | private onInputChange(): void {
method performSearch (line 92) | private performSearch(): void {
method renderResults (line 107) | private renderResults(results: DocumentSearchResult[]): void {
method resolveUrl (line 128) | private resolveUrl(url: string): string {
method onKeyDown (line 137) | private onKeyDown(event: KeyboardEvent): void {
method selectItem (line 174) | private selectItem(items: NodeListOf<HTMLElement>, index: number): void {
method hideResults (line 183) | private hideResults(): void {
method hideResultsDelayed (line 191) | private hideResultsDelayed(): void {
FILE: quarkdown-html/src/main/typescript/document/handlers/docs/sibling-pages-buttons.ts
constant BUTTON_AREA_ID (line 4) | const BUTTON_AREA_ID = "sibling-pages-button-area";
constant PREVIOUS_LINK_ID (line 5) | const PREVIOUS_LINK_ID = "previous-page-anchor";
constant NEXT_LINK_ID (line 6) | const NEXT_LINK_ID = "next-page-anchor";
constant PREVIOUS_ICON_CLASS (line 7) | const PREVIOUS_ICON_CLASS = "bi bi-arrow-left";
constant NEXT_ICON_CLASS (line 8) | const NEXT_ICON_CLASS = "bi bi-arrow-right";
class SiblingPagesButtons (line 15) | class SiblingPagesButtons extends DocumentHandler {
method onPostRendering (line 16) | async onPostRendering() {
method createAnchor (line 40) | private createAnchor(
FILE: quarkdown-html/src/main/typescript/document/handlers/docs/toc-active-tracking.ts
constant TOC_SELECTOR (line 4) | const TOC_SELECTOR = 'aside nav[data-role="table-of-contents"]';
class TocActiveTracking (line 10) | class TocActiveTracking extends DocumentHandler {
method onPostRendering (line 11) | async onPostRendering() {
FILE: quarkdown-html/src/main/typescript/document/handlers/docs/util/page-list-analyzer.ts
constant PAGE_LIST_NAV_SELECTOR (line 1) | const PAGE_LIST_NAV_SELECTOR = 'nav[data-role="page-list"]';
constant CURRENT_PAGE_SELECTOR (line 2) | const CURRENT_PAGE_SELECTOR = 'a[aria-current="page"]';
class PageListAnalyzer (line 9) | class PageListAnalyzer {
method constructor (line 13) | constructor() {
method getAllLinks (line 22) | private getAllLinks(): HTMLAnchorElement[] {
method isSamePageAnchor (line 31) | private isSamePageAnchor(link: HTMLAnchorElement): boolean {
method getCurrentIndex (line 42) | private getCurrentIndex(links: HTMLAnchorElement[]): number | null {
method getNextPageLink (line 51) | getNextPageLink(): HTMLAnchorElement | null {
method getPreviousPageLink (line 61) | getPreviousPageLink(): HTMLAnchorElement | null {
FILE: quarkdown-html/src/main/typescript/document/handlers/footnotes/footnotes-docs.ts
class FootnotesDocs (line 6) | class FootnotesDocs extends FootnotesDocumentHandler {
method onPostRendering (line 7) | async onPostRendering() {
FILE: quarkdown-html/src/main/typescript/document/handlers/footnotes/footnotes-document-handler.ts
method onPreRendering (line 13) | async onPreRendering() {
FILE: quarkdown-html/src/main/typescript/document/handlers/footnotes/footnotes-paged.ts
class FootnotesPaged (line 7) | class FootnotesPaged extends FootnotesDocumentHandler {
method onPreRendering (line 18) | async onPreRendering() {
method onPostRendering (line 36) | async onPostRendering() {
FILE: quarkdown-html/src/main/typescript/document/handlers/footnotes/footnotes-plain.ts
class FootnotesPlain (line 8) | class FootnotesPlain extends FootnotesDocumentHandler {
method init (line 10) | init() {
method getLastDefinitionOffset (line 19) | private getLastDefinitionOffset(marginArea: HTMLElement): number {
method onPostRendering (line 30) | async onPostRendering() {
FILE: quarkdown-html/src/main/typescript/document/handlers/footnotes/footnotes-slides.ts
class FootnotesSlides (line 7) | class FootnotesSlides extends FootnotesDocumentHandler {
method onPostRendering (line 8) | async onPostRendering() {
FILE: quarkdown-html/src/main/typescript/document/handlers/inline-collapsibles.ts
class InlineCollapsibles (line 9) | class InlineCollapsibles extends DocumentHandler {
method onPostRendering (line 10) | async onPostRendering() {
method toggleCollapse (line 18) | private toggleCollapse(span: HTMLElement) {
FILE: quarkdown-html/src/main/typescript/document/handlers/landscape-size-swapper.ts
class LandscapeSizeSwapper (line 9) | class LandscapeSizeSwapper extends DocumentHandler {
method onPreRendering (line 10) | async onPreRendering() {
FILE: quarkdown-html/src/main/typescript/document/handlers/page-margins/page-margins-docs.ts
constant HEADER (line 4) | const HEADER = 'body > header';
constant CONTENT (line 5) | const CONTENT = 'body > .content-wrapper';
constant SIDEBAR_LEFT (line 6) | const SIDEBAR_LEFT = `${CONTENT} > aside:first-child`;
constant SIDEBAR_RIGHT (line 7) | const SIDEBAR_RIGHT = `${CONTENT} > aside:last-child`;
constant FOOTER (line 8) | const FOOTER = `${CONTENT} > main > footer`;
constant MARGIN_TARGETS (line 13) | const MARGIN_TARGETS: Record<string, string> = {
class PageMarginsDocs (line 44) | class PageMarginsDocs extends DocumentHandler {
method onPostRendering (line 46) | async onPostRendering(): Promise<void> {
method createWrapper (line 65) | private createWrapper(initializer: HTMLElement, position: string): HTM...
method getMarginPosition (line 76) | private getMarginPosition(initializer: HTMLElement): string | null {
FILE: quarkdown-html/src/main/typescript/document/handlers/page-margins/page-margins-document-handler.ts
method selectPageMarginInitializers (line 17) | private selectPageMarginInitializers(page: QuarkdownPage | HTMLElement):...
method onPreRendering (line 25) | async onPreRendering() {
method onPostRendering (line 42) | async onPostRendering() {
method getMarginPositionName (line 71) | private getMarginPositionName(initializer: HTMLElement, page: QuarkdownP...
method pushMarginClassList (line 83) | protected pushMarginClassList(target: HTMLElement, initializer: HTMLElem...
FILE: quarkdown-html/src/main/typescript/document/handlers/page-margins/page-margins-paged.ts
class PageMarginsPaged (line 21) | class PageMarginsPaged extends PageMarginsDocumentHandler {
method apply (line 22) | apply(initializer: HTMLElement, page: HTMLElement, marginPositionName:...
FILE: quarkdown-html/src/main/typescript/document/handlers/page-margins/page-margins-slides.ts
class PageMarginsSlides (line 19) | class PageMarginsSlides extends PageMarginsDocumentHandler {
method apply (line 23) | apply(initializer: HTMLElement, page: SlidesPage, marginPositionName: ...
FILE: quarkdown-html/src/main/typescript/document/handlers/page-numbers.ts
class PageNumbers (line 11) | class PageNumbers extends DocumentHandler<PagedLikeQuarkdownDocument<any...
method getTotalPageNumberElements (line 16) | private getTotalPageNumberElements(): NodeListOf<HTMLElement> {
method getCurrentPageNumberElements (line 25) | private getCurrentPageNumberElements(page: QuarkdownPage): NodeListOf<...
method getPageNumberResetMarkers (line 32) | private getPageNumberResetMarkers(page: QuarkdownPage): HTMLElement[] {
method getPageNumberFormatMarkers (line 39) | private getPageNumberFormatMarkers(page: QuarkdownPage): HTMLElement[] {
method updateTotalPageNumbers (line 46) | private updateTotalPageNumbers(pages: QuarkdownPage[]) {
method updateCurrentPageNumbers (line 56) | private updateCurrentPageNumbers(pages: QuarkdownPage[]) {
method updateTableOfContentsPageNumbers (line 93) | private updateTableOfContentsPageNumbers() {
method setTableOfContentsPageNumber (line 110) | private setTableOfContentsPageNumber(anchor: HTMLAnchorElement, value?...
method onPostRendering (line 125) | async onPostRendering() {
FILE: quarkdown-html/src/main/typescript/document/handlers/paged/split-code-blocks-fix-paged.ts
type SplitCodeBlock (line 6) | interface SplitCodeBlock {
class SplitCodeBlocksFixPaged (line 23) | class SplitCodeBlocksFixPaged extends DocumentHandler {
method getSplitCodeBlocks (line 32) | private getSplitCodeBlocks(): SplitCodeBlock[] {
method fixSplitCodeBlockFirstLineIndentation (line 59) | private fixSplitCodeBlockFirstLineIndentation(splitCodeBlocks: SplitCo...
method fixSplitCodeBlockLineNumbers (line 80) | private fixSplitCodeBlockLineNumbers(splitCodeBlocks: SplitCodeBlock[]) {
method onPostRendering (line 106) | async onPostRendering() {
FILE: quarkdown-html/src/main/typescript/document/handlers/persistent-headings.ts
constant MIN_HEADING_LEVEL (line 4) | const MIN_HEADING_LEVEL = 1;
constant MAX_HEADING_LEVEL (line 5) | const MAX_HEADING_LEVEL = 6;
class PersistentHeadings (line 12) | class PersistentHeadings extends DocumentHandler<PagedLikeQuarkdownDocum...
method overwriteLastHeadings (line 38) | private overwriteLastHeadings(page: QuarkdownPage) {
method applyLastHeadings (line 55) | private applyLastHeadings(page: QuarkdownPage) {
method onPostRendering (line 63) | async onPostRendering() {
FILE: quarkdown-html/src/main/typescript/document/handlers/remaining-height.ts
class RemainingHeight (line 9) | class RemainingHeight extends DocumentHandler {
method onPostRendering (line 10) | async onPostRendering() {
FILE: quarkdown-html/src/main/typescript/document/handlers/show-on-ready.ts
class ShowOnReady (line 7) | class ShowOnReady extends DocumentHandler {
method onPreRendering (line 8) | async onPreRendering() {
method onPostRendering (line 12) | async onPostRendering() {
FILE: quarkdown-html/src/main/typescript/document/handlers/sidebar.ts
class Sidebar (line 8) | class Sidebar extends DocumentHandler {
method onPostRendering (line 9) | async onPostRendering() {
FILE: quarkdown-html/src/main/typescript/document/paged-like-quarkdown-document.ts
type QuarkdownPage (line 6) | type QuarkdownPage = {
type PagedLikeQuarkdownDocument (line 14) | interface PagedLikeQuarkdownDocument<TPage extends QuarkdownPage = HTMLE...
FILE: quarkdown-html/src/main/typescript/document/quarkdown-document.ts
type QuarkdownDocument (line 9) | interface QuarkdownDocument {
function prepare (line 42) | function prepare(document: QuarkdownDocument): void {
FILE: quarkdown-html/src/main/typescript/document/type/docs-document.ts
class DocsDocument (line 15) | class DocsDocument extends PlainDocument {
method getHandlers (line 16) | getHandlers(): DocumentHandler[] {
FILE: quarkdown-html/src/main/typescript/document/type/paged-document.ts
class PagedDocument (line 17) | class PagedDocument implements PagedLikeQuarkdownDocument {
method getParentViewport (line 21) | getParentViewport(element: Element): HTMLElement | undefined {
method getPages (line 25) | getPages(): HTMLElement[] {
method getPage (line 29) | getPage(element: HTMLElement): HTMLElement | undefined {
method getPageNumber (line 33) | getPageNumber(page: HTMLElement): number {
method getDisplayPageNumber (line 37) | getDisplayPageNumber(page: HTMLElement): string {
method setDisplayPageNumber (line 41) | setDisplayPageNumber(page: HTMLElement, pageNumber: string) {
method getPageType (line 45) | getPageType(page: HTMLElement): "left" | "right" {
method setupPreRenderingHook (line 50) | setupPreRenderingHook() {
method setupPostRenderingHook (line 55) | setupPostRenderingHook(): void {
method initializeRendering (line 66) | initializeRendering(): void {
method getHandlers (line 70) | getHandlers(): DocumentHandler[] {
FILE: quarkdown-html/src/main/typescript/document/type/plain-document.ts
class PlainDocument (line 11) | class PlainDocument implements QuarkdownDocument {
method getParentViewport (line 15) | getParentViewport(_element: Element): HTMLElement | undefined {
method setupPreRenderingHook (line 20) | setupPreRenderingHook() {
method setupPostRenderingHook (line 27) | setupPostRenderingHook() {
method initializeRendering (line 31) | initializeRendering() {
method getHandlers (line 35) | getHandlers(): DocumentHandler[] {
function getRightMarginArea (line 48) | function getRightMarginArea(): HTMLElement | null {
FILE: quarkdown-html/src/main/typescript/document/type/slides-document.ts
constant SLIDE_SELECTOR (line 13) | const SLIDE_SELECTOR = ".reveal .slides > :is(section, .pdf-page)";
constant BACKGROUND_SELECTOR (line 14) | const BACKGROUND_SELECTOR = ".reveal :is(.backgrounds, .slides > .pdf-pa...
type SlidesPage (line 19) | type SlidesPage = { slide: HTMLElement, background: HTMLElement } & Quar...
class SlidesDocument (line 24) | class SlidesDocument implements PagedLikeQuarkdownDocument<SlidesPage> {
method getConfigProperty (line 29) | private getConfigProperty<T>(property: string, defaultValue: T): T {
method getParentViewport (line 37) | getParentViewport(element: Element): HTMLElement | undefined {
method getPages (line 41) | getPages(): SlidesPage[] {
method getPageNumber (line 61) | getPageNumber(page: SlidesPage): number {
method getDisplayPageNumber (line 69) | getDisplayPageNumber(page: SlidesPage): string {
method setDisplayPageNumber (line 75) | setDisplayPageNumber(page: SlidesPage, pageNumber: string) {
method getPageType (line 79) | getPageType(page: SlidesPage): "left" | "right" {
method getPage (line 84) | getPage(element: HTMLElement): SlidesPage | undefined {
method setupPreRenderingHook (line 89) | setupPreRenderingHook() {
method setupPostRenderingHook (line 94) | setupPostRenderingHook() {
method initializeRendering (line 105) | initializeRendering() {
method getHandlers (line 127) | getHandlers(): DocumentHandler[] {
FILE: quarkdown-html/src/main/typescript/footnotes/footnote-dom.ts
function getOrCreateFootnoteRule (line 7) | function getOrCreateFootnoteRule(footnoteArea: Element) {
function getOrCreateFootnoteArea (line 24) | function getOrCreateFootnoteArea(page: Element) {
FILE: quarkdown-html/src/main/typescript/footnotes/footnote-lookup.ts
function getFootnoteDefinitions (line 8) | function getFootnoteDefinitions(sorted: boolean): HTMLElement[] {
function getFootnoteFirstReference (line 20) | function getFootnoteFirstReference(definitionId: string): HTMLElement | ...
function getFootnoteDefinitionsAndFirstReference (line 29) | function getFootnoteDefinitionsAndFirstReference(sorted: boolean = true)...
FILE: quarkdown-html/src/main/typescript/footnotes/footnote-pair.ts
type FootnotePair (line 4) | interface FootnotePair {
FILE: quarkdown-html/src/main/typescript/index.ts
function isReady (line 17) | function isReady(): boolean {
FILE: quarkdown-html/src/main/typescript/live/live-preview.ts
constant MESSAGE_SOURCE (line 1) | const MESSAGE_SOURCE = 'quarkdown';
constant TARGET_ORIGIN (line 2) | const TARGET_ORIGIN = '*';
function notifyLivePreview (line 10) | function notifyLivePreview(event: string, data: Record<string, any> = {}) {
FILE: quarkdown-html/src/main/typescript/navigation/active-tracking.ts
function initNavigationActiveTracking (line 7) | function initNavigationActiveTracking(navigation: HTMLElement): void {
FILE: quarkdown-html/src/main/typescript/queue/async-execution-queue.ts
class AsyncExecutionQueue (line 19) | class AsyncExecutionQueue {
method pushAsync (line 34) | pushAsync(fn: () => Promise<void>) {
method push (line 47) | push(fn: () => void) {
method addOnComplete (line 56) | addOnComplete(fn: () => void) {
method execute (line 69) | async execute(): Promise<void> {
method isCompleted (line 81) | isCompleted(): boolean {
FILE: quarkdown-html/src/main/typescript/search/__tests__/search-result-expander.spec.ts
function createResult (line 5) | function createResult(overrides: Partial<DocumentSearchResult> = {}): Do...
FILE: quarkdown-html/src/main/typescript/search/search-highlight.ts
function trimTitleFromContent (line 16) | function trimTitleFromContent(content: string, title: string | null): st...
function extractPreviewAroundMatch (line 33) | function extractPreviewAroundMatch(
function highlightTerms (line 81) | function highlightTerms(text: string, matchedTerms: string[]): string {
FILE: quarkdown-html/src/main/typescript/search/search-result-expander.ts
type DisplayItem (line 7) | interface DisplayItem {
function expandResult (line 20) | function expandResult(result: DocumentSearchResult): DisplayItem[] {
function getTermsForField (line 54) | function getTermsForField(matchedFields: Record<string, string[]>, field...
function findMatchingHeadings (line 67) | function findMatchingHeadings(
function isTitleOrHeadingMatch (line 85) | function isTitleOrHeadingMatch(matchedFields: Record<string, string[]>):...
function getHighlightedDescription (line 95) | function getHighlightedDescription(result: DocumentSearchResult): string {
FILE: quarkdown-html/src/main/typescript/search/search-result-renderer.ts
function renderResultItem (line 10) | function renderResultItem(item: DisplayItem, index: number): string {
function renderResultItems (line 27) | function renderResultItems(items: DisplayItem[]): string {
FILE: quarkdown-html/src/main/typescript/search/search.ts
type SearchHeading (line 6) | interface SearchHeading {
type SearchEntry (line 15) | interface SearchEntry {
type SearchIndex (line 27) | interface SearchIndex {
type IndexedDocument (line 34) | interface IndexedDocument {
type DocumentSearchResult (line 47) | interface DocumentSearchResult {
type DocumentSearchOptions (line 58) | interface DocumentSearchOptions {
constant DEFAULT_OPTIONS (line 77) | const DEFAULT_OPTIONS: Required<Omit<DocumentSearchOptions, "maxResults"...
class DocumentSearch (line 91) | class DocumentSearch {
method constructor (line 102) | constructor(index: SearchIndex, options: DocumentSearchOptions = {}) {
method createMiniSearch (line 109) | private createMiniSearch(): MiniSearch<IndexedDocument> {
method indexEntries (line 127) | private indexEntries(entries: SearchEntry[]): void {
method search (line 151) | search(query: string, searchOptions?: SearchOptions): DocumentSearchRe...
method suggest (line 188) | suggest(query: string, maxSuggestions: number = 5): string[] {
method entryCount (line 202) | get entryCount(): number {
function createSearch (line 214) | function createSearch(index: SearchIndex | string, options?: DocumentSea...
FILE: quarkdown-html/src/main/typescript/types/pagedjs.d.ts
class Handler (line 3) | class Handler {
FILE: quarkdown-html/src/main/typescript/util/browser.ts
function isSafari (line 4) | function isSafari(): boolean {
FILE: quarkdown-html/src/main/typescript/util/escape.ts
function escapeHtml (line 6) | function escapeHtml(text: string): string {
function escapeRegExp (line 17) | function escapeRegExp(text: string): string {
FILE: quarkdown-html/src/main/typescript/util/hash.ts
function hashCode (line 6) | function hashCode(str: string): string {
FILE: quarkdown-html/src/main/typescript/util/id.ts
function getAnchorTargetId (line 6) | function getAnchorTargetId(link: HTMLAnchorElement): string | undefined {
FILE: quarkdown-html/src/main/typescript/util/meta.ts
constant ROOT_PATH_META (line 1) | const ROOT_PATH_META = "quarkdown:root-path";
function getMetaContent (line 8) | function getMetaContent(name: string): string | null {
function getRootPath (line 18) | function getRootPath(): string {
FILE: quarkdown-html/src/main/typescript/util/numbering.ts
function formatNumber (line 17) | function formatNumber(number: number, format: string): string {
FILE: quarkdown-html/src/main/typescript/util/visibility.ts
function isHidden (line 6) | function isHidden(element: Element): boolean {
function isBlank (line 15) | function isBlank(element: HTMLElement): boolean {
FILE: quarkdown-html/src/test/e2e/__util/compile.ts
constant DEFAULT_CLI_PATH (line 5) | const DEFAULT_CLI_PATH = path.join(PROJECT_ROOT, "build/install/quarkdow...
constant CLI_PATH (line 7) | const CLI_PATH = process.env.QUARKDOWN_CLI_PATH || DEFAULT_CLI_PATH;
function compile (line 16) | function compile(source: string, outName: string): string {
FILE: quarkdown-html/src/test/e2e/__util/css.ts
function getFullText (line 8) | async function getFullText(locator: Locator): Promise<string> {
function getBeforeContent (line 23) | async function getBeforeContent(locator: Locator): Promise<string> {
function isBeforeInline (line 33) | async function isBeforeInline(locator: Locator): Promise<boolean> {
function computeCssValue (line 55) | async function computeCssValue<T>(
function getComputedSizeProperty (line 82) | async function getComputedSizeProperty(context: Locator | Page, value: s...
function getComputedColor (line 92) | async function getComputedColor(context: Locator | Page, value: string):...
function evaluateComputedStyle (line 101) | async function evaluateComputedStyle(locator: Locator): Promise<CSSStyle...
FILE: quarkdown-html/src/test/e2e/__util/free-port.ts
function findFreePort (line 7) | async function findFreePort(): Promise<number> {
FILE: quarkdown-html/src/test/e2e/__util/global-setup.ts
constant SERVER_PORT (line 7) | const SERVER_PORT = 8089;
constant SERVER_STATE_FILE (line 8) | const SERVER_STATE_FILE = path.join(OUTPUT_DIR, ".server-state.json");
function globalSetup (line 10) | async function globalSetup() {
function waitForServer (line 43) | async function waitForServer(url: string, timeout = 10000): Promise<void> {
function getServerUrl (line 57) | function getServerUrl(): string {
FILE: quarkdown-html/src/test/e2e/__util/global-teardown.ts
constant SERVER_STATE_FILE (line 5) | const SERVER_STATE_FILE = path.join(OUTPUT_DIR, ".server-state.json");
function globalTeardown (line 7) | async function globalTeardown() {
FILE: quarkdown-html/src/test/e2e/__util/live-preview-runner.ts
type LivePreviewContext (line 13) | interface LivePreviewContext {
type LivePreviewTestOptions (line 32) | interface LivePreviewTestOptions {
function waitForServer (line 46) | async function waitForServer(url: string, timeout: number): Promise<void> {
function waitForIframeReady (line 64) | async function waitForIframeReady(page: Page, timeout: number): Promise<...
function runLivePreviewTest (line 102) | async function runLivePreviewTest(
FILE: quarkdown-html/src/test/e2e/__util/paths.ts
constant PROJECT_ROOT (line 3) | const PROJECT_ROOT = path.resolve(__dirname, "../../../../..");
constant OUTPUT_DIR (line 4) | const OUTPUT_DIR = path.join(PROJECT_ROOT, "build/e2e");
constant ENTRY_POINT (line 5) | const ENTRY_POINT = "main.qd";
type DocumentType (line 7) | type DocumentType = "plain" | "slides" | "slides-print" | "paged" | "docs";
FILE: quarkdown-html/src/test/e2e/__util/runner.ts
function uniqueId (line 9) | function uniqueId(): string {
function createSourceWithDocType (line 21) | function createSourceWithDocType(testDir: string, docType: DocumentType,...
type RunTestOptions (line 33) | interface RunTestOptions {
function runTest (line 46) | async function runTest(
function waitForReady (line 86) | async function waitForReady(page: Page): Promise<void> {
FILE: quarkdown-html/src/test/e2e/alerts/box/box.spec.ts
constant BOX_TYPES (line 6) | const BOX_TYPES = ["callout", "tip", "note", "warning", "error"] as const;
FILE: quarkdown-html/src/test/e2e/alerts/quote/quote.spec.ts
constant ALERT_TYPES (line 6) | const ALERT_TYPES = ["tip", "note", "warning", "important"] as const;
FILE: quarkdown-html/src/test/e2e/captions/index.ts
type CaptionPosition (line 3) | type CaptionPosition = "top" | "bottom";
function assertCaptionPosition (line 5) | async function assertCaptionPosition(
function assertFigureCaption (line 17) | async function assertFigureCaption(
function assertTableCaption (line 39) | async function assertTableCaption(page: Page, position: CaptionPosition) {
FILE: quarkdown-html/src/test/e2e/code/numbered/numbered.spec.ts
function getCaptionBeforeContent (line 5) | async function getCaptionBeforeContent(page: any, figcaption: any): Prom...
FILE: quarkdown-html/src/test/e2e/docs/content-width/content-width.spec.ts
type LayoutWidths (line 5) | interface LayoutWidths {
function getLayoutWidths (line 14) | async function getLayoutWidths(page: any): Promise<LayoutWidths> {
FILE: quarkdown-html/src/test/e2e/docs/layout/layout.spec.ts
function expectApprox (line 6) | function expectApprox(actual: number, expected: number) {
FILE: quarkdown-html/src/test/e2e/docs/multi-page/sibling-pages.spec.ts
constant NAV_SELECTOR (line 5) | const NAV_SELECTOR = 'nav[data-role="page-list"]';
constant BUTTON_AREA_SELECTOR (line 6) | const BUTTON_AREA_SELECTOR = "#sibling-pages-button-area";
constant PREVIOUS_LINK_SELECTOR (line 7) | const PREVIOUS_LINK_SELECTOR = "#previous-page-anchor";
constant NEXT_LINK_SELECTOR (line 8) | const NEXT_LINK_SELECTOR = "#next-page-anchor";
function assertButtons (line 10) | async function assertButtons(
FILE: quarkdown-html/src/test/e2e/doctype/responsiveness/responsiveness.spec.ts
constant DESKTOP_WIDTH (line 5) | const DESKTOP_WIDTH = 1400;
constant MOBILE_WIDTH (line 6) | const MOBILE_WIDTH = 600;
constant TABLET_WIDTH (line 7) | const TABLET_WIDTH = 1000;
FILE: quarkdown-html/src/test/e2e/font/index.ts
function getCssVar (line 8) | async function getCssVar(page: Page, varName: string): Promise<string> {
function isHashedFont (line 17) | function isHashedFont(fontFamily: string): boolean {
function fontFamilyMatches (line 25) | function fontFamilyMatches(computedFontFamily: string, expectedFontFamil...
function testCustomFontApplication (line 36) | async function testCustomFontApplication(page: Page, expectCustomHeading...
FILE: quarkdown-html/src/test/e2e/font/localized-default/localized-default.spec.ts
constant FALLBACK_HEADING_FONT (line 7) | const FALLBACK_HEADING_FONT = "Inter";
constant FALLBACK_MAIN_FONT (line 8) | const FALLBACK_MAIN_FONT = "Lato";
FILE: quarkdown-html/src/test/e2e/list/issue_overjustified-list-in-page-break/overjustified-list-in-page-break.spec.ts
constant TOTAL_ITEMS (line 5) | const TOTAL_ITEMS = 9;
FILE: quarkdown-html/src/test/e2e/live-preview/live-preview.spec.ts
constant TEST_DIR (line 7) | const TEST_DIR = __dirname;
constant TEST_TIMEOUT (line 10) | const TEST_TIMEOUT = 90_000;
constant RELOAD_TIMEOUT (line 13) | const RELOAD_TIMEOUT = 30_000;
constant DOC_TYPES (line 15) | const DOC_TYPES: DocumentType[] = ["plain", "paged", "slides", "docs"];
function readOriginalMain (line 20) | function readOriginalMain(): string {
function mainWithMarker (line 27) | function mainWithMarker(marker: string): string {
constant SCROLLABLE_DOC_TYPES (line 89) | const SCROLLABLE_DOC_TYPES: DocumentType[] = ["plain", "paged", "docs"];
FILE: quarkdown-html/src/test/e2e/mermaid/index.ts
function assertMermaidBase (line 7) | async function assertMermaidBase(page: Page) {
function assertSvgWidthRatio (line 33) | async function assertSvgWidthRatio(
FILE: quarkdown-html/src/test/e2e/multicolumn/full-span/full-span.spec.ts
function distinctColumnCount (line 8) | async function distinctColumnCount(locator: import("@playwright/test").L...
FILE: quarkdown-html/src/test/e2e/page-format/index.ts
constant A4_WIDTH_PX (line 5) | const A4_WIDTH_PX = 210 * 96 / 25.4;
constant A4_HEIGHT_PX (line 6) | const A4_HEIGHT_PX = 297 * 96 / 25.4;
constant A5_WIDTH_PX (line 9) | const A5_WIDTH_PX = 148 * 96 / 25.4;
constant A5_HEIGHT_PX (line 10) | const A5_HEIGHT_PX = 210 * 96 / 25.4;
function getPageSizeTarget (line 12) | function getPageSizeTarget(page: Page, docType: DocumentType): Locator {
FILE: quarkdown-html/src/test/e2e/page-format/scoped/range-side/range-side.spec.ts
function getPage (line 20) | function getPage(page: import("@playwright/test").Page, index: number) {
function getArea (line 24) | function getArea(page: import("@playwright/test").Page, index: number) {
FILE: quarkdown-html/src/test/e2e/page-format/scoped/range/range.spec.ts
function getPage (line 9) | function getPage(page: import("@playwright/test").Page, index: number) {
FILE: quarkdown-html/src/test/e2e/page-format/scoped/side/side.spec.ts
function getLeftPage (line 11) | function getLeftPage(page: import("@playwright/test").Page) {
function getRightPage (line 15) | function getRightPage(page: import("@playwright/test").Page) {
FILE: quarkdown-html/src/test/e2e/page-format/size/width/width.spec.ts
constant EXPECTED_WIDTH (line 6) | const EXPECTED_WIDTH = 100;
FILE: quarkdown-html/src/test/e2e/page-margins/all-pages/all-pages.spec.ts
function assertMarginContent (line 10) | async function assertMarginContent(marginContent: ReturnType<typeof page...
FILE: quarkdown-html/src/test/e2e/page-margins/format-page-numbers/format-page-numbers.spec.ts
constant EXPECTED_TEXTS (line 6) | const EXPECTED_TEXTS = [
FILE: quarkdown-html/src/test/e2e/page-margins/index.ts
constant MARGIN_NAMES (line 7) | const MARGIN_NAMES = [
constant MARGIN_SUFFIX (line 27) | const MARGIN_SUFFIX: Record<string, string> = {
constant DOCS_CONTAINERS (line 47) | const DOCS_CONTAINERS: Record<string, string> = DOCS_MARGIN_CONTAINERS;
function getPageContainers (line 52) | function getPageContainers(page: Page, docType: string): Locator {
function getMarginContent (line 61) | function getMarginContent(container: Locator, docType: string, marginNam...
FILE: quarkdown-html/src/test/e2e/page-margins/mirror/mirror.spec.ts
constant MIRROR_MARGINS (line 9) | const MIRROR_MARGINS: Record<string, {odd: string; even: string}> = {
FILE: quarkdown-html/src/test/e2e/page-margins/page-counter/page-counter.spec.ts
constant EXPECTED_TEXTS (line 6) | const EXPECTED_TEXTS = [
FILE: quarkdown-html/src/test/e2e/page-margins/persistent-headings/persistent-headings.spec.ts
constant EXPECTED_HEADINGS (line 7) | const EXPECTED_HEADINGS: [string, string, string][] = [
constant MARGINS (line 19) | const MARGINS = ["topleft", "topcenter", "topright"] as const;
FILE: quarkdown-html/src/test/e2e/page-margins/scoped/scoped.spec.ts
constant EXPECTED (line 7) | const EXPECTED: Array<{topcenter?: string; bottomcenter?: string}> = [
FILE: quarkdown-html/src/test/e2e/quarkdown.ts
type TestOptions (line 8) | interface TestOptions {
function outputDir (line 16) | function outputDir(testDir: string): string {
function suite (line 27) | function suite(testDir: string) {
FILE: quarkdown-html/src/test/e2e/sidebar/sidebar.spec.ts
constant MOBILE_WIDTH (line 7) | const MOBILE_WIDTH = 600;
FILE: quarkdown-html/src/test/e2e/stack/default/default.spec.ts
function assertHorizontalRow (line 6) | function assertHorizontalRow(boxes: BoundingBox[]) {
function assertVerticalColumn (line 15) | function assertVerticalColumn(boxes: BoundingBox[]) {
FILE: quarkdown-html/src/test/e2e/stack/grid-row-column-gap/grid-row-column-gap.spec.ts
constant EXPECTED_GAPS (line 6) | const EXPECTED_GAPS = [
FILE: quarkdown-html/src/test/e2e/stack/index.ts
type BoundingBox (line 4) | type BoundingBox = NonNullable<Awaited<ReturnType<Locator["boundingBox"]...
function getChildBoxes (line 8) | async function getChildBoxes(container: Locator, count: number): Promise...
function assertHorizontalRow (line 18) | function assertHorizontalRow(boxes: BoundingBox[], gap: number) {
function assertVerticalColumn (line 25) | function assertVerticalColumn(boxes: BoundingBox[], gap: number) {
FILE: quarkdown-html/src/test/e2e/toc/format-page-numbers/format-page-numbers.spec.ts
constant EXPECTED_TEXTS (line 6) | const EXPECTED_TEXTS = [
FILE: quarkdown-html/src/test/e2e/toc/index.ts
constant TOC_SELECTOR (line 3) | const TOC_SELECTOR = "nav[data-role='table-of-contents']";
constant EXPECTED_NUMBERS (line 4) | const EXPECTED_NUMBERS = ["1", "2", "2.1", "2.1.1", "3", "3.1", "3.2"];
function assertTocStructure (line 6) | async function assertTocStructure(page: Page, itemCount: number = 7) {
function assertTocNumbering (line 16) | async function assertTocNumbering(
function assertTocLinks (line 36) | async function assertTocLinks(page: Page, expectedTexts: string[] = EXPE...
Condensed preview — 1523 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,762K chars).
[
{
"path": ".dockerignore",
"chars": 6,
"preview": "build/"
},
{
"path": ".github/FUNDING.yml",
"chars": 14,
"preview": "github: iamgio"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.yml",
"chars": 1598,
"preview": "name: Bug report\ndescription: Report a bug or unexpected behavior\ntitle: \"[Bug] \"\nlabels: [\"bug\"]\nbody:\n - type: markdo"
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 179,
"preview": "blank_issues_enabled: false\ncontact_links:\n - name: Question\n url: https://github.com/iamgio/quarkdown/discussions/n"
},
{
"path": ".github/ISSUE_TEMPLATE/enhancement.yml",
"chars": 1420,
"preview": "name: Enhancement suggestion\ndescription: Suggest a new feature or improvement\ntitle: \"[Enhancement] \"\nlabels: [\"enhance"
},
{
"path": ".github/PULL_REQUEST_TEMPLATE.md",
"chars": 439,
"preview": "- [X] I confirm an issue for this change exists, and it was discussed with maintainers.\n- [X] I have read the [contribut"
},
{
"path": ".github/actions/bump-scoop/action.yml",
"chars": 2097,
"preview": "name: \"Bump Scoop Manifest\"\ndescription: \"Update Scoop bucket manifest with a new version\"\n\ninputs:\n version:\n descr"
},
{
"path": ".github/actions/deploy-wiki/action.yml",
"chars": 753,
"preview": "name: Deploy Wiki\ndescription: Builds and deploys the docs folder to the wiki directory of gh-pages\n\ninputs:\n quarkdown"
},
{
"path": ".github/actions/setup-environment/action.yml",
"chars": 1638,
"preview": "name: Quarkdown Environment Setup\ndescription: Sets up Quarkdown execution environment\ninputs:\n full-checkout:\n desc"
},
{
"path": ".github/actions/update-emoji-list/action.yml",
"chars": 1423,
"preview": "name: Update Emoji List\ndescription: Generates emoji list using Quarkdown and commits it to the gh-pages-src branch\ninpu"
},
{
"path": ".github/actions/update-emoji-list/generate.qd",
"chars": 172,
"preview": ".docname {emoji-list}\n\n.var {headers}\n - Emoji\n - Code\n\n.tablebyrows {.headers}\n .foreach {.allemojis}\n "
},
{
"path": ".github/workflows/deploy-wiki.yml",
"chars": 568,
"preview": "name: Deploy Wiki\n\non:\n workflow_dispatch:\n\njobs:\n deploy:\n runs-on: ubuntu-latest\n\n steps:\n - uses: iamgio"
},
{
"path": ".github/workflows/generate-pdf/color.txt",
"chars": 32,
"preview": "paperwhite\ndarko\nbeaver\ngalactic"
},
{
"path": ".github/workflows/generate-pdf/generate-theme-combinations.js",
"chars": 1629,
"preview": "const fs = require('fs');\nconst path = require('path');\n\nconst PROJECT_DIR = 'mock';\nconst MAIN_FILE = PROJECT_DIR + '/m"
},
{
"path": ".github/workflows/generate-pdf/layout.txt",
"chars": 33,
"preview": "latex\nminimal\nbeamer\nhyperlegible"
},
{
"path": ".github/workflows/generate-pdf.yml",
"chars": 1889,
"preview": "name: PDF generation via Puppeteer\n\non:\n push:\n tags: [ \"v*\" ]\n paths-ignore:\n - '*.md'\n - '**/README.m"
},
{
"path": ".github/workflows/gradle-deploy.yml",
"chars": 4999,
"preview": "# This workflow will build the project with Gradle and release its build.\n\nname: Gradle deploy\n\non:\n push:\n branches"
},
{
"path": ".github/workflows/gradle-test.yml",
"chars": 2709,
"preview": "# This workflow will build the project with Gradle and release its build.\n\nname: Gradle test\n\non:\n workflow_call:\n pus"
},
{
"path": ".github/workflows/update-emoji-list.yml",
"chars": 980,
"preview": "# This workflow updates the emoji list on the gh-pages-src branch.\n\nname: Update emoji list\n\non:\n schedule:\n # Runs "
},
{
"path": ".gitignore",
"chars": 1617,
"preview": "##############################\n## Java\n##############################\n.mtj.tmp/\n*.class\n*.jar\n*.war\n*.ear\n*.nar\nhs_err_p"
},
{
"path": ".run/CLI_Docs.run.xml",
"chars": 601,
"preview": "<component name=\"ProjectRunConfigurationManager\">\n <configuration default=\"false\" name=\"CLI: Docs\" type=\"JetRunConfigur"
},
{
"path": ".run/CLI_Mock.run.xml",
"chars": 577,
"preview": "<component name=\"ProjectRunConfigurationManager\">\n <configuration default=\"false\" name=\"CLI: Mock\" type=\"JetRunConfigur"
},
{
"path": ".run/Lint_format.run.xml",
"chars": 1136,
"preview": "<component name=\"ProjectRunConfigurationManager\">\n <configuration default=\"false\" name=\"Lint: format\" type=\"GradleRunCo"
},
{
"path": ".run/Test_full_suite.run.xml",
"chars": 1132,
"preview": "<component name=\"ProjectRunConfigurationManager\">\n <configuration default=\"false\" name=\"Test: full suite\" type=\"GradleR"
},
{
"path": ".run/Test_minimal_suite.run.xml",
"chars": 1248,
"preview": "<component name=\"ProjectRunConfigurationManager\">\n <configuration default=\"false\" name=\"Test: minimal suite\" type=\"Grad"
},
{
"path": "CHANGELOG.md",
"chars": 14411,
"preview": "# Changelog\n\n## [Unreleased]\n\n### Added\n\n#### [CSL bibliography styles](https://quarkdown.com/wiki/bibliography) (breaki"
},
{
"path": "CLAUDE.md",
"chars": 18642,
"preview": "# About Quarkdown\n\nThis is the Quarkdown project. Quarkdown is a:\n- Turing-complete Markdown flavor, with a `.qd` standa"
},
{
"path": "CONTRIBUTING.md",
"chars": 7668,
"preview": "[Issues]: https://github.com/iamgio/quarkdown/issues\n[Issue]: https://github.com/iamgio/quarkdown/issues\n[Discussions]: "
},
{
"path": "Dockerfile",
"chars": 1398,
"preview": "# Build stage via Gradle\nFROM gradle:8.14.3-jdk17 AS builder\n\nCOPY . /app\nWORKDIR /app\n\n# Build the distribution zip\nRUN"
},
{
"path": "LICENSE",
"chars": 35224,
"preview": " GNU GENERAL PUBLIC LICENSE\n Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
},
{
"path": "README.md",
"chars": 18735,
"preview": "<p align=\"center\">\n <picture>\n <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubusercontent.co"
},
{
"path": "build.gradle.kts",
"chars": 5208,
"preview": "\nimport org.jetbrains.kotlin.gradle.dsl.JvmTarget\nimport org.jetbrains.kotlin.gradle.tasks.KotlinCompile\nimport java.tim"
},
{
"path": "demo/code/Point.java",
"chars": 256,
"preview": "public final class Point {\n private final int x;\n private final int y;\n\n public Point(int x, int y) {\n t"
},
{
"path": "demo/csv/people.csv",
"chars": 130,
"preview": "\"Username\",\"Favorite food\",\"Favorite beverage\"\n\"john\",\"Chicken\",\"Orange juice\"\n\"iamgio\",\"Pasta\",\"Iced tea\"\n\"daniel\",\"Sus"
},
{
"path": "demo/demo.qd",
"chars": 8629,
"preview": ".docname {Quarkdown demo}\n.docauthor {iamgio}\n.doctype {slides}\n.doclang {English}\n.theme {darko} layout:{minimal}\n.auto"
},
{
"path": "demo/mermaid/flow.mmd",
"chars": 195,
"preview": "flowchart LR\n A([Start]) --> B[Enter username and password]\n B --> C{Correct?}\n C -- Yes --> D[Redirect to dash"
},
{
"path": "demo/sources/other.qd",
"chars": 68,
"preview": "### Hello there!\n\nThis content was **included from another source**."
},
{
"path": "docs/_nav.qd",
"chars": 4294,
"preview": "###! Getting started\n- [Quickstart](quickstart.qd)\n\n###! Documentation\n- [Stable ↗](https://quarkdown.com/docs/quarkdown"
},
{
"path": "docs/_setup.qd",
"chars": 1514,
"preview": ".doclang {English}\n.theme {galactic} layout:{hyperlegible}\n\n.numbering\n - example: 1\n\n.html {.read {assets/analytics."
},
{
"path": "docs/align.qd",
"chars": 433,
"preview": ".docname {Align}\n.include {docs}\n\nThe **`.align`** block function sets the horizontal alignment of content, including mu"
},
{
"path": "docs/assets/analytics.html",
"chars": 144,
"preview": "<script defer src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon='{\"token\": \"7ff9d84e763543269faa5"
},
{
"path": "docs/assets/people.csv",
"chars": 161,
"preview": "\"Username\",\"Birth year\",\"Favorite food\",\"Favorite drink\"\n\"john\",\"1992\",\"Chicken\",\"Orange juice\"\n\"iamgio\",\"2002\",\"Pasta\","
},
{
"path": "docs/assets/people2.csv",
"chars": 135,
"preview": "Name, Favorite drink, Age *(as of 2026)*\nAlice, Coffee, .subtract {2026} {1995}\nBob, *Pepsi*, .subtrac"
},
{
"path": "docs/assets/point.ts",
"chars": 139,
"preview": "export class Point {\n x: number;\n y: number;\n\n constructor(x: number, y: number) {\n this.x = x;\n "
},
{
"path": "docs/assets/sales.csv",
"chars": 157,
"preview": "Year, A Sales, B Sales\n2017, 85, 230\n2018, 100, 190\n2019, 135, 180\n2020, 180, 175\n2021, 240, 200\n2022, 320, 250\n2023, 43"
},
{
"path": "docs/assets/style.css",
"chars": 789,
"preview": ".page-margin-top-left a {\n display: flex;\n}\n\nheader .version {\n opacity: 0.6;\n transform: translateY(2px);\n}\n\n."
},
{
"path": "docs/bibliography/file.bib",
"chars": 798,
"preview": "@article{einstein,\n author = \"Albert Einstein\",\n title = \"Zur Elektrodynamik bewegter Körper. (German)\n "
},
{
"path": "docs/bibliography/source.qd",
"chars": 293,
"preview": "Einstein's publication .cite {einstein} in 1905 revolutionized the field of physics.\nSimilarly, Hawking's book .cite {ha"
},
{
"path": "docs/bibliography.qd",
"chars": 3741,
"preview": ".docname {Bibliography}\n.include {docs}\n\nQuarkdown provides CSL-powered bibliography support for the following bibliogra"
},
{
"path": "docs/boolean.qd",
"chars": 811,
"preview": ".docname {Boolean}\n.include {docs}\n\nBoolean values are represented by the following literals, which are **case insensiti"
},
{
"path": "docs/box.qd",
"chars": 1332,
"preview": ".docname {Box}\n.include {docs}\n\nThe **`.box`** .docslink {quarkdown-stdlib/com.quarkdown.stdlib.module.Layout/box.html} "
},
{
"path": "docs/caption-position.qd",
"chars": 1755,
"preview": ".docname {Caption position}\n.include {docs}\n\nThe **`.captionposition`** .docslink {quarkdown-stdlib/com.quarkdown.stdlib"
},
{
"path": "docs/cli-compiler.qd",
"chars": 289,
"preview": ".docname {CLI - Compiler}\n.include {docs}\n\n**`quarkdown c <file>`** is the command for compiling a main source file into"
},
{
"path": "docs/cli-project-creator.qd",
"chars": 1945,
"preview": ".docname {CLI - Project creator}\n.include {docs}\n\nThe **project creator** is a CLI project wizard that makes it fast to "
},
{
"path": "docs/cli-webserver.qd",
"chars": 842,
"preview": ".docname {CLI - Webserver}\n.include {docs}\n\nQuarkdown's webserver allows direct communication between the compiler and t"
},
{
"path": "docs/clip.qd",
"chars": 685,
"preview": ".docname {Clip}\n.include {docs}\n\nThe **`.clip {shape}`** block function clips its content to a defined shape.\n\nSupported"
},
{
"path": "docs/code-caption.qd",
"chars": 935,
"preview": ".docname {Code caption}\n.include {docs}\n\nQuarkdown introduces code captions, which you can set by adding a caption direc"
},
{
"path": "docs/code.qd",
"chars": 2226,
"preview": ".docname {Code}\n.include {docs}\n\nYou can create code blocks using the standard Markdown specification: either with 4-spa"
},
{
"path": "docs/collapsible.qd",
"chars": 730,
"preview": ".docname {Collapsible}\n.include {docs}\n\nThe **`.collapse`** function creates an interactive collapsible block that users"
},
{
"path": "docs/color.qd",
"chars": 797,
"preview": ".docname {Color}\n.include {docs}\n\nYou can define a `Color` value in any of the following ways:\n\n- **Hexadecimal:** `#hex"
},
{
"path": "docs/conditional-statements.qd",
"chars": 1451,
"preview": ".docname {Conditional statements}\n.include {docs}\n\nThe **`.if`** function creates a conditional statement:\n\n1. The first"
},
{
"path": "docs/container.qd",
"chars": 3561,
"preview": ".docname {Container}\n.include {docs}\n\nThe **`.container`** .docslink {quarkdown-stdlib/com.quarkdown.stdlib.module.Layou"
},
{
"path": "docs/cross-references.qd",
"chars": 2985,
"preview": ".docname {Cross references}\n.include {docs}\n\nIn typesetting, cross-references are references to other parts of the docum"
},
{
"path": "docs/css.qd",
"chars": 3053,
"preview": ".docname {CSS}\n.include {docs}\n\nThe **`.css`** .docslink {quarkdown-stdlib/com.quarkdown.stdlib.module.Injection/css.htm"
},
{
"path": "docs/custom-figure.qd",
"chars": 457,
"preview": ".docname {Custom figure}\n.include {docs}\n\n.numbering\n - figures: 1\n\nThe **`.figure {caption?} {body}`** function gene"
},
{
"path": "docs/declaring-functions.qd",
"chars": 2812,
"preview": ".docname {Declaring functions}\n.include {docs}\n\nYou can declare functions using the **`.function`** .docslink {quarkdown"
},
{
"path": "docs/destructuring.qd",
"chars": 1738,
"preview": ".docname {Destructuring}\n.include {docs}\n\nDestructuring splits a [lambda](lambda.qd) parameter into its individual compo"
},
{
"path": "docs/dictionary.qd",
"chars": 1685,
"preview": ".docname {Dictionary}\n.include {docs}\n\nIn Quarkdown, a dictionary is a collection of key-value pairs without duplicate k"
},
{
"path": "docs/docs-library.qd",
"chars": 4080,
"preview": ".docname {Docs library}\n.include {docs}\n\nThe built-in .repolink {`docs`} {blob/main/quarkdown-libs/src/main/resources/do"
},
{
"path": "docs/document-metadata.qd",
"chars": 5980,
"preview": ".docname {Document metadata}\n.include {docs}\n\nYou can set document information using the following functions. By convent"
},
{
"path": "docs/document-types.qd",
"chars": 3370,
"preview": ".docname {Document types}\n.include {docs}\n\nThe [`.doctype`](document-metadata.qd) function defines the type of document "
},
{
"path": "docs/emojis.qd",
"chars": 1206,
"preview": ".docname {Emojis}\n.include {docs}\n\nQuarkdown documents support emojis through direct insertion or shortcode functions.\n\n"
},
{
"path": "docs/enumeration-entry.qd",
"chars": 1111,
"preview": ".docname {Enumeration entry}\n.include {docs}\n\nAn **enumeration entry** is an input value that matches the name of an ele"
},
{
"path": "docs/figure.qd",
"chars": 877,
"preview": ".docname {Figure}\n.include {docs}\n\nQuarkdown introduces the concept of **figure**, which is missing in base Markdown. A "
},
{
"path": "docs/file-data.qd",
"chars": 3322,
"preview": ".docname {File data}\n.include {docs}\n\nQuarkdown provides functions to retrieve information from files.\n\n> [!NOTE]\n> The "
},
{
"path": "docs/file-tree.qd",
"chars": 955,
"preview": ".docname {File Tree}\n.include {docs}\n\nThe **`.filetree`** .docslink {quarkdown-stdlib/com.quarkdown.stdlib.module.MiscEl"
},
{
"path": "docs/float.qd",
"chars": 508,
"preview": ".docname {Float}\n.include {docs}\n\nThe **`.float {alignment}`** function transforms any content into a floating element t"
},
{
"path": "docs/font-configuration.qd",
"chars": 2182,
"preview": ".docname {Font configuration}\n.include {docs}\n\nThe **`.font`** .docslink {quarkdown-stdlib/com.quarkdown.stdlib.module.D"
},
{
"path": "docs/footnotes.qd",
"chars": 3086,
"preview": ".docname {Footnotes}\n.include {docs}\n\nFootnotes allow readers to reference additional information without cluttering the"
},
{
"path": "docs/headings.qd",
"chars": 4131,
"preview": ".docname {Headings}\n.include {docs}\n\nThe **`.heading {content} {depth}`** .docslink {quarkdown-stdlib/com.quarkdown.stdl"
},
{
"path": "docs/html.qd",
"chars": 2231,
"preview": ".docname {HTML}\n.include {docs}\n\nStandard Markdown specifications allow freely mixing Markdown and HTML, as they are mea"
},
{
"path": "docs/icons.qd",
"chars": 543,
"preview": ".docname {Icons}\n.include {docs}\n\nThe **`.icon {name}`** .docslink {quarkdown-stdlib/com.quarkdown.stdlib.module.Icon/ic"
},
{
"path": "docs/image-size.qd",
"chars": 2018,
"preview": ".docname {Image size}\n.include {docs}\n\nWhile base Markdown requires HTML code to constrain the size of an image, Quarkdo"
},
{
"path": "docs/importing-external-libraries.qd",
"chars": 906,
"preview": ".docname {Importing external libraries}\n.include {docs}\n\nThe **`.include`** function, previously seen in [*Including oth"
},
{
"path": "docs/including-other-quarkdown-files.qd",
"chars": 3589,
"preview": ".docname {Including other Quarkdown files}\n.include {docs}\n\nThe **`.include {file} {sandbox?}`** .docslink {quarkdown-st"
},
{
"path": "docs/inclusion-vs-subdocuments.qd",
"chars": 2410,
"preview": ".docname {Inclusion vs subdocuments}\n.include {docs}\n\nQuarkdown offers two ways to include content from other files: **i"
},
{
"path": "docs/inside-live-preview.qd",
"chars": 2832,
"preview": ".docname {Inside live preview}\n.include {docs}\n\nQuarkdown's [webserver](cli-webserver.qd) enables direct communication b"
},
{
"path": "docs/iterable.qd",
"chars": 1506,
"preview": ".docname {Iterable}\n.include {docs}\n\nIterable values are ordered lists or unordered sets that you can iterate through wi"
},
{
"path": "docs/lambda.qd",
"chars": 2231,
"preview": ".docname {Lambda}\n.include {docs}\n\nA **lambda** is a block of code that maps a variable number of parameters into a sing"
},
{
"path": "docs/landscape-content.qd",
"chars": 785,
"preview": ".docname {Landscape content}\n.include {docs}\n\n> Warning: This feature is **experimental**.\n\nFitting wide tables, diagram"
},
{
"path": "docs/let.qd",
"chars": 937,
"preview": ".docname {Let}\n.include {docs}\n\nThe **`.let`** function defines a temporary variable that is accessible only within its "
},
{
"path": "docs/line-breaks.qd",
"chars": 1027,
"preview": ".docname {Line breaks}\n.include {docs}\n\nQuarkdown follows the standard Markdown specification, so you can create soft li"
},
{
"path": "docs/localization.qd",
"chars": 3533,
"preview": ".docname {Localization}\n.include {docs}\n\nQuarkdown supports **string localization** out of the box.\n\nThe first step is t"
},
{
"path": "docs/logging.qd",
"chars": 880,
"preview": ".docname {Logging}\n.include {docs}\n\nQuarkdown provides several ways to log content to standard channels, which can be us"
},
{
"path": "docs/loops.qd",
"chars": 1409,
"preview": ".docname {Loops}\n.include {docs}\n\n## For-each\n\nThe main type of loop is provided by the **`.foreach`** function, which a"
},
{
"path": "docs/main.qd",
"chars": 1653,
"preview": ".docname {Quarkdown Wiki}\n.include {docs}\n\n.css\n h1 { opacity: 0; height: 0; margin: 0; padding: 0; }\n\n figure { m"
},
{
"path": "docs/markdown-content.qd",
"chars": 1656,
"preview": ".docname {Markdown content}\n.include {docs}\n\nMany functions accept rich Quarkdown content as their argument.\n\n## Block c"
},
{
"path": "docs/math.qd",
"chars": 845,
"preview": ".docname {Math}\n.include {docs}\n\nMathematical functions provide a way to perform numeric operations.\n\n.examplemirror\n "
},
{
"path": "docs/media-storage.qd",
"chars": 1766,
"preview": ".docname {Media storage}\n.include {docs}\n\n**Media storage** is a feature that ensures all required files are present in "
},
{
"path": "docs/mermaid-diagrams.qd",
"chars": 2178,
"preview": ".docname {Mermaid diagrams}\n.include {docs}\n\nQuarkdown offers full Mermaid interoperability via the **`.mermaid`** block"
},
{
"path": "docs/multi-column-layout/source.qd",
"chars": 4966,
"preview": ".doctype {paged}\n.pageformat columns:{2}\n\n.nonumbering\n\n# Robinson Crusoe\n\nI was born in the year 1632, in the city of Y"
},
{
"path": "docs/multi-column-layout.qd",
"chars": 636,
"preview": ".docname {Multi-column layout}\n.include {docs}\n\n[**`.pageformat {columns}`**](page-format.qd) applies a multi-column lay"
},
{
"path": "docs/none.qd",
"chars": 3516,
"preview": ".docname {None}\n.include {docs}\n\n*None* is a special value that represents nothing or emptiness (similar to `null` in ma"
},
{
"path": "docs/numbering.qd",
"chars": 7052,
"preview": ".docname {Numbering}\n.include {docs}\n\nThe **`.numbering`** function sets the global numbering configuration of the docum"
},
{
"path": "docs/page-break.qd",
"chars": 1810,
"preview": ".docname {Page break}\n.include {docs}\n\nA page break is a forced interruption of the page flow that causes content follow"
},
{
"path": "docs/page-counter.qd",
"chars": 2249,
"preview": ".docname {Page counter}\n.include {docs}\n\nThe **`.currentpage`** and **`.totalpages`** functions display, respectively, t"
},
{
"path": "docs/page-format.qd",
"chars": 7124,
"preview": ".docname {Page format}\n.include {docs}\n\nThe **`.pageformat`** .docslink {quarkdown-stdlib/com.quarkdown.stdlib.module.Do"
},
{
"path": "docs/page-margin-content.qd",
"chars": 4371,
"preview": ".docname {Page margin content}\n.include {docs}\n\nThe **`.pagemargin`** function displays content on each page in a fixed "
},
{
"path": "docs/paper-library.qd",
"chars": 2938,
"preview": ".docname {Paper library}\n.include {docs}\n.include {paper}\n\nThe built-in .repolink {`paper`} {blob/main/quarkdown-libs/sr"
},
{
"path": "docs/paragraph-style.qd",
"chars": 1189,
"preview": ".docname {Paragraph style}\n.include {docs}\n\nThe **`.paragraphstyle`** .docslink {quarkdown-stdlib/com.quarkdown.stdlib.m"
},
{
"path": "docs/pdf-export.qd",
"chars": 1610,
"preview": ".docname {PDF export}\n.include {docs}\n\nWhen running Quarkdown's [compiler](cli-compiler.qd) via `quarkdown c`, specifyin"
},
{
"path": "docs/persistent-headings.qd",
"chars": 1269,
"preview": ".docname {Persistent headings}\n.include {docs}\n\nThe **`.lastheading {depth}`** .docslink {quarkdown-stdlib/com.quarkdown"
},
{
"path": "docs/pipeline---function-call-expansion.qd",
"chars": 2577,
"preview": ".docname {Pipeline - Function call expansion}\n.include {docs}\n\n> Main packages: .repolink {`core.function`} {tree/main/q"
},
{
"path": "docs/pipeline---lexing.qd",
"chars": 1952,
"preview": ".docname {Pipeline - Lexing}\n.include {docs}\n\n> Main packages: .repolink {`core.lexer`} {tree/main/quarkdown-core/src/ma"
},
{
"path": "docs/pipeline---parsing.qd",
"chars": 1828,
"preview": ".docname {Pipeline - Parsing}\n.include {docs}\n\n> Main packages: .repolink {`core.parser`} {tree/main/quarkdown-core/src/"
},
{
"path": "docs/pipeline---post-rendering.qd",
"chars": 2045,
"preview": ".docname {Pipeline - Post rendering}\n.include {docs}\n\n> Main packages: .repolink {`core.rendering`} {tree/main/quarkdown"
},
{
"path": "docs/pipeline---rendering.qd",
"chars": 1131,
"preview": ".docname {Pipeline - Rendering}\n.include {docs}\n\n> Main packages: .repolink {`core.rendering`} {tree/main/quarkdown-core"
},
{
"path": "docs/pipeline---tree-traversal.qd",
"chars": 939,
"preview": ".docname {Pipeline - Tree traversal}\n.include {docs}\n\n> Main packages: .repolink {`core.ast.iterator`} {tree/main/quarkd"
},
{
"path": "docs/pipeline.qd",
"chars": 1128,
"preview": ".docname {Pipeline}\n.include {docs}\n\nWhen you supply an input file to Quarkdown, it undergoes a process of elaboration t"
},
{
"path": "docs/quickstart.qd",
"chars": 15339,
"preview": ".docname {Quickstart}\n.include {docs}\n\nWelcome to Quarkdown! This guide walks you through the main features you need to "
},
{
"path": "docs/quotation-source.qd",
"chars": 943,
"preview": ".docname {Quotation source}\n.include {docs}\n\nQuarkdown allows a blockquote to have a citation source.\n\nIn general, if th"
},
{
"path": "docs/quote-types.qd",
"chars": 956,
"preview": ".docname {Quote types}\n.include {docs}\n\nIf a blockquote begins with `Tip:`, `Note:`, `Warning:`, or `Important:`, Quarkd"
},
{
"path": "docs/range.qd",
"chars": 1223,
"preview": ".docname {Range}\n.include {docs}\n\nThe syntax for defining a range is **`a..b`**, where `a` and `b` are non-negative inte"
},
{
"path": "docs/sizes.qd",
"chars": 1493,
"preview": ".docname {Sizes}\n.include {docs}\n\nMany functions accept sizes as arguments. This page explains the correct format for de"
},
{
"path": "docs/slides-configuration.qd",
"chars": 1574,
"preview": ".docname {Slides configuration}\n.include {docs}\n\nThe **`.slides`** .docslink {quarkdown-stdlib/com.quarkdown.stdlib.modu"
},
{
"path": "docs/slides-fragment.qd",
"chars": 1133,
"preview": ".docname {Slides fragment}\n.include {docs}\n\nA **fragment** is an interactive section of a slide that can show or hide co"
},
{
"path": "docs/slides-speaker-notes.qd",
"chars": 1128,
"preview": ".docname {Slides speaker notes}\n.include {docs}\n\nSpeaker notes are helpful tools for remembering talking points, reminde"
},
{
"path": "docs/stacks.qd",
"chars": 2599,
"preview": ".docname {Stacks}\n.include {docs}\n\nStack functions are layout functions that arrange a group of elements according to ce"
},
{
"path": "docs/subdocuments.qd",
"chars": 5924,
"preview": ".docname {Subdocuments}\n.include {docs}\n\nWhen referring to a Quarkdown *document*, we are talking broadly about the grou"
},
{
"path": "docs/syntax-of-a-function-call.qd",
"chars": 6454,
"preview": ".docname {Syntax of a function call}\n.include {docs}\n\n**Functions** are the key feature of Quarkdown, distinguishing it "
},
{
"path": "docs/table-caption.qd",
"chars": 1056,
"preview": ".docname {Table caption}\n.include {docs}\n\nThe Quarkdown flavor introduces table captions, which you can set by adding a "
},
{
"path": "docs/table-generation.qd",
"chars": 1358,
"preview": ".docname {Table generation}\n.include {docs}\n\n## Table generation by columns\n\nThe **`.table`** function takes a single bl"
},
{
"path": "docs/table-manipulation.qd",
"chars": 5323,
"preview": ".docname {Table manipulation}\n.include {docs}\n\nThis page describes table manipulation functions .docslink {quarkdown-std"
},
{
"path": "docs/table-of-contents.qd",
"chars": 5007,
"preview": ".docname {Table of contents}\n.include {docs}\n\nA table of contents provides a quick overview of your document by displayi"
},
{
"path": "docs/tex-formulae.qd",
"chars": 1543,
"preview": ".docname {TeX formulae}\n.include {docs}\n\nQuarkdown natively supports TeX math equations and formulae. When rendering to "
},
{
"path": "docs/tex-macros.qd",
"chars": 1294,
"preview": ".docname {TeX macros}\n.include {docs}\n\nWhen writing [TeX formulae](tex-formulae.qd), you may want to use custom macros.\n"
},
{
"path": "docs/text-symbols.qd",
"chars": 2915,
"preview": ".docname {Text symbols}\n.include {docs}\n\nQuarkdown features automatic text replacement for commonly used UTF-8 symbols.\n"
},
{
"path": "docs/text.qd",
"chars": 2382,
"preview": ".docname {Text}\n.include {docs}\n\nThe **`.text`** inline function provides extensive text formatting that cannot be expre"
},
{
"path": "docs/themes.qd",
"chars": 1163,
"preview": ".docname {Themes}\n.include {docs}\n\nA theme defines the look and feel of your Quarkdown document. More themes are planned"
},
{
"path": "docs/typing.qd",
"chars": 1863,
"preview": ".docname {Typing}\n.include {docs}\n\nQuarkdown is **dynamically typed**: every value that may be passed to a function argu"
},
{
"path": "docs/variables.qd",
"chars": 1733,
"preview": ".docname {Variables}\n.include {docs}\n\nVariables allow you to store and reuse values throughout your document. They are e"
},
{
"path": "docs/whitespace.qd",
"chars": 742,
"preview": ".docname {Whitespace}\n.include {docs}\n\nYou can add blank space anywhere via the **`.whitespace`** function .docslink {qu"
},
{
"path": "docs/xy-chart.qd",
"chars": 5015,
"preview": ".docname {XY chart}\n.include {docs}\n\nThe **`.xychart`** .docslink {quarkdown-stdlib/com.quarkdown.stdlib.module.Mermaid/"
},
{
"path": "gradle/wrapper/gradle-wrapper.properties",
"chars": 200,
"preview": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributi"
},
{
"path": "gradle.properties",
"chars": 177,
"preview": "org.gradle.parallel=true\nkotlin.code.style=official\norg.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled\norg.jet"
},
{
"path": "gradlew",
"chars": 8047,
"preview": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "gradlew.bat",
"chars": 2674,
"preview": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \""
},
{
"path": "mock/README.md",
"chars": 595,
"preview": "<p align=\"center\">\n <img src=\"https://raw.githubusercontent.com/iamgio/quarkdown/project-files/images/mock-demo.png\" al"
},
{
"path": "mock/alignment.qd",
"chars": 293,
"preview": "# Alignment\n\n.function {aligncontent}\n\talignment:\n\t.align {.alignment}\n\t\t##! .alignment::capitalize\n\t\n\t\tThe quick brown "
},
{
"path": "mock/bibliography/bibliography.bib",
"chars": 706,
"preview": "@article{einstein,\n author = \"Albert Einstein\",\n title = \"Zur Elektrodynamik bewegter Körper. (German)\n "
},
{
"path": "mock/bibliography.qd",
"chars": 459,
"preview": "# Bibliography\n\nEinstein's publication .cite {einstein} in 1905 revolutionized the field of physics, particularly in the"
},
{
"path": "mock/boxes.qd",
"chars": 747,
"preview": "# Boxes\n\n.var {boxtext}\n\tDon't fight it, use what happens. That's what makes life fun. That you can make these decisions"
},
{
"path": "mock/code/Wrapper.java",
"chars": 191,
"preview": "public final class Wrapper<T> {\n private final T value;\n\n public Wrapper(T value) {\n this.value = value;\n "
},
{
"path": "mock/code.qd",
"chars": 326,
"preview": "# Code\n\n#### Default\n\n.code lang:{java}\n\t.read {code/Wrapper.java}\n\n#### With caption\n\n.code lang:{java} caption:{A wrap"
},
{
"path": "mock/collapsibles.qd",
"chars": 230,
"preview": "# Collapsibles\n\n#### Block\n\n.collapse {A collapsible block. *Click me!*} open:{yes}\n\t.loremipsum\n\n#### Inline\n\nHere is a"
},
{
"path": "mock/colorpreview.qd",
"chars": 108,
"preview": "# Color preview\n\n`#000000`\n\n`#FFFFFF`\n\n`#32A852`\n\n`rgb(255, 0, 255)`\n\n`hsl(350, 55, 40)`\n\n`hsv(190, 50, 90)`"
},
{
"path": "mock/crossreferences.qd",
"chars": 968,
"preview": "# Cross-references {#cross-references}\n\n.ref {cross-references} shows various examples of cross-references.\nFor instance"
},
{
"path": "mock/errors.qd",
"chars": 58,
"preview": "# Errors\n\n.row alignment:{Error demonstration!}\n Hello!"
},
{
"path": "mock/footnotes.qd",
"chars": 1908,
"preview": "# Footnotes\n\nThe search for planets beyond our solar system - exoplanets - has transformed modern astronomy.\nEver since "
},
{
"path": "mock/headings.qd",
"chars": 270,
"preview": "# Headings\n\n.initnumbering\n\n#! First-level heading\n\n.loremipsum\n\n##! Second-level heading\n\n.loremipsum\n\n###! Third-level"
},
{
"path": "mock/icons.qd",
"chars": 203,
"preview": "# Icons\n\n.var {icons}\n - heart\n - heart-fill\n - arrow-down\n - arrow-down-fill\n - airplane-fill\n - warn"
},
{
"path": "mock/images.qd",
"chars": 2061,
"preview": "# Images\n\n\n\nThe quick brown fox jumps over the lazy dog. This is a separator text.\n\n!["
},
{
"path": "mock/lists.qd",
"chars": 1397,
"preview": "# Lists\n\n## Unordered\n\n#### Tight\n\nMy favorite foods:\n\n- Some delicious pasta\n- A huge pizza\n- A lot of sushi\n- A tasty "
},
{
"path": "mock/localization.qd",
"chars": 867,
"preview": "# Ad-hoc locale adaptation\n\nQuarkdown can dynamically adapt to different locales. \nTry changing the document language t"
},
{
"path": "mock/main.qd",
"chars": 606,
"preview": "<!-- Change here to test a different theme -->\n.theme {paperwhite} layout:{latex}\n<!-- Change here to paged/slides/plain"
},
{
"path": "mock/math.qd",
"chars": 447,
"preview": "# Math\n\n#### Inline\nLet $ F(u) $ be the *Fourier Transform* of the function $ f(x) $.\n\n#### Block\n$ F(u) = \\int_{-\\infty"
},
{
"path": "mock/mermaid/class.mmd",
"chars": 674,
"preview": "classDiagram\n class Bank {\n +name: string\n +address: string\n }\n\n class Customer {\n +name: "
},
{
"path": "mock/mermaid/flow.mmd",
"chars": 195,
"preview": "flowchart TD\n A([Start]) --> B[Enter username and password]\n B --> C{Correct?}\n C -- Yes --> D[Redirect to dash"
},
{
"path": "mock/mermaid/git.mmd",
"chars": 229,
"preview": "gitGraph:\n commit \"Ashish\"\n branch newbranch\n checkout newbranch\n commit id:\"1111\"\n commit tag:\"test\"\n "
},
{
"path": "mock/mermaid/pie.mmd",
"chars": 96,
"preview": "pie showData\n \"Sleep\" : 8\n \"Work\" : 9\n \"Exercise\" : 1\n \"Leisure\" : 4\n \"Meals\" : 2"
},
{
"path": "mock/mermaid/sequence.mmd",
"chars": 241,
"preview": "sequenceDiagram\n Alice ->> Bob: Hello Bob, how are you?\n alt sick\n Bob ->> Alice: Not so good :(\n else w"
},
{
"path": "mock/mermaid.qd",
"chars": 1093,
"preview": "# Mermaid diagrams\n\n## XY chart\n\n.let {100}\n n:\n .xychart yrange:{..100}\n .repeat {.n}\n .1::pow "
},
{
"path": "mock/paragraphs.qd",
"chars": 1593,
"preview": "# Paragraphs\n\nAll you need is a dream in your heart, and an almighty knife. Learn when to stop. No pressure. Just relax "
},
{
"path": "mock/quotes.qd",
"chars": 674,
"preview": "# Blockquotes\n\n> The quick brown fox jumps over the lazy dog.\n\n> Let your imagination be your guide. Maybe we got a few "
},
{
"path": "mock/separators.qd",
"chars": 228,
"preview": "# Separators\n\n#### Horizontal\n\nThe quick brown fox jumps over the lazy dog.\n\n---\n\nThe quick brown fox jumps over the laz"
},
{
"path": "mock/setup.qd",
"chars": 1556,
"preview": ".docname {Quarkdown Mock}\n.docauthor {Giorgio Garofalo}\n.doclang {English}\n.pageformat borderbottom:{1px} bordercolor:{g"
},
{
"path": "mock/stacks.qd",
"chars": 1092,
"preview": "# Layout stacks\n\nHere positioning techniques will be used: rows, columns, grids and containers.\n\n.row alignment:{center}"
},
{
"path": "mock/tables.qd",
"chars": 771,
"preview": "# Tables\n\n| Name | Age | City |\n|------------|-----|--------------|\n| Alice | 30 | New York |\n| "
},
{
"path": "mock/textformatting.qd",
"chars": 1700,
"preview": "# Text formatting\n\n## *Emphasis*\n\n**You can't have light without dark.** You can't know *happiness* unless you've known "
},
{
"path": "quarkdown-cli/LICENSE",
"chars": 34598,
"preview": " GNU AFFERO GENERAL PUBLIC LICENSE\n Version 3, 19 November 2007\n\n Copyright (C)"
},
{
"path": "quarkdown-cli/build.gradle.kts",
"chars": 1246,
"preview": "plugins {\n kotlin(\"jvm\")\n application\n}\n\ndependencies {\n testImplementation(\"org.jetbrains.kotlin:kotlin-test\")"
},
{
"path": "quarkdown-cli/src/main/kotlin/com/quarkdown/cli/CliOptions.kt",
"chars": 1425,
"preview": "package com.quarkdown.cli\n\nimport com.quarkdown.cli.renderer.RendererRetriever\nimport java.io.File\n\n/**\n * Options that "
},
{
"path": "quarkdown-cli/src/main/kotlin/com/quarkdown/cli/PipelineInitialization.kt",
"chars": 2663,
"preview": "package com.quarkdown.cli\n\nimport com.quarkdown.core.context.Context\nimport com.quarkdown.core.context.MutableContext\nim"
},
{
"path": "quarkdown-cli/src/main/kotlin/com/quarkdown/cli/QuarkdownCli.kt",
"chars": 1112,
"preview": "package com.quarkdown.cli\n\nimport com.github.ajalt.clikt.core.CliktCommand\nimport com.github.ajalt.clikt.core.main\nimpor"
},
{
"path": "quarkdown-cli/src/main/kotlin/com/quarkdown/cli/creator/ProjectCreator.kt",
"chars": 3055,
"preview": "package com.quarkdown.cli.creator\n\nimport com.quarkdown.cli.creator.content.ProjectCreatorInitialContentSupplier\nimport "
},
{
"path": "quarkdown-cli/src/main/kotlin/com/quarkdown/cli/creator/command/CreateProjectCommand.kt",
"chars": 6678,
"preview": "package com.quarkdown.cli.creator.command\n\nimport com.github.ajalt.clikt.core.CliktCommand\nimport com.github.ajalt.clikt"
},
{
"path": "quarkdown-cli/src/main/kotlin/com/quarkdown/cli/creator/content/DefaultProjectCreatorInitialContentSupplier.kt",
"chars": 1361,
"preview": "package com.quarkdown.cli.creator.content\n\nimport com.quarkdown.core.pipeline.output.ArtifactType\nimport com.quarkdown.c"
},
{
"path": "quarkdown-cli/src/main/kotlin/com/quarkdown/cli/creator/content/DefaultTheme.kt",
"chars": 1169,
"preview": "package com.quarkdown.cli.creator.content\n\nimport com.quarkdown.core.document.DocumentType\n\n/**\n * Utilities to determin"
},
{
"path": "quarkdown-cli/src/main/kotlin/com/quarkdown/cli/creator/content/DocsProjectCreatorInitialContentSupplier.kt",
"chars": 1087,
"preview": "package com.quarkdown.cli.creator.content\n\nimport com.quarkdown.core.pipeline.output.ArtifactType\nimport com.quarkdown.c"
},
{
"path": "quarkdown-cli/src/main/kotlin/com/quarkdown/cli/creator/content/EmptyProjectCreatorInitialContentSupplier.kt",
"chars": 414,
"preview": "package com.quarkdown.cli.creator.content\n\nimport com.quarkdown.core.pipeline.output.OutputResource\n\n/**\n * A [ProjectCr"
},
{
"path": "quarkdown-cli/src/main/kotlin/com/quarkdown/cli/creator/content/ProjectCreatorInitialContentSupplier.kt",
"chars": 1008,
"preview": "package com.quarkdown.cli.creator.content\n\nimport com.quarkdown.cli.creator.template.ProjectCreatorTemplateProcessorFact"
},
{
"path": "quarkdown-cli/src/main/kotlin/com/quarkdown/cli/creator/template/DefaultProjectCreatorTemplateProcessorFactory.kt",
"chars": 1819,
"preview": "package com.quarkdown.cli.creator.template\n\nimport com.quarkdown.core.document.DocumentInfo\nimport com.quarkdown.core.do"
},
{
"path": "quarkdown-cli/src/main/kotlin/com/quarkdown/cli/creator/template/DocsProjectCreatorTemplateProcessorFactory.kt",
"chars": 1003,
"preview": "package com.quarkdown.cli.creator.template\n\nimport com.quarkdown.core.document.DocumentInfo\nimport com.quarkdown.core.te"
},
{
"path": "quarkdown-cli/src/main/kotlin/com/quarkdown/cli/creator/template/ProjectCreatorTemplatePlaceholders.kt",
"chars": 631,
"preview": "package com.quarkdown.cli.creator.template\n\n/**\n * Placeholders used in project creator templates.\n */\nobject ProjectCre"
},
{
"path": "quarkdown-cli/src/main/kotlin/com/quarkdown/cli/creator/template/ProjectCreatorTemplateProcessorFactory.kt",
"chars": 711,
"preview": "package com.quarkdown.cli.creator.template\n\nimport com.quarkdown.core.template.TemplateProcessor\n\n/**\n * Factory that cr"
},
{
"path": "quarkdown-cli/src/main/kotlin/com/quarkdown/cli/exec/CompileCommand.kt",
"chars": 4901,
"preview": "package com.quarkdown.cli.exec\n\nimport com.github.ajalt.clikt.parameters.arguments.argument\nimport com.github.ajalt.clik"
},
{
"path": "quarkdown-cli/src/main/kotlin/com/quarkdown/cli/exec/Execute.kt",
"chars": 3941,
"preview": "package com.quarkdown.cli.exec\n\nimport com.quarkdown.cli.CliOptions\nimport com.quarkdown.cli.PipelineInitialization\nimpo"
},
{
"path": "quarkdown-cli/src/main/kotlin/com/quarkdown/cli/exec/ExecuteCommand.kt",
"chars": 10437,
"preview": "package com.quarkdown.cli.exec\n\nimport com.github.ajalt.clikt.core.CliktCommand\nimport com.github.ajalt.clikt.parameters"
},
{
"path": "quarkdown-cli/src/main/kotlin/com/quarkdown/cli/exec/ExecutionOutcome.kt",
"chars": 909,
"preview": "package com.quarkdown.cli.exec\n\nimport com.quarkdown.core.context.Context\nimport com.quarkdown.core.pipeline.Pipeline\nim"
},
{
"path": "quarkdown-cli/src/main/kotlin/com/quarkdown/cli/exec/ReplCommand.kt",
"chars": 362,
"preview": "package com.quarkdown.cli.exec\n\nimport com.quarkdown.cli.CliOptions\nimport com.quarkdown.cli.exec.strategy.ReplExecution"
}
]
// ... and 1323 more files (download for full content)
About this extraction
This page contains the full source code of the iamgio/quarkdown GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1523 files (3.3 MB), approximately 965.6k tokens, and a symbol index with 426 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.