{"id":17792165,"url":"https://github.com/hlaueriksson/markupolation","last_synced_at":"2025-03-16T16:32:39.992Z","repository":{"id":142785597,"uuid":"412162953","full_name":"hlaueriksson/Markupolation","owner":"hlaueriksson","description":"\u003c📜\u003e Markupolation = Markup + String Interpolation - A library for generating HTML in C#","archived":false,"fork":false,"pushed_at":"2024-03-24T19:48:10.000Z","size":3109,"stargazers_count":12,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-03-27T05:10:04.231Z","etag":null,"topics":["csharp","dotnet","html","markup","string-interpolation"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hlaueriksson.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2021-09-30T17:38:13.000Z","updated_at":"2024-04-14T21:30:31.347Z","dependencies_parsed_at":"2023-11-20T22:24:50.127Z","dependency_job_id":"dfee8cc0-8fe2-4340-925c-c3076d272f35","html_url":"https://github.com/hlaueriksson/Markupolation","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hlaueriksson%2FMarkupolation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hlaueriksson%2FMarkupolation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hlaueriksson%2FMarkupolation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hlaueriksson%2FMarkupolation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hlaueriksson","download_url":"https://codeload.github.com/hlaueriksson/Markupolation/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221666276,"owners_count":16860394,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","dotnet","html","markup","string-interpolation"],"created_at":"2024-10-27T10:58:13.215Z","updated_at":"2024-10-27T10:58:13.724Z","avatar_url":"https://github.com/hlaueriksson.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Markupolation \u003c📜\u003e\u003c!-- omit in toc --\u003e\n\n[![build](https://github.com/hlaueriksson/Markupolation/actions/workflows/build.yml/badge.svg)](https://github.com/hlaueriksson/Markupolation/actions/workflows/build.yml)\n[![CodeFactor](https://codefactor.io/repository/github/hlaueriksson/markupolation/badge)](https://codefactor.io/repository/github/hlaueriksson/markupolation)\n\n[![Markupolation](https://img.shields.io/nuget/v/Markupolation.svg?label=Markupolation)](https://www.nuget.org/packages/Markupolation)\n[![Markupolation.Extensions](https://img.shields.io/nuget/v/Markupolation.Extensions.svg?label=Markupolation.Extensions)](https://www.nuget.org/packages/Markupolation.Extensions)\n\n\u003e \u003c📜\u003e Markupolation = Markup + String Interpolation\n\nA library for generating `HTML` in `C#`\n\n- It uses chainable methods to represent HTML elements and attributes\n- The methods are generated from the HTML specification\n  - \u003chttps://html.spec.whatwg.org\u003e\n- Perfect for your APIs that sends HTML Over The Wire\n\n## Content\u003c!-- omit in toc --\u003e\n\n- [Installation](#installation)\n- [Introduction](#introduction)\n- [When should I use Markupolation?](#when-should-i-use-markupolation)\n- [Markupolation](#markupolation)\n- [Markupolation.Extensions](#markupolationextensions)\n- [String Interpolation](#string-interpolation)\n- [Using Directives](#using-directives)\n- [Performance](#performance)\n- [Samples](#samples)\n\n## Installation\n\nInstall via [NuGet](https://www.nuget.org/packages/Markupolation):\n\n```\nPM\u003e Install-Package Markupolation\n```\n\nEnable `ImplicitUsings` in the `.csproj` file:\n\n```xml\n\u003cPropertyGroup\u003e\n  \u003cImplicitUsings\u003eenable\u003c/ImplicitUsings\u003e\n\u003c/PropertyGroup\u003e\n```\n\nAlso via [NuGet](https://www.nuget.org/packages/Markupolation.Extensions):\n\n```\nPM\u003e Install-Package Markupolation.Extensions\n```\n\n## Introduction\n\nThis project consist of two packages:\n\n- 📦 [Markupolation](https://www.nuget.org/packages/Markupolation)\n- 📦 [Markupolation.Extensions](https://www.nuget.org/packages/Markupolation.Extensions)\n\n`Markupolation` is a library for generating `HTML` in `C#` with a fluent API.\nIt can be used to create *templates* that render markup from your *data*.\n\nAn expression like this:\n\n```cs\nDOCTYPE() + html(head(e.title(\"Markupolation\")), body(h1(\"Hello, World!\")))\n```\n\ngenerates the following result:\n\n```html\n\u003c!DOCTYPE html\u003e\u003chtml\u003e\u003chead\u003e\u003ctitle\u003eMarkupolation\u003c/title\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1\u003eHello, World!\u003c/h1\u003e\u003c/body\u003e\u003c/html\u003e\n```\n\n`Markupolation.Extensions` adds extension methods to control flow with loops and conditionals.\n\nExpressions like these:\n\n```cs\nvar links = new[] { new { Url = \"#\", Title = \"Foo\", Active = true }, new { Url = \"#\", Title = \"Bar\", Active = false } };\nlinks.Each((x, index) =\u003e a(href(x.Url), id($\"link{index}\"), x.IfMatch(x =\u003e x.Active, x =\u003e class_(\"active\")), x.Title));\n```\n\ngenerates the following result:\n\n```html\n\u003ca href=\"#\" id=\"link0\" class=\"active\"\u003eFoo\u003c/a\u003e\u003ca href=\"#\" id=\"link1\"\u003eBar\u003c/a\u003e\n```\n\n## When should I use Markupolation?\n\nIn some situations, you don't have access or don't want to use a template/view engine like [Razor](https://learn.microsoft.com/en-us/aspnet/core/mvc/views/razor).\n\nMaybe you are building\n\n- a _Minimal API_, or\n- _Azure Functions_\n\nto deliver\n\n- **`HTML` Over The Wire**\n- instead of ~~`JSON`~~\n\nto\n\n- a _Blazor WebAssembly_ app, or\n- an _Azure Static Web App_ site with `Hotwire` or `HTMX`?\n\nIn cases like these, `Markupolation` could be a good fit to generate HTML for you.\n\n### Hotwire (`HTML` Over The Wire)?\u003c!-- omit in toc --\u003e\n\n\u003e Hotwire is an alternative approach to building modern web applications without using much JavaScript by sending HTML instead of JSON over the wire. This makes for fast first-load pages, keeps template rendering on the server, and allows for a simpler, more productive development experience in any programming language, without sacrificing any of the speed or responsiveness associated with a traditional single-page application.\n\u003e\n\u003e -- \u003ccite\u003e[hotwired.dev](https://hotwired.dev/)\u003c/cite\u003e\n\n### HTMX?\u003c!-- omit in toc --\u003e\n\n\u003e htmx is a library that allows you to access modern browser features directly from HTML, rather than using javascript.\n\u003e\n\u003e Note that when you are using htmx, on the server side you typically respond with HTML, not JSON.\n\u003e\n\u003e htmx expects responses to the AJAX requests it makes to be HTML, typically HTML fragments.\n\u003e \n\u003e htmx will then swap the returned HTML into the document at the target specified and with the swap strategy specified.\n\u003e\n\u003e -- \u003ccite\u003e[htmx.org](https://htmx.org/)\u003c/cite\u003e\n\n## Markupolation\n\nThis is a library for generating `HTML` in `C#`.\nIt uses chainable methods to represent HTML elements and attributes.\n\nThe methods are generated from the HTML Specification:\n\n- \u003chttps://html.spec.whatwg.org\u003e\n\nInput:\n\n```cs\nDOCTYPE() +\nhtml(lang(\"en\"),\n    head(\n        meta(charset(\"utf-8\")),\n        e.title(\"Markupolation\"),\n        meta(name(\"description\"), content(\"Sample of how to use Markupolation\")),\n        meta(name(\"viewport\"), content(\"width=device-width, initial-scale=1\"))\n    ),\n    body(\n        h1(\"Hello, World!\"),\n        p(\"This is \", mark(a.title(\"Markup with string interpolation\"), \"Markupolation\"), \" in action.\")\n    )\n);\n```\n\nOutput (formatted):\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n\n\u003chead\u003e\n  \u003cmeta charset=\"utf-8\" /\u003e\n  \u003ctitle\u003eMarkupolation\u003c/title\u003e\n  \u003cmeta name=\"description\" content=\"Sample of how to use Markupolation\" /\u003e\n  \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1\" /\u003e\n\u003c/head\u003e\n\n\u003cbody\u003e\n  \u003ch1\u003eHello, World!\u003c/h1\u003e\n  \u003cp\u003eThis is \u003cmark title=\"Markup with string interpolation\"\u003eMarkupolation\u003c/mark\u003e in action.\u003c/p\u003e\n\u003c/body\u003e\n\n\u003c/html\u003e\n```\n\nThe `Markupolation` API consists of static methods for `HTML` elements and attributes.\nThese methods are chainable and together they can be used to generate whole or parts of `HTML` documents.\nThe `C#` compiler makes sure that the generated `HTML` is well-formed.\n\n### The API\u003c!-- omit in toc --\u003e\n\n\u003e Click to expand the sections 👇\n\n\u003cdetails\u003e\n\n\u003csummary\u003eView all Elements\u003c/summary\u003e\n\n#### Elements\u003c!-- omit in toc --\u003e\n\nCode:\n\n- [`Elements.cs`](https://github.com/hlaueriksson/Markupolation/blob/main/src/Markupolation/Generated/Elements.cs)\n\n| Element | Description | Attributes |\n| --- | --- | --- |\n| `a` | Hyperlink | `href`, `target`, `download`, `rel`, `hreflang`, `type`, `referrerpolicy` |\n| `abbr` | Abbreviation |  |\n| `address` | Contact information for a page or article element |  |\n| `area` | Hyperlink or dead area on an image map | `alt`, `coords`, `shape`, `href`, `target`, `download`, `rel`, `referrerpolicy` |\n| `article` | Self-contained syndicatable or reusable composition |  |\n| `aside` | Sidebar for tangentially related content |  |\n| `audio` | Audio player | `src`, `crossorigin`, `preload`, `autoplay`, `loop`, `muted`, `controls` |\n| `b` | Keywords |  |\n| `base_` | Base URL and default target navigable for hyperlinks and forms | `href`, `target` |\n| `bdi` | Text directionality isolation |  |\n| `bdo` | Text directionality formatting |  |\n| `blockquote` | A section quoted from another source | `cite` |\n| `body` | Document body |  |\n| `br` | Line break, e.g. in poem or postal address |  |\n| `button` | Button control | `disabled`, `form`, `formaction`, `formenctype`, `formmethod`, `formnovalidate`, `formtarget`, `name`, `popovertarget`, `popovertargetaction`, `type`, `value` |\n| `canvas` | Scriptable bitmap canvas | `width`, `height` |\n| `caption` | Table caption |  |\n| `cite` | Title of a work |  |\n| `code` | Computer code |  |\n| `col` | Table column | `span` |\n| `colgroup` | Group of columns in a table | `span` |\n| `data` | Machine-readable equivalent | `value` |\n| `datalist` | Container for options for combo box control |  |\n| `dd` | Content for corresponding dt element(s) |  |\n| `del` | A removal from the document | `cite`, `datetime` |\n| `details` | Disclosure control for hiding details | `name`, `open` |\n| `dfn` | Defining instance |  |\n| `dialog` | Dialog box or window | `open` |\n| `div` | Generic flow container, or container for name-value groups in dl elements |  |\n| `dl` | Association list consisting of zero or more name-value groups |  |\n| `dt` | Legend for corresponding dd element(s) |  |\n| `em` | Stress emphasis |  |\n| `embed` | Plugin | `src`, `type`, `width`, `height` |\n| `fieldset` | Group of form controls | `disabled`, `form`, `name` |\n| `figcaption` | Caption for figure |  |\n| `figure` | Figure with optional caption |  |\n| `footer` | Footer for a page or section |  |\n| `form` | User-submittable form | `accept_charset`, `action`, `autocomplete`, `enctype`, `method`, `name`, `novalidate`, `rel`, `target` |\n| `h1` | Heading |  |\n| `h2` | Heading |  |\n| `h3` | Heading |  |\n| `h4` | Heading |  |\n| `h5` | Heading |  |\n| `h6` | Heading |  |\n| `head` | Container for document metadata |  |\n| `header` | Introductory or navigational aids for a page or section |  |\n| `hgroup` | Heading container |  |\n| `hr` | Thematic break |  |\n| `html` | Root element |  |\n| `i` | Alternate voice |  |\n| `iframe` | Child navigable | `src`, `srcdoc`, `name`, `sandbox`, `allow`, `allowfullscreen`, `width`, `height`, `referrerpolicy`, `loading` |\n| `img` | Image | `alt`, `src`, `srcset`, `sizes`, `crossorigin`, `usemap`, `ismap`, `width`, `height`, `referrerpolicy`, `decoding`, `loading`, `fetchpriority` |\n| `input` | Form control | `accept`, `alt`, `autocomplete`, `checked_`, `dirname`, `disabled`, `form`, `formaction`, `formenctype`, `formmethod`, `formnovalidate`, `formtarget`, `height`, `list`, `max`, `maxlength`, `min`, `minlength`, `multiple`, `name`, `pattern`, `placeholder`, `popovertarget`, `popovertargetaction`, `readonly_`, `required`, `size`, `src`, `step`, `type`, `value`, `width` |\n| `ins` | An addition to the document | `cite`, `datetime` |\n| `kbd` | User input |  |\n| `label` | Caption for a form control | `for_` |\n| `legend` | Caption for fieldset |  |\n| `li` | List item | `value` |\n| `link` | Link metadata | `href`, `crossorigin`, `rel`, `as_`, `media`, `hreflang`, `type`, `sizes`, `imagesrcset`, `imagesizes`, `referrerpolicy`, `integrity`, `blocking`, `color`, `disabled`, `fetchpriority` |\n| `main` | Container for the dominant contents of the document |  |\n| `map` | Image map | `name` |\n| `mark` | Highlight |  |\n| `menu` | Menu of commands |  |\n| `meta` | Text metadata | `name`, `http_equiv`, `content`, `charset`, `media` |\n| `meter` | Gauge | `value`, `min`, `max`, `low`, `high`, `optimum` |\n| `nav` | Section with navigational links |  |\n| `noscript` | Fallback content for script |  |\n| `object_` | Image, child navigable, or plugin | `data`, `type`, `name`, `form`, `width`, `height` |\n| `ol` | Ordered list | `reversed`, `start`, `type` |\n| `optgroup` | Group of options in a list box | `disabled`, `label` |\n| `option` | Option in a list box or combo box control | `disabled`, `label`, `selected`, `value` |\n| `output` | Calculated output value | `for_`, `form`, `name` |\n| `p` | Paragraph |  |\n| `picture` | Image |  |\n| `pre` | Block of preformatted text |  |\n| `progress` | Progress bar | `value`, `max` |\n| `q` | Quotation | `cite` |\n| `rp` | Parenthesis for ruby annotation text |  |\n| `rt` | Ruby annotation text |  |\n| `ruby` | Ruby annotation(s) |  |\n| `s` | Inaccurate text |  |\n| `samp` | Computer output |  |\n| `script` | Embedded script | `src`, `type`, `nomodule`, `async`, `defer`, `crossorigin`, `integrity`, `referrerpolicy`, `blocking`, `fetchpriority` |\n| `search` | Container for search controls |  |\n| `section` | Generic document or application section |  |\n| `select` | List box control | `autocomplete`, `disabled`, `form`, `multiple`, `name`, `required`, `size` |\n| `slot` | Shadow tree slot | `name` |\n| `small` | Side comment |  |\n| `source` | Image source for img or media source for video or audio | `type`, `media`, `src`, `srcset`, `sizes`, `width`, `height` |\n| `span` | Generic phrasing container |  |\n| `strong` | Importance |  |\n| `style` | Embedded styling information | `media`, `blocking` |\n| `sub` | Subscript |  |\n| `summary` | Caption for details |  |\n| `sup` | Superscript |  |\n| `table` | Table |  |\n| `tbody` | Group of rows in a table |  |\n| `td` | Table cell | `colspan`, `rowspan`, `headers` |\n| `template` | Template | `shadowrootmode`, `shadowrootdelegatesfocus`, `shadowrootclonable`, `shadowrootserializable` |\n| `textarea` | Multiline text controls | `autocomplete`, `cols`, `dirname`, `disabled`, `form`, `maxlength`, `minlength`, `name`, `placeholder`, `readonly_`, `required`, `rows`, `wrap` |\n| `tfoot` | Group of footer rows in a table |  |\n| `th` | Table header cell | `colspan`, `rowspan`, `headers`, `scope`, `abbr` |\n| `thead` | Group of heading rows in a table |  |\n| `time` | Machine-readable equivalent of date- or time-related data | `datetime` |\n| `title` | Document title |  |\n| `tr` | Table row |  |\n| `track` | Timed text track | `default_`, `kind`, `label`, `src`, `srclang` |\n| `u` | Unarticulated annotation |  |\n| `ul` | List |  |\n| `var` | Variable |  |\n| `video` | Video player | `src`, `crossorigin`, `poster`, `preload`, `autoplay`, `playsinline`, `loop`, `muted`, `controls`, `width`, `height` |\n| `wbr` | Line breaking opportunity |  |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\n\u003csummary\u003eView all Attributes\u003c/summary\u003e\n\n#### Attributes\u003c!-- omit in toc --\u003e\n\nCode:\n\n- [`Attributes.cs`](https://github.com/hlaueriksson/Markupolation/blob/main/src/Markupolation/Generated/Attributes.cs)\n\n| Attribute | Description | Elements |\n| --- | --- | --- |\n| `abbr` | Alternative label to use for the header cell when referencing the cell in other contexts | `th` |\n| `accept` | Hint for expected file type in file upload controls | `input` |\n| `accept_charset` | Character encodings to use for form submission | `form` |\n| `accesskey` | Keyboard shortcut to activate or focus element |  |\n| `action` | URL to use for form submission | `form` |\n| `allow` | Permissions policy to be applied to the iframe's contents | `iframe` |\n| `allowfullscreen` | Whether to allow the iframe's contents to use requestFullscreen() | `iframe` |\n| `alt` | Replacement text for use when images are not available | `area`, `img`, `input` |\n| `as_` | Potential destination for a preload request (for rel=\"preload\" and rel=\"modulepreload\") | `link` |\n| `async` | Execute script when available, without blocking while fetching | `script` |\n| `autocapitalize` | Recommended autocapitalization behavior (for supported input methods) |  |\n| `autocomplete` | Default setting for autofill feature for controls in the form\u003cbr/\u003eHint for form autofill feature | `form`, `input`, `select`, `textarea` |\n| `autofocus` | Automatically focus the element when the page is loaded |  |\n| `autoplay` | Hint that the media resource can be started automatically when the page is loaded | `audio`, `video` |\n| `blocking` | Whether the element is potentially render-blocking | `link`, `script`, `style` |\n| `charset` | Character encoding declaration | `meta` |\n| `checked_` | Whether the control is checked | `input` |\n| `cite` | Link to the source of the quotation or more information about the edit | `blockquote`, `del`, `ins`, `q` |\n| `class_` | Classes to which the element belongs |  |\n| `color` | Color to use when customizing a site's icon (for rel=\"mask-icon\") | `link` |\n| `cols` | Maximum number of characters per line | `textarea` |\n| `colspan` | Number of columns that the cell is to span | `td`, `th` |\n| `content` | Value of the element | `meta` |\n| `contenteditable` | Whether the element is editable |  |\n| `controls` | Show user agent controls | `audio`, `video` |\n| `coords` | Coordinates for the shape to be created in an image map | `area` |\n| `crossorigin` | How the element handles crossorigin requests | `audio`, `img`, `link`, `script`, `video` |\n| `data` | Address of the resource | `object_` |\n| `datetime` | Date and (optionally) time of the change\u003cbr/\u003eMachine-readable value | `del`, `ins`, `time` |\n| `decoding` | Decoding hint to use when processing this image for presentation | `img` |\n| `default_` | Enable the track if no other text track is more suitable | `track` |\n| `defer` | Defer script execution | `script` |\n| `dir` | The text directionality of the element\u003cbr/\u003eThe text directionality of the element |  |\n| `dirname` | Name of form control to use for sending the element's directionality in form submission | `input`, `textarea` |\n| `disabled` | Whether the form control is disabled\u003cbr/\u003eWhether the descendant form controls, except any inside legend, are disabled\u003cbr/\u003eWhether the link is disabled | `button`, `input`, `optgroup`, `option`, `select`, `textarea`, `fieldset`, `link` |\n| `download` | Whether to download the resource instead of navigating to it, and its filename if so | `a`, `area` |\n| `draggable` | Whether the element is draggable |  |\n| `enctype` | Entry list encoding type to use for form submission | `form` |\n| `enterkeyhint` | Hint for selecting an enter key action |  |\n| `fetchpriority` | Sets the priority for fetches initiated by the element | `img`, `link`, `script` |\n| `for_` | Associate the label with form control\u003cbr/\u003eSpecifies controls from which the output was calculated | `label`, `output` |\n| `form` | Associates the element with a form element | `button`, `fieldset`, `input`, `object_`, `output`, `select`, `textarea` |\n| `formaction` | URL to use for form submission | `button`, `input` |\n| `formenctype` | Entry list encoding type to use for form submission | `button`, `input` |\n| `formmethod` | Variant to use for form submission | `button`, `input` |\n| `formnovalidate` | Bypass form control validation for form submission | `button`, `input` |\n| `formtarget` | Navigable for form submission | `button`, `input` |\n| `headers` | The header cells for this cell | `td`, `th` |\n| `height` | Vertical dimension | `canvas`, `embed`, `iframe`, `img`, `input`, `object_`, `source`, `video` |\n| `hidden` | Whether the element is relevant |  |\n| `high` | Low limit of high range | `meter` |\n| `href` | Address of the hyperlink\u003cbr/\u003eAddress of the hyperlink\u003cbr/\u003eDocument base URL | `a`, `area`, `link`, `base_` |\n| `hreflang` | Language of the linked resource | `a`, `link` |\n| `http_equiv` | Pragma directive | `meta` |\n| `id` | The element's ID |  |\n| `imagesizes` | Image sizes for different page layouts (for rel=\"preload\") | `link` |\n| `imagesrcset` | Images to use in different situations, e.g., high-resolution displays, small monitors, etc. (for rel=\"preload\") | `link` |\n| `inert` | Whether the element is inert |  |\n| `inputmode` | Hint for selecting an input modality |  |\n| `integrity` | Integrity metadata used in Subresource Integrity checks [SRI] | `link`, `script` |\n| `is_` | Creates a customized built-in element |  |\n| `ismap` | Whether the image is a server-side image map | `img` |\n| `itemid` | Global identifier for a microdata item |  |\n| `itemprop` | Property names of a microdata item |  |\n| `itemref` | Referenced elements |  |\n| `itemscope` | Introduces a microdata item |  |\n| `itemtype` | Item types of a microdata item |  |\n| `kind` | The type of text track | `track` |\n| `label` | User-visible label | `optgroup`, `option`, `track` |\n| `lang` | Language of the element |  |\n| `list` | List of autocomplete options | `input` |\n| `loading` | Used when determining loading deferral | `iframe`, `img` |\n| `loop` | Whether to loop the media resource | `audio`, `video` |\n| `low` | High limit of low range | `meter` |\n| `max` | Maximum value\u003cbr/\u003eUpper bound of range | `input`, `meter`, `progress` |\n| `maxlength` | Maximum length of value | `input`, `textarea` |\n| `media` | Applicable media | `link`, `meta`, `source`, `style` |\n| `method` | Variant to use for form submission | `form` |\n| `min` | Minimum value\u003cbr/\u003eLower bound of range | `input`, `meter` |\n| `minlength` | Minimum length of value | `input`, `textarea` |\n| `multiple` | Whether to allow multiple values | `input`, `select` |\n| `muted` | Whether to mute the media resource by default | `audio`, `video` |\n| `name` | Name of the element to use for form submission and in the form.elements API\u003cbr/\u003eName of group of mutually-exclusive details elements\u003cbr/\u003eName of form to use in the document.forms API\u003cbr/\u003eName of content navigable\u003cbr/\u003eName of image map to reference from the usemap attribute\u003cbr/\u003eMetadata name\u003cbr/\u003eName of shadow tree slot | `button`, `fieldset`, `input`, `output`, `select`, `textarea`, `details`, `form`, `iframe`, `object_`, `map`, `meta`, `slot` |\n| `nomodule` | Prevents execution in user agents that support module scripts | `script` |\n| `nonce` | Cryptographic nonce used in Content Security Policy checks [CSP] |  |\n| `novalidate` | Bypass form control validation for form submission | `form` |\n| `open` | Whether the details are visible\u003cbr/\u003eWhether the dialog box is showing | `details`, `dialog` |\n| `optimum` | Optimum value in gauge | `meter` |\n| `pattern` | Pattern to be matched by the form control's value | `input` |\n| `ping` | URLs to ping |  |\n| `placeholder` | User-visible label to be placed within the form control | `input`, `textarea` |\n| `playsinline` | Encourage the user agent to display video content within the element's playback area | `video` |\n| `popover` | Makes the element a popover element |  |\n| `popovertarget` | Targets a popover element to toggle, show, or hide | `button`, `input` |\n| `popovertargetaction` | Indicates whether a targeted popover element is to be toggled, shown, or hidden | `button`, `input` |\n| `poster` | Poster frame to show prior to video playback | `video` |\n| `preload` | Hints how much buffering the media resource will likely need | `audio`, `video` |\n| `readonly_` | Whether to allow the value to be edited by the user\u003cbr/\u003eAffects willValidate, plus any behavior added by the custom element author | `input`, `textarea` |\n| `referrerpolicy` | Referrer policy for fetches initiated by the element | `a`, `area`, `iframe`, `img`, `link`, `script` |\n| `rel` | Relationship between the location in the document containing the hyperlink and the destination resource\u003cbr/\u003eRelationship between the document containing the hyperlink and the destination resource | `a`, `area`, `link` |\n| `required` | Whether the control is required for form submission | `input`, `select`, `textarea` |\n| `reversed` | Number the list backwards | `ol` |\n| `rows` | Number of lines to show | `textarea` |\n| `rowspan` | Number of rows that the cell is to span | `td`, `th` |\n| `sandbox` | Security rules for nested content | `iframe` |\n| `scope` | Specifies which cells the header cell applies to | `th` |\n| `selected` | Whether the option is selected by default | `option` |\n| `shadowrootclonable` | Sets clonable on a declarative shadow root | `template` |\n| `shadowrootdelegatesfocus` | Sets delegates focus on a declarative shadow root | `template` |\n| `shadowrootmode` | Enables streaming declarative shadow roots | `template` |\n| `shadowrootserializable` | Sets serializable on a declarative shadow root | `template` |\n| `shape` | The kind of shape to be created in an image map | `area` |\n| `size` | Size of the control | `input`, `select` |\n| `sizes` | Sizes of the icons (for rel=\"icon\")\u003cbr/\u003eImage sizes for different page layouts | `link`, `img`, `source` |\n| `slot` | The element's desired slot |  |\n| `span` | Number of columns spanned by the element | `col`, `colgroup` |\n| `spellcheck` | Whether the element is to have its spelling and grammar checked |  |\n| `src` | Address of the resource | `audio`, `embed`, `iframe`, `img`, `input`, `script`, `source`, `track`, `video` |\n| `srcdoc` | A document to render in the iframe | `iframe` |\n| `srclang` | Language of the text track | `track` |\n| `srcset` | Images to use in different situations, e.g., high-resolution displays, small monitors, etc | `img`, `source` |\n| `start` | Starting value of the list | `ol` |\n| `step` | Granularity to be matched by the form control's value | `input` |\n| `style` | Presentational and formatting instructions |  |\n| `tabindex` | Whether the element is focusable and sequentially focusable, and the relative order of the element for the purposes of sequential focus navigation |  |\n| `target` | Navigable for hyperlink navigation\u003cbr/\u003eDefault navigable for hyperlink navigation and form submission\u003cbr/\u003eNavigable for form submission | `a`, `area`, `base_`, `form` |\n| `title` | Advisory information for the element\u003cbr/\u003eFull term or expansion of abbreviation\u003cbr/\u003eDescription of pattern (when used with pattern attribute)\u003cbr/\u003eTitle of the link\u003cbr/\u003eCSS style sheet set name | `abbr`, `dfn`, `input`, `link`, `link`, `style` |\n| `translate` | Whether the element is to be translated when the page is localized |  |\n| `type` | Hint for the type of the referenced resource\u003cbr/\u003eType of button\u003cbr/\u003eType of embedded resource\u003cbr/\u003eType of form control\u003cbr/\u003eKind of list marker\u003cbr/\u003eType of script | `a`, `link`, `button`, `embed`, `object_`, `source`, `input`, `ol`, `script` |\n| `usemap` | Name of image map to use | `img` |\n| `value` | Value to be used for form submission\u003cbr/\u003eMachine-readable value\u003cbr/\u003eValue of the form control\u003cbr/\u003eOrdinal value of the list item\u003cbr/\u003eCurrent value of the element | `button`, `option`, `data`, `input`, `li`, `meter`, `progress` |\n| `width` | Horizontal dimension | `canvas`, `embed`, `iframe`, `img`, `input`, `object_`, `source`, `video` |\n| `wrap` | How the value of the form control is to be wrapped for form submission | `textarea` |\n| `writingsuggestions` | Whether the element can offer writing suggestions or not |  |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\n\u003csummary\u003eView all EventHandlerContentAttributes\u003c/summary\u003e\n\n#### EventHandlerContentAttributes\u003c!-- omit in toc --\u003e\n\nCode:\n\n- [`EventHandlerContentAttributes.cs`](https://github.com/hlaueriksson/Markupolation/blob/main/src/Markupolation/Generated/EventHandlerContentAttributes.cs)\n\n| Attribute | Description | Elements |\n| --- | --- | --- |\n| `onafterprint` | afterprint event handler for Window object | `body` |\n| `onauxclick` | auxclick event handler |  |\n| `onbeforeinput` | beforeinput event handler |  |\n| `onbeforematch` | beforematch event handler |  |\n| `onbeforeprint` | beforeprint event handler for Window object | `body` |\n| `onbeforeunload` | beforeunload event handler for Window object | `body` |\n| `onbeforetoggle` | beforetoggle event handler |  |\n| `onblur` | blur event handler |  |\n| `oncancel` | cancel event handler |  |\n| `oncanplay` | canplay event handler |  |\n| `oncanplaythrough` | canplaythrough event handler |  |\n| `onchange` | change event handler |  |\n| `onclick` | click event handler |  |\n| `onclose` | close event handler |  |\n| `oncontextlost` | contextlost event handler |  |\n| `oncontextmenu` | contextmenu event handler |  |\n| `oncontextrestored` | contextrestored event handler |  |\n| `oncopy` | copy event handler |  |\n| `oncuechange` | cuechange event handler |  |\n| `oncut` | cut event handler |  |\n| `ondblclick` | dblclick event handler |  |\n| `ondrag` | drag event handler |  |\n| `ondragend` | dragend event handler |  |\n| `ondragenter` | dragenter event handler |  |\n| `ondragleave` | dragleave event handler |  |\n| `ondragover` | dragover event handler |  |\n| `ondragstart` | dragstart event handler |  |\n| `ondrop` | drop event handler |  |\n| `ondurationchange` | durationchange event handler |  |\n| `onemptied` | emptied event handler |  |\n| `onended` | ended event handler |  |\n| `onerror` | error event handler |  |\n| `onfocus` | focus event handler |  |\n| `onformdata` | formdata event handler |  |\n| `onhashchange` | hashchange event handler for Window object | `body` |\n| `oninput` | input event handler |  |\n| `oninvalid` | invalid event handler |  |\n| `onkeydown` | keydown event handler |  |\n| `onkeypress` | keypress event handler |  |\n| `onkeyup` | keyup event handler |  |\n| `onlanguagechange` | languagechange event handler for Window object | `body` |\n| `onload` | load event handler |  |\n| `onloadeddata` | loadeddata event handler |  |\n| `onloadedmetadata` | loadedmetadata event handler |  |\n| `onloadstart` | loadstart event handler |  |\n| `onmessage` | message event handler for Window object | `body` |\n| `onmessageerror` | messageerror event handler for Window object | `body` |\n| `onmousedown` | mousedown event handler |  |\n| `onmouseenter` | mouseenter event handler |  |\n| `onmouseleave` | mouseleave event handler |  |\n| `onmousemove` | mousemove event handler |  |\n| `onmouseout` | mouseout event handler |  |\n| `onmouseover` | mouseover event handler |  |\n| `onmouseup` | mouseup event handler |  |\n| `onoffline` | offline event handler for Window object | `body` |\n| `ononline` | online event handler for Window object | `body` |\n| `onpagehide` | pagehide event handler for Window object | `body` |\n| `onpagereveal` | pagereveal event handler for Window object | `body` |\n| `onpageshow` | pageshow event handler for Window object | `body` |\n| `onpageswap` | pageswap event handler for Window object | `body` |\n| `onpaste` | paste event handler |  |\n| `onpause` | pause event handler |  |\n| `onplay` | play event handler |  |\n| `onplaying` | playing event handler |  |\n| `onpopstate` | popstate event handler for Window object | `body` |\n| `onprogress` | progress event handler |  |\n| `onratechange` | ratechange event handler |  |\n| `onreset` | reset event handler |  |\n| `onresize` | resize event handler |  |\n| `onrejectionhandled` | rejectionhandled event handler for Window object | `body` |\n| `onscroll` | scroll event handler |  |\n| `onscrollend` | scrollend event handler |  |\n| `onsecuritypolicyviolation` | securitypolicyviolation event handler |  |\n| `onseeked` | seeked event handler |  |\n| `onseeking` | seeking event handler |  |\n| `onselect` | select event handler |  |\n| `onslotchange` | slotchange event handler |  |\n| `onstalled` | stalled event handler |  |\n| `onstorage` | storage event handler for Window object | `body` |\n| `onsubmit` | submit event handler |  |\n| `onsuspend` | suspend event handler |  |\n| `ontimeupdate` | timeupdate event handler |  |\n| `ontoggle` | toggle event handler |  |\n| `onunhandledrejection` | unhandledrejection event handler for Window object | `body` |\n| `onunload` | unload event handler for Window object | `body` |\n| `onvolumechange` | volumechange event handler |  |\n| `onwaiting` | waiting event handler |  |\n| `onwheel` | wheel event handler |  |\n\n\u003c/details\u003e\n\n### Naming Convention\u003c!-- omit in toc --\u003e\n\n- ℹ️ The names of element and attribute methods are in *lowercase* to reflect the `HTML` Specification:\n  - \u003chttps://html.spec.whatwg.org\u003e\n- ℹ️ Names that conflict with the [`C#` keywords](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/) are suffixed with an underscore (`_`)\n- ℹ️ Attributes that contain hyphen (`-`) are converted to [snake_case](https://en.wikipedia.org/wiki/Snake_case)\n- ⚠️ Some methods are *ambiguous* and are defined for both elements and attributes\n\nElements suffixed with `_`:\n\n- `base_`\n- `object_`\n\nAttributes suffixed with `_`:\n\n- `as_`\n- `checked_`\n- `class_`\n- `default_`\n- `for_`\n- `is_`\n- `readonly_`\n\nAttributes converted to `snake_case`:\n\n- `accept_charset`\n- `http_equiv`\n\nAmbiguous methods for both elements and attributes:\n\n- `abbr`\n- `cite`\n- `data`\n- `form`\n- `label`\n- `slot`\n- `span`\n- `style`\n- `title`\n\nUse the predefined `e` and `a` aliases as shorthands for these ambiguous methods:\n\n- `e.title(\"Title element\")`\n- `a.title(\"Title attribute\")`\n\n### Custom Elements and Attributes\u003c!-- omit in toc --\u003e\n\nCustom elements and attributes that are not available in the API (not part of the HTML Specification) can be instantiated from the `Element` and `Attribute` classes.\nUse the predefined `E` and `A` aliases as shorthands for these classes.\n\nScalable Vector Graphics element:\n\n```cs\nnew Element(\"\"\"\n  \u003csvg width=\"100\" height=\"100\"\u003e\n    \u003ccircle cx=\"50\" cy=\"50\" r=\"40\" fill=\"blue\" /\u003e\n  \u003c/svg\u003e\n\"\"\")\n```\n\nThe `E` alias:\n\n```cs\nnew E(\"\"\"\n  \u003csvg width=\"100\" height=\"100\"\u003e\n    \u003ccircle cx=\"50\" cy=\"50\" r=\"40\" fill=\"blue\" /\u003e\n  \u003c/svg\u003e\n\"\"\")\n```\n\nOpen Graph attribute:\n\n```cs\nnew Attribute(\"property\", \"og:title\")\n```\n\nThe `A` alias:\n\n```cs\nnew A(\"property\", \"og:title\")\n```\n\n## Markupolation.Extensions\n\nThis is a library for controlling the flow when writing templates.\nUse lambda expressions for loops and conditionals.\n\nInput:\n\n```cs\nbool Fizz(int i) =\u003e i % 3 == 0;\nbool Buzz(int i) =\u003e i % 5 == 0;\nvar numbers = Enumerable.Range(1, 15);\n\nDOCTYPE() +\nhtml(lang(\"en\"),\n    head(\n        meta(charset(\"utf-8\")),\n        e.title(\"Markupolation.Extensions\"),\n        meta(name(\"description\"), content(\"Sample of how to use Markupolation.Extensions\")),\n        meta(name(\"viewport\"), content(\"width=device-width, initial-scale=1\"))\n    ),\n    body(\n        ul(\n            numbers.Each(x =\u003e li(\n                x.IfMatch(i =\u003e Fizz(i) \u0026\u0026 Buzz(i), i =\u003e strong(\"FizzBuzz\")),\n                x.IfMatch(i =\u003e Fizz(i) \u0026\u0026 !Buzz(i), i =\u003e em(\"Fizz\")),\n                x.IfMatch(i =\u003e !Fizz(i) \u0026\u0026 Buzz(i), i =\u003e em(\"Buzz\")),\n                x.IfMatch(i =\u003e !Fizz(i) \u0026\u0026 !Buzz(i), i =\u003e i.ToString())\n            ))\n        )\n    )\n);\n```\n\nOutput (formatted):\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n\n\u003chead\u003e\n  \u003cmeta charset=\"utf-8\" /\u003e\n  \u003ctitle\u003eMarkupolation.Extensions\u003c/title\u003e\n  \u003cmeta name=\"description\" content=\"Sample of how to use Markupolation.Extensions\" /\u003e\n  \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1\" /\u003e\n\u003c/head\u003e\n\n\u003cbody\u003e\n  \u003cul\u003e\n    \u003cli\u003e1\u003c/li\u003e\n    \u003cli\u003e2\u003c/li\u003e\n    \u003cli\u003e\u003cem\u003eFizz\u003c/em\u003e\u003c/li\u003e\n    \u003cli\u003e4\u003c/li\u003e\n    \u003cli\u003e\u003cem\u003eBuzz\u003c/em\u003e\u003c/li\u003e\n    \u003cli\u003e\u003cem\u003eFizz\u003c/em\u003e\u003c/li\u003e\n    \u003cli\u003e7\u003c/li\u003e\n    \u003cli\u003e8\u003c/li\u003e\n    \u003cli\u003e\u003cem\u003eFizz\u003c/em\u003e\u003c/li\u003e\n    \u003cli\u003e\u003cem\u003eBuzz\u003c/em\u003e\u003c/li\u003e\n    \u003cli\u003e11\u003c/li\u003e\n    \u003cli\u003e\u003cem\u003eFizz\u003c/em\u003e\u003c/li\u003e\n    \u003cli\u003e13\u003c/li\u003e\n    \u003cli\u003e14\u003c/li\u003e\n    \u003cli\u003e\u003cstrong\u003eFizzBuzz\u003c/strong\u003e\u003c/li\u003e\n  \u003c/ul\u003e\n\u003c/body\u003e\n\n\u003c/html\u003e\n```\n\nLooping on `IEnumerable\u003cT\u003e`:\n\n- `Each\u003cT\u003e`\n\nConditionals on `IEnumerable\u003cT\u003e`:\n\n- `IfEmpty\u003cT\u003e`\n- `IfNotEmpty\u003cT\u003e`\n\nConditionals on `T`:\n\n- `IfNull\u003cT\u003e`\n- `IfNotNull\u003cT\u003e`\n- `IfMatch\u003cT\u003e`\n\nConditionals on `string`:\n\n- `IfNullOrEmpty`\n- `IfNotNullOrEmpty`\n\nConditionals on `T?`:\n\n- `IfHasValue\u003cT\u003e`\n\n## String Interpolation\n\nYou can interpolate strings and string literals with the methods of `Markupolation`.\n\nThese concepts in .NET are of interest:\n\n- [String interpolation](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated)\n- [String literals](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/reference-types#string-literals)\n- [Verbatim text](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/verbatim)\n- [Raw string literal text](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/raw-string)\n\n## Using Directives\n\nWhen `ImplicitUsings` are enabled:\n\n```xml\n\u003cPropertyGroup\u003e\n  \u003cImplicitUsings\u003eenable\u003c/ImplicitUsings\u003e\n\u003c/PropertyGroup\u003e\n```\n\nThese using directives are applied automatically:\n\n```xml\n\u003cItemGroup\u003e\n  \u003cUsing Include=\"Markupolation\" /\u003e\n  \u003cUsing Include=\"Markupolation.Elements\" Static=\"True\" /\u003e\n  \u003cUsing Include=\"Markupolation.Elements\" Alias=\"e\" /\u003e\n  \u003cUsing Include=\"Markupolation.Element\" Alias=\"E\" /\u003e\n  \u003cUsing Include=\"Markupolation.Attributes\" Static=\"True\" /\u003e\n  \u003cUsing Include=\"Markupolation.Attributes\" Alias=\"a\" /\u003e\n  \u003cUsing Include=\"Markupolation.Attribute\" Alias=\"A\" /\u003e\n  \u003cUsing Include=\"Markupolation.EventHandlerContentAttributes\" Static=\"True\" /\u003e\n\u003c/ItemGroup\u003e\n```\n\nIf you do not want to enable `ImplicitUsings` in your project, you can copy and paste the above into your `.csproj` file.\n\nAlternatively you can add the following using directives in a `.cs` file:\n\n```cs\nglobal using Markupolation;\nglobal using static Markupolation.Elements;\nglobal using e = Markupolation.Elements;\nglobal using E = Markupolation.Element;\nglobal using static Markupolation.Attributes;\nglobal using a = Markupolation.Attributes;\nglobal using A = Markupolation.Attribute;\nglobal using static Markupolation.EventHandlerContentAttributes;\n```\n\n## Performance\n\nString concatenation in C# can be done in [different](https://docs.microsoft.com/en-us/dotnet/csharp/how-to/concatenate-multiple-strings) ways.\nConventional wisdom is to use the `StringBuilder` class.\nJon Skeet offers advice on [Concatenating Strings Efficiently](https://jonskeet.uk/csharp/stringbuilder.html).\n\nC# 10 offers\n[improved](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/improved-interpolated-strings)\nand\n[constant](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/constant_interpolated_strings)\ninterpolated strings that you can benefit from when using `Markupolation`.\n\nThe tests folder contains some [benchmarks](/tests/Markupolation.Benchmark).\n\n## Samples\n\nThe [samples](/samples) folder contains examples of `Markupolation` together with:\n\n- Blazor + Functions + Tye\n- HTMX + Api + YARP + Aspire\n- Console + Playwright\n\nThe [PlaygroundTests](/tests/Markupolation.Tests/PlaygroundTests.cs) also contains some templating code that you may find interesting.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhlaueriksson%2Fmarkupolation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhlaueriksson%2Fmarkupolation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhlaueriksson%2Fmarkupolation/lists"}