Skip to content

devlooped/readme

Repository files navigation

NuGet Readme

Version Downloads EULA License

Usage

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

<PackageReference Include="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)

Include What it does
../../readme.md#content Local file + #fragment — pulls the docs body between matching <!-- #content --><!-- #content --> anchors in the repo readme
https://…/osmf.md Remote HTTPS — shared Open Source Maintenance Fee / EULA notice
https://…/footer.md Remote 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 / item Default Description
PackReadme true Auto-pack the package readme when present
PackageReadmeFile readme.md if it exists Package readme path / in-package filename
ReadmeIncludeScheme https Semicolon-separated URI schemes allowed for remote includes (add http only if needed)
ReadmeExpandGitHubUrls true Expand 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>
  <ReadmeIncludeDomain Include="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>
  <PackageReplacementToken Include="Company" Value="$(Company)" />
</ItemGroup>

Override or remove defaults after they are collected:

<Target Name="CustomizePackageTokens" AfterTargets="CollectReplacementTokens">
  <ItemGroup>
    <PackageReplacementToken Remove="Product" />
    <PackageReplacementToken Include="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).

<Target Name="ProcessPackageEula"
        DependsOnTargets="CollectReplacementTokens"
        Inputs="osmfeula.txt"
        Outputs="$(IntermediateOutputPath)OSMFEULA.txt">
  <ReplacePackageTokens InputFile="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://github.com/org/repo/<commit>/license.txt) and ![logo](https://github.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 Org MFB Technologies, Inc. SandRock DRIVE.NET, Inc. Keith Pickford Thomas Bolon Kori Francis Reuben Swartz Jacob Foshee Eric Johnson Jonathan Ken Bonny Simon Cropp agileworks-eu Zheyu Shen Vezel ChilliCream 4OTC domischell Adrian Alonso torutek Ryan McCaffery Seika Logiciel Andrew Grant eska-gmbh Geodata AS

Sponsor this project

Learn more about GitHub Sponsors

About

Smart readmes for nuget packages

Resources

License

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors