Repository files navigation

NuGet Readme

VersionDownloadsEULALicense

Usage

Adds automatic package readme packing and include-directive resolution at pack time. Works with SDK Pack and NuGetizer (no NuGetizer required).

<PackageReferenceInclude="Readme"Version="*" />

You don't need to set PrivateAssets=all: Readme is a development dependency and automatically excludes itself from packed dependencies.

When the project is packable and a readme.md (or $(PackageReadmeFile)) is present:

  1. The readme is included in the package automatically (PackReadme=false to opt out).
  2. Include directives are resolved before pack (local files, nested includes, #fragment sections, HTTP(S) URLs).
  3. NuGet-style $token$ replacements are applied to the expanded content.
  4. Relative Markdown links/images are expanded to raw.githubusercontent.com URLs when the project has a GitHub RepositoryUrl and commit (opt out: ReadmeExpandGitHubUrls=false; auto-skipped when url/commit is missing or not github.com).
  5. The processed file is written under $(BaseIntermediateOutputPath) and that intermediate file is what is packed.

Example

This package's own project-level readme.md is essentially three includes:

<!-- include ../../readme.md#content -->
<!-- include https://github.com/devlooped/.github/raw/main/osmf.md -->
<!-- include https://github.com/devlooped/sponsors/raw/main/footer.md -->

(written as HTML comments in your actual readme, using '!' rather than '!` used above for rendering purposes)

IncludeWhat it does
../../readme.md#contentLocal file + #fragment — pulls the docs body between matching <!-- #content --><!-- #content --> anchors in the repo readme
https://…/osmf.mdRemote HTTPS — shared Open Source Maintenance Fee / EULA notice
https://…/footer.mdRemote HTTPS — shared sponsors footer

That keeps the package readme short, reuses the repo docs, and keeps EULA and sponsors in sync across packages.

Include syntax

Use an HTML comment starting with include and a path (relative file, #fragment, or http(s) URL). Nested includes are supported.

Fragments resolve in this order:

  1. Explicit comment anchors — matching <!-- #section --><!-- #section --> pairs (when present). The markers and everything between them is included, so you control whether a section title is in the range (for example put ## Usage inside the pair to keep the title, or place the pair after the heading to omit it).
  2. GitHub heading auto-anchors — otherwise the Markdown ATX heading whose GitHub auto-anchor matches the fragment (for example ## Usage for #usage). The heading line itself is included, through the line before the next heading of the same or higher level.

Use explicit <!-- #fragment --> markup when you need maximum control over whether the section name is included; auto-anchors always include the matching heading.

Unresolved includes log a warning and leave the marker in place (pack does not fail).

To document the include syntax itself without expansion, put example directives in a fenced code block with language exclude (as in the example above). Includes in other code fences are still resolved.

Remote includes

Absolute http(s) includes from a local file are always allowed (subject to scheme). Includes nested inside remote content resolve relative paths against that URL’s base. Absolute URLs from remote content are allowed only when the host is the same as (or a subdomain of) the including remote host, or is listed in @(ReadmeIncludeDomain) (subdomains of listed domains count too). Other schemes/hosts warn and stay unresolved.

Properties

Property / itemDefaultDescription
PackReadmetrueAuto-pack the package readme when present
PackageReadmeFilereadme.md if it existsPackage readme path / in-package filename
ReadmeIncludeSchemehttpsSemicolon-separated URI schemes allowed for remote includes (add http only if needed)
ReadmeExpandGitHubUrlstrueExpand relative links/images to raw.githubusercontent.com when RepositoryUrl is github.com and a commit is available
@(ReadmeIncludeDomain)(empty)Hosts allowed for absolute remote includes nested inside remote content
@(PackageReplacementToken)Id, Version, Author, Authors, Title, Description, Copyright, Configuration, Product$token$ replacements (defaults from CollectReplacementTokens)
<PropertyGroup>
<!-- Optional: allow cleartext remote includes -->
<ReadmeIncludeScheme>https;http</ReadmeIncludeScheme>
</PropertyGroup>
<ItemGroup>
<ReadmeIncludeDomainInclude="cdn.example.com" />
</ItemGroup>

Replacement tokens

Supports the official NuGet replacement tokens ($id$, $version$, $author$, $title$, $description$, $copyright$, $configuration$), plus $authors$ (MSBuild $(Authors)) and $product$ (as in NuGetizer). Replacements run after include expansion so tokens inside included files are replaced too.

Defaults are populated by the CollectReplacementTokens target (same item name as NuGetizer: @(PackageReplacementToken)). Duplicate names keep the last value — never an error — so Readme and NuGetizer can both contribute tokens.

Extend tokens (readme and other files)

Add items anytime; use them case-insensitively as $company$ in the readme:

<ItemGroup>
<PackageReplacementTokenInclude="Company"Value="$(Company)" />
</ItemGroup>

Override or remove defaults after they are collected:

<TargetName="CustomizePackageTokens"AfterTargets="CollectReplacementTokens">
<ItemGroup>
<PackageReplacementTokenRemove="Product" />
<PackageReplacementTokenInclude="BuildDate"Value="$([System.DateTime]::UtcNow.ToString('yyyy-MM-dd'))" />
</ItemGroup>
</Target>

Pre-work before defaults (e.g. compute properties) via $(CollectReplacementTokensDependsOn) or BeforeTargets="CollectReplacementTokens".

Replace tokens in arbitrary files

ReplacePackageTokens applies the same @(PackageReplacementToken) map to any file. Pair it with Inputs / Outputs for incremental builds. Unknown remaining $token$ placeholders emit warning RDM001 (suppress with <NoWarn>$(NoWarn);RDM001</NoWarn>). The package-readme path does not warn on unknown tokens (docs may contain $…$ examples).

<TargetName="ProcessPackageEula"DependsOnTargets="CollectReplacementTokens"Inputs="osmfeula.txt"Outputs="$(IntermediateOutputPath)OSMFEULA.txt">
<ReplacePackageTokensInputFile="osmfeula.txt"OutputFile="$(IntermediateOutputPath)OSMFEULA.txt"Tokens="@(PackageReplacementToken)" />
</Target>

GitHub relative URLs

When packing a package whose repository is on GitHub, relative Markdown links and images in the readme are rewritten so nuget.org (and other consumers) can resolve them:

See [license](license.txt) and ![logo](img/logo.png).

becomes (pinned to the packed commit):

See [license](https://raw.githubusercontent.com/org/repo/<commit>/license.txt) and ![logo](https://raw.githubusercontent.com/org/repo/<commit>/img/logo.png).

Requires a github.com RepositoryUrl (or SourceLink PrivateRepositoryUrl with PublishRepositoryUrl=true) and a commit from RepositoryCommit, RepositorySha, or SourceRevisionId. Absolute URLs are left unchanged. Nested clickable images ([![alt](img.png)](doc.txt)) expand both the image and the outer link.

<PropertyGroup>
<!-- Optional: leave relative URLs as-is -->
<ReadmeExpandGitHubUrls>false</ReadmeExpandGitHubUrls>
</PropertyGroup>

Open Source Maintenance Fee

To ensure the long-term sustainability of this project, users of this package who generate revenue must pay an Open Source Maintenance Fee. While the source code is freely available under the terms of the License, this package and other aspects of the project require adherence to the Maintenance Fee.

To pay the Maintenance Fee, become a Sponsor at the proper OSMF tier. A single fee covers all of Devlooped packages.


Sponsors

Clarius OrgMFB Technologies, Inc.SandRockDRIVE.NET, Inc.Keith PickfordThomas BolonReuben SwartzJacob FosheeEric JohnsonJonathan Ken BonnySimon Croppagileworks-euZheyu ShenVezelChilliCream4OTCdomischellAdrian AlonsotorutekRyan McCafferySeika LogicielAndrew Granteska-gmbhGeodata AS

Sponsor this project

Learn more about GitHub Sponsors

About

Smart readmes for nuget packages

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

NuGet Readme

VersionDownloadsEULALicense

Usage

Adds automatic package readme packing and include-directive resolution at pack time. Works with SDK Pack and NuGetizer (no NuGetizer required).

<PackageReferenceInclude="Readme"Version="*" />

You don't need to set PrivateAssets=all: Readme is a development dependency and automatically excludes itself from packed dependencies.

When the project is packable and a readme.md (or $(PackageReadmeFile)) is present:

  1. The readme is included in the package automatically (PackReadme=false to opt out).
  2. Include directives are resolved before pack (local files, nested includes, #fragment sections, HTTP(S) URLs).
  3. NuGet-style $token$ replacements are applied to the expanded content.
  4. Relative Markdown links/images are expanded to raw.githubusercontent.com URLs when the project has a GitHub RepositoryUrl and commit (opt out: ReadmeExpandGitHubUrls=false; auto-skipped when url/commit is missing or not github.com).
  5. The processed file is written under $(BaseIntermediateOutputPath) and that intermediate file is what is packed.

Example

This package's own project-level readme.md is essentially three includes:

<!-- include ../../readme.md#content -->
<!-- include https://github.com/devlooped/.github/raw/main/osmf.md -->
<!-- include https://github.com/devlooped/sponsors/raw/main/footer.md -->

(written as HTML comments in your actual readme, using '!' rather than '!` used above for rendering purposes)

IncludeWhat it does
../../readme.md#contentLocal file + #fragment — pulls the docs body between matching <!-- #content --><!-- #content --> anchors in the repo readme
https://…/osmf.mdRemote HTTPS — shared Open Source Maintenance Fee / EULA notice
https://…/footer.mdRemote HTTPS — shared sponsors footer

That keeps the package readme short, reuses the repo docs, and keeps EULA and sponsors in sync across packages.

Include syntax

Use an HTML comment starting with include and a path (relative file, #fragment, or http(s) URL). Nested includes are supported.

Fragments resolve in this order:

  1. Explicit comment anchors — matching <!-- #section --><!-- #section --> pairs (when present). The markers and everything between them is included, so you control whether a section title is in the range (for example put ## Usage inside the pair to keep the title, or place the pair after the heading to omit it).
  2. GitHub heading auto-anchors — otherwise the Markdown ATX heading whose GitHub auto-anchor matches the fragment (for example ## Usage for #usage). The heading line itself is included, through the line before the next heading of the same or higher level.

Use explicit <!-- #fragment --> markup when you need maximum control over whether the section name is included; auto-anchors always include the matching heading.

Unresolved includes log a warning and leave the marker in place (pack does not fail).

To document the include syntax itself without expansion, put example directives in a fenced code block with language exclude (as in the example above). Includes in other code fences are still resolved.

Remote includes

Absolute http(s) includes from a local file are always allowed (subject to scheme). Includes nested inside remote content resolve relative paths against that URL’s base. Absolute URLs from remote content are allowed only when the host is the same as (or a subdomain of) the including remote host, or is listed in @(ReadmeIncludeDomain) (subdomains of listed domains count too). Other schemes/hosts warn and stay unresolved.

Properties

Property / itemDefaultDescription
PackReadmetrueAuto-pack the package readme when present
PackageReadmeFilereadme.md if it existsPackage readme path / in-package filename
ReadmeIncludeSchemehttpsSemicolon-separated URI schemes allowed for remote includes (add http only if needed)
ReadmeExpandGitHubUrlstrueExpand relative links/images to raw.githubusercontent.com when RepositoryUrl is github.com and a commit is available
@(ReadmeIncludeDomain)(empty)Hosts allowed for absolute remote includes nested inside remote content
@(PackageReplacementToken)Id, Version, Author, Authors, Title, Description, Copyright, Configuration, Product$token$ replacements (defaults from CollectReplacementTokens)
<PropertyGroup>
<!-- Optional: allow cleartext remote includes -->
<ReadmeIncludeScheme>https;http</ReadmeIncludeScheme>
</PropertyGroup>
<ItemGroup>
<ReadmeIncludeDomainInclude="cdn.example.com" />
</ItemGroup>

Replacement tokens

Supports the official NuGet replacement tokens ($id$, $version$, $author$, $title$, $description$, $copyright$, $configuration$), plus $authors$ (MSBuild $(Authors)) and $product$ (as in NuGetizer). Replacements run after include expansion so tokens inside included files are replaced too.

Defaults are populated by the CollectReplacementTokens target (same item name as NuGetizer: @(PackageReplacementToken)). Duplicate names keep the last value — never an error — so Readme and NuGetizer can both contribute tokens.

Extend tokens (readme and other files)

Add items anytime; use them case-insensitively as $company$ in the readme:

<ItemGroup>
<PackageReplacementTokenInclude="Company"Value="$(Company)" />
</ItemGroup>

Override or remove defaults after they are collected:

<TargetName="CustomizePackageTokens"AfterTargets="CollectReplacementTokens">
<ItemGroup>
<PackageReplacementTokenRemove="Product" />
<PackageReplacementTokenInclude="BuildDate"Value="$([System.DateTime]::UtcNow.ToString('yyyy-MM-dd'))" />
</ItemGroup>
</Target>

Pre-work before defaults (e.g. compute properties) via $(CollectReplacementTokensDependsOn) or BeforeTargets="CollectReplacementTokens".

Replace tokens in arbitrary files

ReplacePackageTokens applies the same @(PackageReplacementToken) map to any file. Pair it with Inputs / Outputs for incremental builds. Unknown remaining $token$ placeholders emit warning RDM001 (suppress with <NoWarn>$(NoWarn);RDM001</NoWarn>). The package-readme path does not warn on unknown tokens (docs may contain $…$ examples).

<TargetName="ProcessPackageEula"DependsOnTargets="CollectReplacementTokens"Inputs="osmfeula.txt"Outputs="$(IntermediateOutputPath)OSMFEULA.txt">
<ReplacePackageTokensInputFile="osmfeula.txt"OutputFile="$(IntermediateOutputPath)OSMFEULA.txt"Tokens="@(PackageReplacementToken)" />
</Target>

GitHub relative URLs

When packing a package whose repository is on GitHub, relative Markdown links and images in the readme are rewritten so nuget.org (and other consumers) can resolve them:

See [license](license.txt) and ![logo](img/logo.png).

becomes (pinned to the packed commit):

See [license](https://raw.githubusercontent.com/org/repo/<commit>/license.txt) and ![logo](https://raw.githubusercontent.com/org/repo/<commit>/img/logo.png).

Requires a github.com RepositoryUrl (or SourceLink PrivateRepositoryUrl with PublishRepositoryUrl=true) and a commit from RepositoryCommit, RepositorySha, or SourceRevisionId. Absolute URLs are left unchanged. Nested clickable images ([![alt](img.png)](doc.txt)) expand both the image and the outer link.

<PropertyGroup>
<!-- Optional: leave relative URLs as-is -->
<ReadmeExpandGitHubUrls>false</ReadmeExpandGitHubUrls>
</PropertyGroup>

Open Source Maintenance Fee

To ensure the long-term sustainability of this project, users of this package who generate revenue must pay an Open Source Maintenance Fee. While the source code is freely available under the terms of the License, this package and other aspects of the project require adherence to the Maintenance Fee.

To pay the Maintenance Fee, become a Sponsor at the proper OSMF tier. A single fee covers all of Devlooped packages.


Sponsors

Clarius OrgMFB Technologies, Inc.SandRockDRIVE.NET, Inc.Keith PickfordThomas BolonReuben SwartzJacob FosheeEric JohnsonJonathan Ken BonnySimon Croppagileworks-euZheyu ShenVezelChilliCream4OTCdomischellAdrian AlonsotorutekRyan McCafferySeika LogicielAndrew Granteska-gmbhGeodata AS

Sponsor this project

Learn more about GitHub Sponsors

About

Smart readmes for nuget packages

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

NuGet Readme

VersionDownloadsEULALicense

Usage

Adds automatic package readme packing and include-directive resolution at pack time. Works with SDK Pack and NuGetizer (no NuGetizer required).

<PackageReferenceInclude="Readme"Version="*" />

You don't need to set PrivateAssets=all: Readme is a development dependency and automatically excludes itself from packed dependencies.

When the project is packable and a readme.md (or $(PackageReadmeFile)) is present:

  1. The readme is included in the package automatically (PackReadme=false to opt out).
  2. Include directives are resolved before pack (local files, nested includes, #fragment sections, HTTP(S) URLs).
  3. NuGet-style $token$ replacements are applied to the expanded content.
  4. Relative Markdown links/images are expanded to raw.githubusercontent.com URLs when the project has a GitHub RepositoryUrl and commit (opt out: ReadmeExpandGitHubUrls=false; auto-skipped when url/commit is missing or not github.com).
  5. The processed file is written under $(BaseIntermediateOutputPath) and that intermediate file is what is packed.

Example

This package's own project-level readme.md is essentially three includes:

<!-- include ../../readme.md#content -->
<!-- include https://github.com/devlooped/.github/raw/main/osmf.md -->
<!-- include https://github.com/devlooped/sponsors/raw/main/footer.md -->

(written as HTML comments in your actual readme, using '!' rather than '!` used above for rendering purposes)

IncludeWhat it does
../../readme.md#contentLocal file + #fragment — pulls the docs body between matching <!-- #content --><!-- #content --> anchors in the repo readme
https://…/osmf.mdRemote HTTPS — shared Open Source Maintenance Fee / EULA notice
https://…/footer.mdRemote HTTPS — shared sponsors footer

That keeps the package readme short, reuses the repo docs, and keeps EULA and sponsors in sync across packages.

Include syntax

Use an HTML comment starting with include and a path (relative file, #fragment, or http(s) URL). Nested includes are supported.

Fragments resolve in this order:

  1. Explicit comment anchors — matching <!-- #section --><!-- #section --> pairs (when present). The markers and everything between them is included, so you control whether a section title is in the range (for example put ## Usage inside the pair to keep the title, or place the pair after the heading to omit it).
  2. GitHub heading auto-anchors — otherwise the Markdown ATX heading whose GitHub auto-anchor matches the fragment (for example ## Usage for #usage). The heading line itself is included, through the line before the next heading of the same or higher level.

Use explicit <!-- #fragment --> markup when you need maximum control over whether the section name is included; auto-anchors always include the matching heading.

Unresolved includes log a warning and leave the marker in place (pack does not fail).

To document the include syntax itself without expansion, put example directives in a fenced code block with language exclude (as in the example above). Includes in other code fences are still resolved.

Remote includes

Absolute http(s) includes from a local file are always allowed (subject to scheme). Includes nested inside remote content resolve relative paths against that URL’s base. Absolute URLs from remote content are allowed only when the host is the same as (or a subdomain of) the including remote host, or is listed in @(ReadmeIncludeDomain) (subdomains of listed domains count too). Other schemes/hosts warn and stay unresolved.

Properties

Property / itemDefaultDescription
PackReadmetrueAuto-pack the package readme when present
PackageReadmeFilereadme.md if it existsPackage readme path / in-package filename
ReadmeIncludeSchemehttpsSemicolon-separated URI schemes allowed for remote includes (add http only if needed)
ReadmeExpandGitHubUrlstrueExpand relative links/images to raw.githubusercontent.com when RepositoryUrl is github.com and a commit is available
@(ReadmeIncludeDomain)(empty)Hosts allowed for absolute remote includes nested inside remote content
@(PackageReplacementToken)Id, Version, Author, Authors, Title, Description, Copyright, Configuration, Product$token$ replacements (defaults from CollectReplacementTokens)
<PropertyGroup>
<!-- Optional: allow cleartext remote includes -->
<ReadmeIncludeScheme>https;http</ReadmeIncludeScheme>
</PropertyGroup>
<ItemGroup>
<ReadmeIncludeDomainInclude="cdn.example.com" />
</ItemGroup>

Replacement tokens

Supports the official NuGet replacement tokens ($id$, $version$, $author$, $title$, $description$, $copyright$, $configuration$), plus $authors$ (MSBuild $(Authors)) and $product$ (as in NuGetizer). Replacements run after include expansion so tokens inside included files are replaced too.

Defaults are populated by the CollectReplacementTokens target (same item name as NuGetizer: @(PackageReplacementToken)). Duplicate names keep the last value — never an error — so Readme and NuGetizer can both contribute tokens.

Extend tokens (readme and other files)

Add items anytime; use them case-insensitively as $company$ in the readme:

<ItemGroup>
<PackageReplacementTokenInclude="Company"Value="$(Company)" />
</ItemGroup>

Override or remove defaults after they are collected:

<TargetName="CustomizePackageTokens"AfterTargets="CollectReplacementTokens">
<ItemGroup>
<PackageReplacementTokenRemove="Product" />
<PackageReplacementTokenInclude="BuildDate"Value="$([System.DateTime]::UtcNow.ToString('yyyy-MM-dd'))" />
</ItemGroup>
</Target>

Pre-work before defaults (e.g. compute properties) via $(CollectReplacementTokensDependsOn) or BeforeTargets="CollectReplacementTokens".

Replace tokens in arbitrary files

ReplacePackageTokens applies the same @(PackageReplacementToken) map to any file. Pair it with Inputs / Outputs for incremental builds. Unknown remaining $token$ placeholders emit warning RDM001 (suppress with <NoWarn>$(NoWarn);RDM001</NoWarn>). The package-readme path does not warn on unknown tokens (docs may contain $…$ examples).

<TargetName="ProcessPackageEula"DependsOnTargets="CollectReplacementTokens"Inputs="osmfeula.txt"Outputs="$(IntermediateOutputPath)OSMFEULA.txt">
<ReplacePackageTokensInputFile="osmfeula.txt"OutputFile="$(IntermediateOutputPath)OSMFEULA.txt"Tokens="@(PackageReplacementToken)" />
</Target>

GitHub relative URLs

When packing a package whose repository is on GitHub, relative Markdown links and images in the readme are rewritten so nuget.org (and other consumers) can resolve them:

See [license](license.txt) and ![logo](img/logo.png).

becomes (pinned to the packed commit):

See [license](https://raw.githubusercontent.com/org/repo/<commit>/license.txt) and ![logo](https://raw.githubusercontent.com/org/repo/<commit>/img/logo.png).

Requires a github.com RepositoryUrl (or SourceLink PrivateRepositoryUrl with PublishRepositoryUrl=true) and a commit from RepositoryCommit, RepositorySha, or SourceRevisionId. Absolute URLs are left unchanged. Nested clickable images ([![alt](img.png)](doc.txt)) expand both the image and the outer link.

<PropertyGroup>
<!-- Optional: leave relative URLs as-is -->
<ReadmeExpandGitHubUrls>false</ReadmeExpandGitHubUrls>
</PropertyGroup>

Open Source Maintenance Fee

To ensure the long-term sustainability of this project, users of this package who generate revenue must pay an Open Source Maintenance Fee. While the source code is freely available under the terms of the License, this package and other aspects of the project require adherence to the Maintenance Fee.

To pay the Maintenance Fee, become a Sponsor at the proper OSMF tier. A single fee covers all of Devlooped packages.


Sponsors

Clarius OrgMFB Technologies, Inc.SandRockDRIVE.NET, Inc.Keith PickfordThomas BolonReuben SwartzJacob FosheeEric JohnsonJonathan Ken BonnySimon Croppagileworks-euZheyu ShenVezelChilliCream4OTCdomischellAdrian AlonsotorutekRyan McCafferySeika LogicielAndrew Granteska-gmbhGeodata AS

Sponsor this project

Learn more about GitHub Sponsors

About

Smart readmes for nuget packages

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

NuGet Readme

VersionDownloadsEULALicense

Usage

Adds automatic package readme packing and include-directive resolution at pack time. Works with SDK Pack and NuGetizer (no NuGetizer required).

<PackageReferenceInclude="Readme"Version="*" />

You don't need to set PrivateAssets=all: Readme is a development dependency and automatically excludes itself from packed dependencies.

When the project is packable and a readme.md (or $(PackageReadmeFile)) is present:

  1. The readme is included in the package automatically (PackReadme=false to opt out).
  2. Include directives are resolved before pack (local files, nested includes, #fragment sections, HTTP(S) URLs).
  3. NuGet-style $token$ replacements are applied to the expanded content.
  4. Relative Markdown links/images are expanded to raw.githubusercontent.com URLs when the project has a GitHub RepositoryUrl and commit (opt out: ReadmeExpandGitHubUrls=false; auto-skipped when url/commit is missing or not github.com).
  5. The processed file is written under $(BaseIntermediateOutputPath) and that intermediate file is what is packed.

Example

This package's own project-level readme.md is essentially three includes:

<!-- include ../../readme.md#content -->
<!-- include https://github.com/devlooped/.github/raw/main/osmf.md -->
<!-- include https://github.com/devlooped/sponsors/raw/main/footer.md -->

(written as HTML comments in your actual readme, using '!' rather than '!` used above for rendering purposes)

IncludeWhat it does
../../readme.md#contentLocal file + #fragment — pulls the docs body between matching <!-- #content --><!-- #content --> anchors in the repo readme
https://…/osmf.mdRemote HTTPS — shared Open Source Maintenance Fee / EULA notice
https://…/footer.mdRemote HTTPS — shared sponsors footer

That keeps the package readme short, reuses the repo docs, and keeps EULA and sponsors in sync across packages.

Include syntax

Use an HTML comment starting with include and a path (relative file, #fragment, or http(s) URL). Nested includes are supported.

Fragments resolve in this order:

  1. Explicit comment anchors — matching <!-- #section --><!-- #section --> pairs (when present). The markers and everything between them is included, so you control whether a section title is in the range (for example put ## Usage inside the pair to keep the title, or place the pair after the heading to omit it).
  2. GitHub heading auto-anchors — otherwise the Markdown ATX heading whose GitHub auto-anchor matches the fragment (for example ## Usage for #usage). The heading line itself is included, through the line before the next heading of the same or higher level.

Use explicit <!-- #fragment --> markup when you need maximum control over whether the section name is included; auto-anchors always include the matching heading.

Unresolved includes log a warning and leave the marker in place (pack does not fail).

To document the include syntax itself without expansion, put example directives in a fenced code block with language exclude (as in the example above). Includes in other code fences are still resolved.

Remote includes

Absolute http(s) includes from a local file are always allowed (subject to scheme). Includes nested inside remote content resolve relative paths against that URL’s base. Absolute URLs from remote content are allowed only when the host is the same as (or a subdomain of) the including remote host, or is listed in @(ReadmeIncludeDomain) (subdomains of listed domains count too). Other schemes/hosts warn and stay unresolved.

Properties

Property / itemDefaultDescription
PackReadmetrueAuto-pack the package readme when present
PackageReadmeFilereadme.md if it existsPackage readme path / in-package filename
ReadmeIncludeSchemehttpsSemicolon-separated URI schemes allowed for remote includes (add http only if needed)
ReadmeExpandGitHubUrlstrueExpand relative links/images to raw.githubusercontent.com when RepositoryUrl is github.com and a commit is available
@(ReadmeIncludeDomain)(empty)Hosts allowed for absolute remote includes nested inside remote content
@(PackageReplacementToken)Id, Version, Author, Authors, Title, Description, Copyright, Configuration, Product$token$ replacements (defaults from CollectReplacementTokens)
<PropertyGroup>
<!-- Optional: allow cleartext remote includes -->
<ReadmeIncludeScheme>https;http</ReadmeIncludeScheme>
</PropertyGroup>
<ItemGroup>
<ReadmeIncludeDomainInclude="cdn.example.com" />
</ItemGroup>

Replacement tokens

Supports the official NuGet replacement tokens ($id$, $version$, $author$, $title$, $description$, $copyright$, $configuration$), plus $authors$ (MSBuild $(Authors)) and $product$ (as in NuGetizer). Replacements run after include expansion so tokens inside included files are replaced too.

Defaults are populated by the CollectReplacementTokens target (same item name as NuGetizer: @(PackageReplacementToken)). Duplicate names keep the last value — never an error — so Readme and NuGetizer can both contribute tokens.

Extend tokens (readme and other files)

Add items anytime; use them case-insensitively as $company$ in the readme:

<ItemGroup>
<PackageReplacementTokenInclude="Company"Value="$(Company)" />
</ItemGroup>

Override or remove defaults after they are collected:

<TargetName="CustomizePackageTokens"AfterTargets="CollectReplacementTokens">
<ItemGroup>
<PackageReplacementTokenRemove="Product" />
<PackageReplacementTokenInclude="BuildDate"Value="$([System.DateTime]::UtcNow.ToString('yyyy-MM-dd'))" />
</ItemGroup>
</Target>

Pre-work before defaults (e.g. compute properties) via $(CollectReplacementTokensDependsOn) or BeforeTargets="CollectReplacementTokens".

Replace tokens in arbitrary files

ReplacePackageTokens applies the same @(PackageReplacementToken) map to any file. Pair it with Inputs / Outputs for incremental builds. Unknown remaining $token$ placeholders emit warning RDM001 (suppress with <NoWarn>$(NoWarn);RDM001</NoWarn>). The package-readme path does not warn on unknown tokens (docs may contain $…$ examples).

<TargetName="ProcessPackageEula"DependsOnTargets="CollectReplacementTokens"Inputs="osmfeula.txt"Outputs="$(IntermediateOutputPath)OSMFEULA.txt">
<ReplacePackageTokensInputFile="osmfeula.txt"OutputFile="$(IntermediateOutputPath)OSMFEULA.txt"Tokens="@(PackageReplacementToken)" />
</Target>

GitHub relative URLs

When packing a package whose repository is on GitHub, relative Markdown links and images in the readme are rewritten so nuget.org (and other consumers) can resolve them:

See [license](license.txt) and ![logo](img/logo.png).

becomes (pinned to the packed commit):

See [license](https://raw.githubusercontent.com/org/repo/<commit>/license.txt) and ![logo](https://raw.githubusercontent.com/org/repo/<commit>/img/logo.png).

Requires a github.com RepositoryUrl (or SourceLink PrivateRepositoryUrl with PublishRepositoryUrl=true) and a commit from RepositoryCommit, RepositorySha, or SourceRevisionId. Absolute URLs are left unchanged. Nested clickable images ([![alt](img.png)](doc.txt)) expand both the image and the outer link.

<PropertyGroup>
<!-- Optional: leave relative URLs as-is -->
<ReadmeExpandGitHubUrls>false</ReadmeExpandGitHubUrls>
</PropertyGroup>

Open Source Maintenance Fee

To ensure the long-term sustainability of this project, users of this package who generate revenue must pay an Open Source Maintenance Fee. While the source code is freely available under the terms of the License, this package and other aspects of the project require adherence to the Maintenance Fee.

To pay the Maintenance Fee, become a Sponsor at the proper OSMF tier. A single fee covers all of Devlooped packages.


Sponsors

Clarius OrgMFB Technologies, Inc.SandRockDRIVE.NET, Inc.Keith PickfordThomas BolonReuben SwartzJacob FosheeEric JohnsonJonathan Ken BonnySimon Croppagileworks-euZheyu ShenVezelChilliCream4OTCdomischellAdrian AlonsotorutekRyan McCafferySeika LogicielAndrew Granteska-gmbhGeodata AS

Sponsor this project

Learn more about GitHub Sponsors

About

Smart readmes for nuget packages

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

NuGet Readme

VersionDownloadsEULALicense

Usage

Adds automatic package readme packing and include-directive resolution at pack time. Works with SDK Pack and NuGetizer (no NuGetizer required).

<PackageReferenceInclude="Readme"Version="*" />

You don't need to set PrivateAssets=all: Readme is a development dependency and automatically excludes itself from packed dependencies.

When the project is packable and a readme.md (or $(PackageReadmeFile)) is present:

  1. The readme is included in the package automatically (PackReadme=false to opt out).
  2. Include directives are resolved before pack (local files, nested includes, #fragment sections, HTTP(S) URLs).
  3. NuGet-style $token$ replacements are applied to the expanded content.
  4. Relative Markdown links/images are expanded to raw.githubusercontent.com URLs when the project has a GitHub RepositoryUrl and commit (opt out: ReadmeExpandGitHubUrls=false; auto-skipped when url/commit is missing or not github.com).
  5. The processed file is written under $(BaseIntermediateOutputPath) and that intermediate file is what is packed.

Example

This package's own project-level readme.md is essentially three includes:

<!-- include ../../readme.md#content -->
<!-- include https://github.com/devlooped/.github/raw/main/osmf.md -->
<!-- include https://github.com/devlooped/sponsors/raw/main/footer.md -->

(written as HTML comments in your actual readme, using '!' rather than '!` used above for rendering purposes)

IncludeWhat it does
../../readme.md#contentLocal file + #fragment — pulls the docs body between matching <!-- #content --><!-- #content --> anchors in the repo readme
https://…/osmf.mdRemote HTTPS — shared Open Source Maintenance Fee / EULA notice
https://…/footer.mdRemote HTTPS — shared sponsors footer

That keeps the package readme short, reuses the repo docs, and keeps EULA and sponsors in sync across packages.

Include syntax

Use an HTML comment starting with include and a path (relative file, #fragment, or http(s) URL). Nested includes are supported.

Fragments resolve in this order:

  1. Explicit comment anchors — matching <!-- #section --><!-- #section --> pairs (when present). The markers and everything between them is included, so you control whether a section title is in the range (for example put ## Usage inside the pair to keep the title, or place the pair after the heading to omit it).
  2. GitHub heading auto-anchors — otherwise the Markdown ATX heading whose GitHub auto-anchor matches the fragment (for example ## Usage for #usage). The heading line itself is included, through the line before the next heading of the same or higher level.

Use explicit <!-- #fragment --> markup when you need maximum control over whether the section name is included; auto-anchors always include the matching heading.

Unresolved includes log a warning and leave the marker in place (pack does not fail).

To document the include syntax itself without expansion, put example directives in a fenced code block with language exclude (as in the example above). Includes in other code fences are still resolved.

Remote includes

Absolute http(s) includes from a local file are always allowed (subject to scheme). Includes nested inside remote content resolve relative paths against that URL’s base. Absolute URLs from remote content are allowed only when the host is the same as (or a subdomain of) the including remote host, or is listed in @(ReadmeIncludeDomain) (subdomains of listed domains count too). Other schemes/hosts warn and stay unresolved.

Properties

Property / itemDefaultDescription
PackReadmetrueAuto-pack the package readme when present
PackageReadmeFilereadme.md if it existsPackage readme path / in-package filename
ReadmeIncludeSchemehttpsSemicolon-separated URI schemes allowed for remote includes (add http only if needed)
ReadmeExpandGitHubUrlstrueExpand relative links/images to raw.githubusercontent.com when RepositoryUrl is github.com and a commit is available
@(ReadmeIncludeDomain)(empty)Hosts allowed for absolute remote includes nested inside remote content
@(PackageReplacementToken)Id, Version, Author, Authors, Title, Description, Copyright, Configuration, Product$token$ replacements (defaults from CollectReplacementTokens)
<PropertyGroup>
<!-- Optional: allow cleartext remote includes -->
<ReadmeIncludeScheme>https;http</ReadmeIncludeScheme>
</PropertyGroup>
<ItemGroup>
<ReadmeIncludeDomainInclude="cdn.example.com" />
</ItemGroup>

Replacement tokens

Supports the official NuGet replacement tokens ($id$, $version$, $author$, $title$, $description$, $copyright$, $configuration$), plus $authors$ (MSBuild $(Authors)) and $product$ (as in NuGetizer). Replacements run after include expansion so tokens inside included files are replaced too.

Defaults are populated by the CollectReplacementTokens target (same item name as NuGetizer: @(PackageReplacementToken)). Duplicate names keep the last value — never an error — so Readme and NuGetizer can both contribute tokens.

Extend tokens (readme and other files)

Add items anytime; use them case-insensitively as $company$ in the readme:

<ItemGroup>
<PackageReplacementTokenInclude="Company"Value="$(Company)" />
</ItemGroup>

Override or remove defaults after they are collected:

<TargetName="CustomizePackageTokens"AfterTargets="CollectReplacementTokens">
<ItemGroup>
<PackageReplacementTokenRemove="Product" />
<PackageReplacementTokenInclude="BuildDate"Value="$([System.DateTime]::UtcNow.ToString('yyyy-MM-dd'))" />
</ItemGroup>
</Target>

Pre-work before defaults (e.g. compute properties) via $(CollectReplacementTokensDependsOn) or BeforeTargets="CollectReplacementTokens".

Replace tokens in arbitrary files

ReplacePackageTokens applies the same @(PackageReplacementToken) map to any file. Pair it with Inputs / Outputs for incremental builds. Unknown remaining $token$ placeholders emit warning RDM001 (suppress with <NoWarn>$(NoWarn);RDM001</NoWarn>). The package-readme path does not warn on unknown tokens (docs may contain $…$ examples).

<TargetName="ProcessPackageEula"DependsOnTargets="CollectReplacementTokens"Inputs="osmfeula.txt"Outputs="$(IntermediateOutputPath)OSMFEULA.txt">
<ReplacePackageTokensInputFile="osmfeula.txt"OutputFile="$(IntermediateOutputPath)OSMFEULA.txt"Tokens="@(PackageReplacementToken)" />
</Target>

GitHub relative URLs

When packing a package whose repository is on GitHub, relative Markdown links and images in the readme are rewritten so nuget.org (and other consumers) can resolve them:

See [license](license.txt) and ![logo](img/logo.png).

becomes (pinned to the packed commit):

See [license](https://raw.githubusercontent.com/org/repo/<commit>/license.txt) and ![logo](https://raw.githubusercontent.com/org/repo/<commit>/img/logo.png).

Requires a github.com RepositoryUrl (or SourceLink PrivateRepositoryUrl with PublishRepositoryUrl=true) and a commit from RepositoryCommit, RepositorySha, or SourceRevisionId. Absolute URLs are left unchanged. Nested clickable images ([![alt](img.png)](doc.txt)) expand both the image and the outer link.

<PropertyGroup>
<!-- Optional: leave relative URLs as-is -->
<ReadmeExpandGitHubUrls>false</ReadmeExpandGitHubUrls>
</PropertyGroup>

Open Source Maintenance Fee

To ensure the long-term sustainability of this project, users of this package who generate revenue must pay an Open Source Maintenance Fee. While the source code is freely available under the terms of the License, this package and other aspects of the project require adherence to the Maintenance Fee.

To pay the Maintenance Fee, become a Sponsor at the proper OSMF tier. A single fee covers all of Devlooped packages.


Sponsors

Clarius OrgMFB Technologies, Inc.SandRockDRIVE.NET, Inc.Keith PickfordThomas BolonReuben SwartzJacob FosheeEric JohnsonJonathan Ken BonnySimon Croppagileworks-euZheyu ShenVezelChilliCream4OTCdomischellAdrian AlonsotorutekRyan McCafferySeika LogicielAndrew Granteska-gmbhGeodata AS

Sponsor this project

Learn more about GitHub Sponsors

About

Smart readmes for nuget packages

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

NuGet Readme

VersionDownloadsEULALicense

Usage

Adds automatic package readme packing and include-directive resolution at pack time. Works with SDK Pack and NuGetizer (no NuGetizer required).

<PackageReferenceInclude="Readme"Version="*" />

You don't need to set PrivateAssets=all: Readme is a development dependency and automatically excludes itself from packed dependencies.

When the project is packable and a readme.md (or $(PackageReadmeFile)) is present:

  1. The readme is included in the package automatically (PackReadme=false to opt out).
  2. Include directives are resolved before pack (local files, nested includes, #fragment sections, HTTP(S) URLs).
  3. NuGet-style $token$ replacements are applied to the expanded content.
  4. Relative Markdown links/images are expanded to raw.githubusercontent.com URLs when the project has a GitHub RepositoryUrl and commit (opt out: ReadmeExpandGitHubUrls=false; auto-skipped when url/commit is missing or not github.com).
  5. The processed file is written under $(BaseIntermediateOutputPath) and that intermediate file is what is packed.

Example

This package's own project-level readme.md is essentially three includes:

<!-- include ../../readme.md#content -->
<!-- include https://github.com/devlooped/.github/raw/main/osmf.md -->
<!-- include https://github.com/devlooped/sponsors/raw/main/footer.md -->

(written as HTML comments in your actual readme, using '!' rather than '!` used above for rendering purposes)

IncludeWhat it does
../../readme.md#contentLocal file + #fragment — pulls the docs body between matching <!-- #content --><!-- #content --> anchors in the repo readme
https://…/osmf.mdRemote HTTPS — shared Open Source Maintenance Fee / EULA notice
https://…/footer.mdRemote HTTPS — shared sponsors footer

That keeps the package readme short, reuses the repo docs, and keeps EULA and sponsors in sync across packages.

Include syntax

Use an HTML comment starting with include and a path (relative file, #fragment, or http(s) URL). Nested includes are supported.

Fragments resolve in this order:

  1. Explicit comment anchors — matching <!-- #section --><!-- #section --> pairs (when present). The markers and everything between them is included, so you control whether a section title is in the range (for example put ## Usage inside the pair to keep the title, or place the pair after the heading to omit it).
  2. GitHub heading auto-anchors — otherwise the Markdown ATX heading whose GitHub auto-anchor matches the fragment (for example ## Usage for #usage). The heading line itself is included, through the line before the next heading of the same or higher level.

Use explicit <!-- #fragment --> markup when you need maximum control over whether the section name is included; auto-anchors always include the matching heading.

Unresolved includes log a warning and leave the marker in place (pack does not fail).

To document the include syntax itself without expansion, put example directives in a fenced code block with language exclude (as in the example above). Includes in other code fences are still resolved.

Remote includes

Absolute http(s) includes from a local file are always allowed (subject to scheme). Includes nested inside remote content resolve relative paths against that URL’s base. Absolute URLs from remote content are allowed only when the host is the same as (or a subdomain of) the including remote host, or is listed in @(ReadmeIncludeDomain) (subdomains of listed domains count too). Other schemes/hosts warn and stay unresolved.

Properties

Property / itemDefaultDescription
PackReadmetrueAuto-pack the package readme when present
PackageReadmeFilereadme.md if it existsPackage readme path / in-package filename
ReadmeIncludeSchemehttpsSemicolon-separated URI schemes allowed for remote includes (add http only if needed)
ReadmeExpandGitHubUrlstrueExpand relative links/images to raw.githubusercontent.com when RepositoryUrl is github.com and a commit is available
@(ReadmeIncludeDomain)(empty)Hosts allowed for absolute remote includes nested inside remote content
@(PackageReplacementToken)Id, Version, Author, Authors, Title, Description, Copyright, Configuration, Product$token$ replacements (defaults from CollectReplacementTokens)
<PropertyGroup>
<!-- Optional: allow cleartext remote includes -->
<ReadmeIncludeScheme>https;http</ReadmeIncludeScheme>
</PropertyGroup>
<ItemGroup>
<ReadmeIncludeDomainInclude="cdn.example.com" />
</ItemGroup>

Replacement tokens

Supports the official NuGet replacement tokens ($id$, $version$, $author$, $title$, $description$, $copyright$, $configuration$), plus $authors$ (MSBuild $(Authors)) and $product$ (as in NuGetizer). Replacements run after include expansion so tokens inside included files are replaced too.

Defaults are populated by the CollectReplacementTokens target (same item name as NuGetizer: @(PackageReplacementToken)). Duplicate names keep the last value — never an error — so Readme and NuGetizer can both contribute tokens.

Extend tokens (readme and other files)

Add items anytime; use them case-insensitively as $company$ in the readme:

<ItemGroup>
<PackageReplacementTokenInclude="Company"Value="$(Company)" />
</ItemGroup>

Override or remove defaults after they are collected:

<TargetName="CustomizePackageTokens"AfterTargets="CollectReplacementTokens">
<ItemGroup>
<PackageReplacementTokenRemove="Product" />
<PackageReplacementTokenInclude="BuildDate"Value="$([System.DateTime]::UtcNow.ToString('yyyy-MM-dd'))" />
</ItemGroup>
</Target>

Pre-work before defaults (e.g. compute properties) via $(CollectReplacementTokensDependsOn) or BeforeTargets="CollectReplacementTokens".

Replace tokens in arbitrary files

ReplacePackageTokens applies the same @(PackageReplacementToken) map to any file. Pair it with Inputs / Outputs for incremental builds. Unknown remaining $token$ placeholders emit warning RDM001 (suppress with <NoWarn>$(NoWarn);RDM001</NoWarn>). The package-readme path does not warn on unknown tokens (docs may contain $…$ examples).

<TargetName="ProcessPackageEula"DependsOnTargets="CollectReplacementTokens"Inputs="osmfeula.txt"Outputs="$(IntermediateOutputPath)OSMFEULA.txt">
<ReplacePackageTokensInputFile="osmfeula.txt"OutputFile="$(IntermediateOutputPath)OSMFEULA.txt"Tokens="@(PackageReplacementToken)" />
</Target>

GitHub relative URLs

When packing a package whose repository is on GitHub, relative Markdown links and images in the readme are rewritten so nuget.org (and other consumers) can resolve them:

See [license](license.txt) and ![logo](img/logo.png).

becomes (pinned to the packed commit):

See [license](https://raw.githubusercontent.com/org/repo/<commit>/license.txt) and ![logo](https://raw.githubusercontent.com/org/repo/<commit>/img/logo.png).

Requires a github.com RepositoryUrl (or SourceLink PrivateRepositoryUrl with PublishRepositoryUrl=true) and a commit from RepositoryCommit, RepositorySha, or SourceRevisionId. Absolute URLs are left unchanged. Nested clickable images ([![alt](img.png)](doc.txt)) expand both the image and the outer link.

<PropertyGroup>
<!-- Optional: leave relative URLs as-is -->
<ReadmeExpandGitHubUrls>false</ReadmeExpandGitHubUrls>
</PropertyGroup>

Open Source Maintenance Fee

To ensure the long-term sustainability of this project, users of this package who generate revenue must pay an Open Source Maintenance Fee. While the source code is freely available under the terms of the License, this package and other aspects of the project require adherence to the Maintenance Fee.

To pay the Maintenance Fee, become a Sponsor at the proper OSMF tier. A single fee covers all of Devlooped packages.


Sponsors

Clarius OrgMFB Technologies, Inc.SandRockDRIVE.NET, Inc.Keith PickfordThomas BolonReuben SwartzJacob FosheeEric JohnsonJonathan Ken BonnySimon Croppagileworks-euZheyu ShenVezelChilliCream4OTCdomischellAdrian AlonsotorutekRyan McCafferySeika LogicielAndrew Granteska-gmbhGeodata AS

Sponsor this project

Learn more about GitHub Sponsors

About

Smart readmes for nuget packages

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

NuGet Readme

VersionDownloadsEULALicense

Usage

Adds automatic package readme packing and include-directive resolution at pack time. Works with SDK Pack and NuGetizer (no NuGetizer required).

<PackageReferenceInclude="Readme"Version="*" />

You don't need to set PrivateAssets=all: Readme is a development dependency and automatically excludes itself from packed dependencies.

When the project is packable and a readme.md (or $(PackageReadmeFile)) is present:

  1. The readme is included in the package automatically (PackReadme=false to opt out).
  2. Include directives are resolved before pack (local files, nested includes, #fragment sections, HTTP(S) URLs).
  3. NuGet-style $token$ replacements are applied to the expanded content.
  4. Relative Markdown links/images are expanded to raw.githubusercontent.com URLs when the project has a GitHub RepositoryUrl and commit (opt out: ReadmeExpandGitHubUrls=false; auto-skipped when url/commit is missing or not github.com).
  5. The processed file is written under $(BaseIntermediateOutputPath) and that intermediate file is what is packed.

Example

This package's own project-level readme.md is essentially three includes:

<!-- include ../../readme.md#content -->
<!-- include https://github.com/devlooped/.github/raw/main/osmf.md -->
<!-- include https://github.com/devlooped/sponsors/raw/main/footer.md -->

(written as HTML comments in your actual readme, using '!' rather than '!` used above for rendering purposes)

IncludeWhat it does
../../readme.md#contentLocal file + #fragment — pulls the docs body between matching <!-- #content --><!-- #content --> anchors in the repo readme
https://…/osmf.mdRemote HTTPS — shared Open Source Maintenance Fee / EULA notice
https://…/footer.mdRemote HTTPS — shared sponsors footer

That keeps the package readme short, reuses the repo docs, and keeps EULA and sponsors in sync across packages.

Include syntax

Use an HTML comment starting with include and a path (relative file, #fragment, or http(s) URL). Nested includes are supported.

Fragments resolve in this order:

  1. Explicit comment anchors — matching <!-- #section --><!-- #section --> pairs (when present). The markers and everything between them is included, so you control whether a section title is in the range (for example put ## Usage inside the pair to keep the title, or place the pair after the heading to omit it).
  2. GitHub heading auto-anchors — otherwise the Markdown ATX heading whose GitHub auto-anchor matches the fragment (for example ## Usage for #usage). The heading line itself is included, through the line before the next heading of the same or higher level.

Use explicit <!-- #fragment --> markup when you need maximum control over whether the section name is included; auto-anchors always include the matching heading.

Unresolved includes log a warning and leave the marker in place (pack does not fail).

To document the include syntax itself without expansion, put example directives in a fenced code block with language exclude (as in the example above). Includes in other code fences are still resolved.

Remote includes

Absolute http(s) includes from a local file are always allowed (subject to scheme). Includes nested inside remote content resolve relative paths against that URL’s base. Absolute URLs from remote content are allowed only when the host is the same as (or a subdomain of) the including remote host, or is listed in @(ReadmeIncludeDomain) (subdomains of listed domains count too). Other schemes/hosts warn and stay unresolved.

Properties

Property / itemDefaultDescription
PackReadmetrueAuto-pack the package readme when present
PackageReadmeFilereadme.md if it existsPackage readme path / in-package filename
ReadmeIncludeSchemehttpsSemicolon-separated URI schemes allowed for remote includes (add http only if needed)
ReadmeExpandGitHubUrlstrueExpand relative links/images to raw.githubusercontent.com when RepositoryUrl is github.com and a commit is available
@(ReadmeIncludeDomain)(empty)Hosts allowed for absolute remote includes nested inside remote content
@(PackageReplacementToken)Id, Version, Author, Authors, Title, Description, Copyright, Configuration, Product$token$ replacements (defaults from CollectReplacementTokens)
<PropertyGroup>
<!-- Optional: allow cleartext remote includes -->
<ReadmeIncludeScheme>https;http</ReadmeIncludeScheme>
</PropertyGroup>
<ItemGroup>
<ReadmeIncludeDomainInclude="cdn.example.com" />
</ItemGroup>

Replacement tokens

Supports the official NuGet replacement tokens ($id$, $version$, $author$, $title$, $description$, $copyright$, $configuration$), plus $authors$ (MSBuild $(Authors)) and $product$ (as in NuGetizer). Replacements run after include expansion so tokens inside included files are replaced too.

Defaults are populated by the CollectReplacementTokens target (same item name as NuGetizer: @(PackageReplacementToken)). Duplicate names keep the last value — never an error — so Readme and NuGetizer can both contribute tokens.

Extend tokens (readme and other files)

Add items anytime; use them case-insensitively as $company$ in the readme:

<ItemGroup>
<PackageReplacementTokenInclude="Company"Value="$(Company)" />
</ItemGroup>

Override or remove defaults after they are collected:

<TargetName="CustomizePackageTokens"AfterTargets="CollectReplacementTokens">
<ItemGroup>
<PackageReplacementTokenRemove="Product" />
<PackageReplacementTokenInclude="BuildDate"Value="$([System.DateTime]::UtcNow.ToString('yyyy-MM-dd'))" />
</ItemGroup>
</Target>

Pre-work before defaults (e.g. compute properties) via $(CollectReplacementTokensDependsOn) or BeforeTargets="CollectReplacementTokens".

Replace tokens in arbitrary files

ReplacePackageTokens applies the same @(PackageReplacementToken) map to any file. Pair it with Inputs / Outputs for incremental builds. Unknown remaining $token$ placeholders emit warning RDM001 (suppress with <NoWarn>$(NoWarn);RDM001</NoWarn>). The package-readme path does not warn on unknown tokens (docs may contain $…$ examples).

<TargetName="ProcessPackageEula"DependsOnTargets="CollectReplacementTokens"Inputs="osmfeula.txt"Outputs="$(IntermediateOutputPath)OSMFEULA.txt">
<ReplacePackageTokensInputFile="osmfeula.txt"OutputFile="$(IntermediateOutputPath)OSMFEULA.txt"Tokens="@(PackageReplacementToken)" />
</Target>

GitHub relative URLs

When packing a package whose repository is on GitHub, relative Markdown links and images in the readme are rewritten so nuget.org (and other consumers) can resolve them:

See [license](license.txt) and ![logo](img/logo.png).

becomes (pinned to the packed commit):

See [license](https://raw.githubusercontent.com/org/repo/<commit>/license.txt) and ![logo](https://raw.githubusercontent.com/org/repo/<commit>/img/logo.png).

Requires a github.com RepositoryUrl (or SourceLink PrivateRepositoryUrl with PublishRepositoryUrl=true) and a commit from RepositoryCommit, RepositorySha, or SourceRevisionId. Absolute URLs are left unchanged. Nested clickable images ([![alt](img.png)](doc.txt)) expand both the image and the outer link.

<PropertyGroup>
<!-- Optional: leave relative URLs as-is -->
<ReadmeExpandGitHubUrls>false</ReadmeExpandGitHubUrls>
</PropertyGroup>

Open Source Maintenance Fee

To ensure the long-term sustainability of this project, users of this package who generate revenue must pay an Open Source Maintenance Fee. While the source code is freely available under the terms of the License, this package and other aspects of the project require adherence to the Maintenance Fee.

To pay the Maintenance Fee, become a Sponsor at the proper OSMF tier. A single fee covers all of Devlooped packages.


Sponsors

Clarius OrgMFB Technologies, Inc.SandRockDRIVE.NET, Inc.Keith PickfordThomas BolonReuben SwartzJacob FosheeEric JohnsonJonathan Ken BonnySimon Croppagileworks-euZheyu ShenVezelChilliCream4OTCdomischellAdrian AlonsotorutekRyan McCafferySeika LogicielAndrew Granteska-gmbhGeodata AS

Sponsor this project

Learn more about GitHub Sponsors

About

Smart readmes for nuget packages

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

NuGet Readme

VersionDownloadsEULALicense

Usage

Adds automatic package readme packing and include-directive resolution at pack time. Works with SDK Pack and NuGetizer (no NuGetizer required).

<PackageReferenceInclude="Readme"Version="*" />

You don't need to set PrivateAssets=all: Readme is a development dependency and automatically excludes itself from packed dependencies.

When the project is packable and a readme.md (or $(PackageReadmeFile)) is present:

  1. The readme is included in the package automatically (PackReadme=false to opt out).
  2. Include directives are resolved before pack (local files, nested includes, #fragment sections, HTTP(S) URLs).
  3. NuGet-style $token$ replacements are applied to the expanded content.
  4. Relative Markdown links/images are expanded to raw.githubusercontent.com URLs when the project has a GitHub RepositoryUrl and commit (opt out: ReadmeExpandGitHubUrls=false; auto-skipped when url/commit is missing or not github.com).
  5. The processed file is written under $(BaseIntermediateOutputPath) and that intermediate file is what is packed.

Example

This package's own project-level readme.md is essentially three includes:

<!-- include ../../readme.md#content -->
<!-- include https://github.com/devlooped/.github/raw/main/osmf.md -->
<!-- include https://github.com/devlooped/sponsors/raw/main/footer.md -->

(written as HTML comments in your actual readme, using '!' rather than '!` used above for rendering purposes)

IncludeWhat it does
../../readme.md#contentLocal file + #fragment — pulls the docs body between matching <!-- #content --><!-- #content --> anchors in the repo readme
https://…/osmf.mdRemote HTTPS — shared Open Source Maintenance Fee / EULA notice
https://…/footer.mdRemote HTTPS — shared sponsors footer

That keeps the package readme short, reuses the repo docs, and keeps EULA and sponsors in sync across packages.

Include syntax

Use an HTML comment starting with include and a path (relative file, #fragment, or http(s) URL). Nested includes are supported.

Fragments resolve in this order:

  1. Explicit comment anchors — matching <!-- #section --><!-- #section --> pairs (when present). The markers and everything between them is included, so you control whether a section title is in the range (for example put ## Usage inside the pair to keep the title, or place the pair after the heading to omit it).
  2. GitHub heading auto-anchors — otherwise the Markdown ATX heading whose GitHub auto-anchor matches the fragment (for example ## Usage for #usage). The heading line itself is included, through the line before the next heading of the same or higher level.

Use explicit <!-- #fragment --> markup when you need maximum control over whether the section name is included; auto-anchors always include the matching heading.

Unresolved includes log a warning and leave the marker in place (pack does not fail).

To document the include syntax itself without expansion, put example directives in a fenced code block with language exclude (as in the example above). Includes in other code fences are still resolved.

Remote includes

Absolute http(s) includes from a local file are always allowed (subject to scheme). Includes nested inside remote content resolve relative paths against that URL’s base. Absolute URLs from remote content are allowed only when the host is the same as (or a subdomain of) the including remote host, or is listed in @(ReadmeIncludeDomain) (subdomains of listed domains count too). Other schemes/hosts warn and stay unresolved.

Properties

Property / itemDefaultDescription
PackReadmetrueAuto-pack the package readme when present
PackageReadmeFilereadme.md if it existsPackage readme path / in-package filename
ReadmeIncludeSchemehttpsSemicolon-separated URI schemes allowed for remote includes (add http only if needed)
ReadmeExpandGitHubUrlstrueExpand relative links/images to raw.githubusercontent.com when RepositoryUrl is github.com and a commit is available
@(ReadmeIncludeDomain)(empty)Hosts allowed for absolute remote includes nested inside remote content
@(PackageReplacementToken)Id, Version, Author, Authors, Title, Description, Copyright, Configuration, Product$token$ replacements (defaults from CollectReplacementTokens)
<PropertyGroup>
<!-- Optional: allow cleartext remote includes -->
<ReadmeIncludeScheme>https;http</ReadmeIncludeScheme>
</PropertyGroup>
<ItemGroup>
<ReadmeIncludeDomainInclude="cdn.example.com" />
</ItemGroup>

Replacement tokens

Supports the official NuGet replacement tokens ($id$, $version$, $author$, $title$, $description$, $copyright$, $configuration$), plus $authors$ (MSBuild $(Authors)) and $product$ (as in NuGetizer). Replacements run after include expansion so tokens inside included files are replaced too.

Defaults are populated by the CollectReplacementTokens target (same item name as NuGetizer: @(PackageReplacementToken)). Duplicate names keep the last value — never an error — so Readme and NuGetizer can both contribute tokens.

Extend tokens (readme and other files)

Add items anytime; use them case-insensitively as $company$ in the readme:

<ItemGroup>
<PackageReplacementTokenInclude="Company"Value="$(Company)" />
</ItemGroup>

Override or remove defaults after they are collected:

<TargetName="CustomizePackageTokens"AfterTargets="CollectReplacementTokens">
<ItemGroup>
<PackageReplacementTokenRemove="Product" />
<PackageReplacementTokenInclude="BuildDate"Value="$([System.DateTime]::UtcNow.ToString('yyyy-MM-dd'))" />
</ItemGroup>
</Target>

Pre-work before defaults (e.g. compute properties) via $(CollectReplacementTokensDependsOn) or BeforeTargets="CollectReplacementTokens".

Replace tokens in arbitrary files

ReplacePackageTokens applies the same @(PackageReplacementToken) map to any file. Pair it with Inputs / Outputs for incremental builds. Unknown remaining $token$ placeholders emit warning RDM001 (suppress with <NoWarn>$(NoWarn);RDM001</NoWarn>). The package-readme path does not warn on unknown tokens (docs may contain $…$ examples).

<TargetName="ProcessPackageEula"DependsOnTargets="CollectReplacementTokens"Inputs="osmfeula.txt"Outputs="$(IntermediateOutputPath)OSMFEULA.txt">
<ReplacePackageTokensInputFile="osmfeula.txt"OutputFile="$(IntermediateOutputPath)OSMFEULA.txt"Tokens="@(PackageReplacementToken)" />
</Target>

GitHub relative URLs

When packing a package whose repository is on GitHub, relative Markdown links and images in the readme are rewritten so nuget.org (and other consumers) can resolve them:

See [license](license.txt) and ![logo](img/logo.png).

becomes (pinned to the packed commit):

See [license](https://raw.githubusercontent.com/org/repo/<commit>/license.txt) and ![logo](https://raw.githubusercontent.com/org/repo/<commit>/img/logo.png).

Requires a github.com RepositoryUrl (or SourceLink PrivateRepositoryUrl with PublishRepositoryUrl=true) and a commit from RepositoryCommit, RepositorySha, or SourceRevisionId. Absolute URLs are left unchanged. Nested clickable images ([![alt](img.png)](doc.txt)) expand both the image and the outer link.

<PropertyGroup>
<!-- Optional: leave relative URLs as-is -->
<ReadmeExpandGitHubUrls>false</ReadmeExpandGitHubUrls>
</PropertyGroup>

Open Source Maintenance Fee

To ensure the long-term sustainability of this project, users of this package who generate revenue must pay an Open Source Maintenance Fee. While the source code is freely available under the terms of the License, this package and other aspects of the project require adherence to the Maintenance Fee.

To pay the Maintenance Fee, become a Sponsor at the proper OSMF tier. A single fee covers all of Devlooped packages.


Sponsors

Clarius OrgMFB Technologies, Inc.SandRockDRIVE.NET, Inc.Keith PickfordThomas BolonReuben SwartzJacob FosheeEric JohnsonJonathan Ken BonnySimon Croppagileworks-euZheyu ShenVezelChilliCream4OTCdomischellAdrian AlonsotorutekRyan McCafferySeika LogicielAndrew Granteska-gmbhGeodata AS

Sponsor this project

Learn more about GitHub Sponsors

About

Smart readmes for nuget packages

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages