npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

markdown-table-embed

v1.0.0

Published

Utility for embedding markdown tables in other markdown documents

Downloads

1

Readme

EmbedMe

Simple utility to embed source files into markdown code blocks why tho?

npm version Build Status Commitizen friendly

Demo

Usage

With a README.md in your current working directory, add a code block for one of the supported file types and start the code block simply with a comment with the path to a file. For example

This is a *markdown* document with a code block:

```ts
// example.ts
```

Next, run the following

npx embedme README.md

Et voilà! Your README.md file will be updated with the content of your source file:

This is a *markdown* document with a code block:

```ts
// example.ts

export function helloWorld(name: string): string {
  return `Hello ${name}!, how are you today?`;
}

```

As the comment is preserved, you can happily re-run embedme and it will run again but there will be no changes.

Features

$ embedme --help
Usage: embedme [options] [...files]

Options:
  -V, --version              output the version number
  --verify                   Verify that running embedme would result in no
                             changes. Useful for CI
  --dry-run                  Run embedme as usual, but don't write
  --source-root [directory]  Directory your source files live in in order to
                             shorten the comment line in code fence
  --silent                   No console output
  --stdout                   Output resulting file to stdout (don't rewrite
                             original)
  --strip-embed-comment      Remove the comments from the code fence. *Must* be
                             run with --stdout flag
  -h, --help                 display help for command

Partial Snippets

Very often you only want to highlight a small part of a file, to do so simply suffix the filename with the GitHub line number syntax, e.g. path/to/my/file.ts#L20-L30.

Multi Language

embedme simply uses the file type hint in a code fence to choose a strategy for finding the commented filename in the first line of the code block. This is a relatively trivial regular expression, so many more languages can be supported in future

Here's a list of file types supported by this utility, if you have a need for another language please feel free to contribute, it is easy!

// src/embedme.lib.ts#L44-L82


  const match = line.match(regex);
  if (!match) {
    return null;
  }
  console.log('>> leadingSymbol END', match);
  return match[1];
};

const filetypeCommentReaders: Record<CommentFamily, FilenameFromCommentReader> = {
  [CommentFamily.NONE]: _ => null,
  [CommentFamily.C]: leadingSymbol('//'),
  [CommentFamily.XML]: line => {
    const match = line.match(/<!--\s*?(\S*?)\s*?-->/);
    if (!match) {
      return null;
    }

    return match[1];
  },
  [CommentFamily.HASH]: leadingSymbol('#'),
  [CommentFamily.SINGLE_QUOTE]: leadingSymbol(`'`),
  [CommentFamily.DOUBLE_PERCENT]: leadingSymbol('%%'),
  [CommentFamily.DOUBLE_HYPHENS]: leadingSymbol('--'),
};

function lookupLanguageCommentFamily(fileType: SupportedFileType): CommentFamily | null {
  console.log('>> lookupLanguageCommentFamily START');
  return Object.values(CommentFamily)
  .filter(x => typeof x === 'number')
  .find((commentFamily: CommentFamily) => languageMap[commentFamily].includes(fileType));
}

// this somewhat convoluted type to generate logs is due to the requirement to be able to log colours to both stdout,
// and stderr, so the appropriate chalk instance has to be injected.
type LogConstructor = (chalk: Chalk) => string;

export const logBuilder = (options: EmbedmeOptions, errorLog = false) => (logConstructor: LogConstructor) => {
  // console.log('>> logBuilder START');

Alternate embedding syntax

It is recommended to use the syntax described above as it is a good hint for readers and maintainers where the source of this file is, however in some situations you may want to omit the comment in the code block, but still benefit from the embedding behaviour of embedme.

This can be achieved by preceding the code block with a markdown comment in the form of <!-- embedme path/to/your/file.txt -->

For example:

<!-- embedme example.ts -->
This is a *markdown* document with a code block:

```ts
```

Will result in the following output

<!-- embedme example.ts -->
This is a *markdown* document with a code block:

```ts
export function helloWorld(name: string): string {
  return `Hello ${name}!, how are you today?`;
}

```

Glob matching

If you want to run embedme over multiple files, you can use glob matching, i.e.

embedme "src/**/*.md"

Note embedme supports both quoted globbing and unquoted. Be careful using unquoted globbing as this can lead to behaviour that is not portable between different operating systems.

If you're using Windows, you must use forward slashes (/) to denote path separators.

You can also pass multiple separate glob patterns to match multiple sets of files

example:

embedme "src/**/*.md" "docs/**/*.markdown"

CI Checks

If you're using continuous integration, you can pass the flag --verify to embedme to check that there are no changes expected to your files. This is useful for repositories with multiple contributors who may not know about embedme, and also for yourself as a sanity check that you remembered to run it after updating sample code!

Output to stdout

Don't want to rewrite the file in-place? That's ok too - you can pass the flag --stdout to have the output pass to stdout - this will allow you to redirect the output to another file.

Additionally, in this mode a --strip-embed-comment flag is available, which allows embedme to exclude the matched comment from the output. This isn't generally recommended as the comment is generally unobtrusive, and will really help maintainers to know where they should go to update the file.

Example

# readme/output-to-std-out.sh

embedme --stdout README.template.md > README.md

Note that with --stdout flag the log output from embedme is redirected to stderr so you can still see the logs but the output can be redirected.

Ignoring files

By default embedme uses the local .gitignore file to exclude any files that match your input but are ignored. You can customise this ignore behavior by creating a .embedmeignore file, which uses the same syntax as .gitignore. This file will be used instead of .gitignore, not merged.

Why?

Why do I want this utility? Writing code in a markdown document is not difficult?

True, however it is difficult to know when your documentation files become out of date - if you're introducing a breaking change, having your example code actually using your library guarantees it will be correct.

How can just having my examples in the language give me guarantees?

For starters if you're using a typesafe language (e.g. Typescript) you will get compiler errors, and secondarily you really should be writing unit tests on your example code. As simple as it might be, how embarrassing is it if your example doesn't even work?!