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

remark-file-attachment

v1.0.4

Published

Remark plugin to embed files in markdown, as more than just a link.

Downloads

9

Readme

Remark File Attachment Plugin

Build

This is a plugin for Remark, and allows you to embed file attachments in markdown files. The plugin offers the ability to style the file attachments, so that they look like more than a simple link, and arguably it offers better accessability as well. This plugin can also be used with Gridsome.

Installation

npm i remark-file-attachment --save-dev
# yarn add remark-file-attachment --dev

Configuration

Structure

You can configure the HTML element type to be used for the attachment container and the attachment item.

  1. Attachment container (default ul)
    containerElement: "ul",
  2. Attachment item (default li)
    containerElement: "li",

Styling

You can provide css and styles for just about all of the attachment's HTML elements.

  1. Attachment container (default ul)

    containerCss: "border border-gray-200 rounded-md divide-y divide-gray-200 max-w-lg mb-3",
    containerStyle: "list-style: none !important; margin-top: 0 !important; margin-bottom: 0 !important;",
  2. Attachment item (default li)

    itemCss: "pr-4 py-3 flex items-center justify-between text-sm text-gray-400 focus-within:text-blue-600",
    itemStyle: "content: none; position: static !important; margin-top: 0 !important; margin-bottom: 0 !important; padding-left: 0.75rem !important;",
  3. Icon and paragraph container (div)

    iconAndParagraphContainerCss: "flex items-center max-w-32 md:max-w-max pr-4",
  4. Paragraph (span)

    paragraphCss: "ml-2 truncate text-gray-800 max-w-xs",
  5. Link container (div)

    linkContainerCss: "ml-3 inline-flex space-x-4",
  6. Show link (a)

    showLinkCss: "font-medium text-blue-600 hover:text-blue-500 outline-none focus:underline",
    showLinkStyle: "text-decoration: none;",
  7. Download link (a)

    downloadLinkCss: "font-medium text-blue-600 hover:text-blue-500 outline-none focus:underline",
    downloadLinkStyle: "text-decoration: none;",

Icon

You can provide HTML for an icon next to the attachment name (paragraph).

Example:

iconHTML: `
    <svg focusable="false" aria-hidden="true" class="flex-shrink-0 h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
        <path fill-rule="evenodd" d="M8 4a3 3 0 00-3 3v4a5 5 0 0010 0V7a1 1 0 112 0v4a7 7 0 11-14 0V7a5 5 0 0110 0v4a3 3 0 11-6 0V7a1 1 0 012 0v4a1 1 0 102 0V7a3 3 0 00-3-3z" clip-rule="evenodd" />
    </svg>
`,

Alignment

If you want alignment to work, you'll have to supply css classes.

There's three options:

  • cssClassToCenterPlaceholder

    Example value w-full flex justify-center

  • cssClassToLeftAlignPlaceholder

    Example value w-full flex justify-start

  • cssClassToRightAlignPlaceholder

    Example value w-full flex justify-end

Note: You can also add extra css, like bottom margin, to space things out nicely.

Link text & alt text

You can provide text to use for the "Show" and "Download" link, so thay they fit with the locale of the webiste.

showLinkText: "Show",
showLinkAltSuffix: "in new tab",

// The alt text of the show link will be showLinkText + " " + attachment text attribute + showLinkAltSuffix.
// Show Document 1.pdf in new tab

downloadLinkText: "Download",

// The alt text of the download link will be downloadLinkText + " " + attachment text attribute.
// Download Document 1.pdf

Remark configuration:

  const remark = require("remark");
  const fileAttachment = require("remark-file-attachment");

  const processor = remark().use(fileAttachment, {
    cssClassToCenter: "w-full flex justify-center",
    cssClassToLeftAlign: "w-full flex justify-start",
    cssClassToRightAlign: "w-full flex justify-end",

    containerElement: "ul",
    containerCss: "border border-gray-200 rounded-md divide-y divide-gray-200 max-w-lg mb-3",
    containerStyle: "list-style: none !important; margin-top: 0 !important; margin-bottom: 0 !important;",
    itemElement: "li",
    itemCss: "pr-4 py-3 flex items-center justify-between text-sm text-gray-400 focus-within:text-blue-600",
    itemStyle: "content: none; position: static !important; margin-top: 0 !important; margin-bottom: 0 !important; padding-left: 0.75rem !important;",

    iconHTML: `
        <svg focusable="false" aria-hidden="true" class="flex-shrink-0 h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
            <path fill-rule="evenodd" d="M8 4a3 3 0 00-3 3v4a5 5 0 0010 0V7a1 1 0 112 0v4a7 7 0 11-14 0V7a5 5 0 0110 0v4a3 3 0 11-6 0V7a1 1 0 012 0v4a1 1 0 102 0V7a3 3 0 00-3-3z" clip-rule="evenodd" />
        </svg>
    `,
    paragraphCss: "ml-2 truncate text-gray-800 max-w-xs",
    iconAndParagraphContainerCss: "flex items-center max-w-32 md:max-w-max pr-4",

    linkContainerCss: "ml-3 inline-flex space-x-4",

    showLinkText: "Show",
    showLinkAltTextSuffix: "in new tab",
    showLinkCss: "font-medium text-blue-600 hover:text-blue-500 outline-none focus:underline",

    downloadLinkText: "Download",
    downloadLinkCss: "font-medium text-blue-600 hover:text-blue-500 outline-none focus:underline",
    downloadLinkStyle: "text-decoration: none;",
  });

Gridsome configuration:

module.exports = {
  plugins: [
    {
      use: "@gridsome/source-filesystem",
      options: {
        path: "blog/**/*.md",
        route: "/blog/:year/:month/:day/:slug",
        remark: {
          plugins: [
            [
              "remark-file-attachment",
              {
                cssClassToCenter: "w-full flex justify-center",
                cssClassToLeftAlign: "w-full flex justify-start",
                cssClassToRightAlign: "w-full flex justify-end",

                containerElement: "ul",
                containerCss: "border border-gray-200 rounded-md divide-y divide-gray-200 max-w-lg mb-3",
                containerStyle: "list-style: none !important; margin-top: 0 !important; margin-bottom: 0 !important;",
                itemElement: "li",
                itemCss: "pr-4 py-3 flex items-center justify-between text-sm text-gray-400 focus-within:text-blue-600",
                itemStyle: "content: none; position: static !important; margin-top: 0 !important; margin-bottom: 0 !important; padding-left: 0.75rem !important;",

                iconHTML: `
                    <svg focusable="false" aria-hidden="true" class="flex-shrink-0 h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
                        <path fill-rule="evenodd" d="M8 4a3 3 0 00-3 3v4a5 5 0 0010 0V7a1 1 0 112 0v4a7 7 0 11-14 0V7a5 5 0 0110 0v4a3 3 0 11-6 0V7a1 1 0 012 0v4a1 1 0 102 0V7a3 3 0 00-3-3z" clip-rule="evenodd" />
                    </svg>
                `,
                paragraphCss: "ml-2 truncate text-gray-800 max-w-xs",
                iconAndParagraphContainerCss: "flex items-center max-w-32 md:max-w-max pr-4",

                linkContainerCss: "ml-3 inline-flex space-x-4",

                showLinkText: "Show",
                showLinkAltTextSuffix: "in new tab",
                showLinkCss: "font-medium text-blue-600 hover:text-blue-500 outline-none focus:underline",

                downloadLinkText: "Download",
                downloadLinkCss: "font-medium text-blue-600 hover:text-blue-500 outline-none focus:underline",
                downloadLinkStyle: "text-decoration: none;",
              },
            ]
          ]
        }
      }
    }
  ]
}

Usage in markdown

The markdown must consist of all the possible attributes (attachment, text & placement), and you must enclose the markdown in backticks (`).

Format:

`attachment [FILE_LINK] text [TEXT] placement [Left|Center|Right]`

Examples:

`attachment /uploads/salesoverview.pdf text Sales overview report placement Left end`

or

`attachment /uploads/salesoverview.pdf text Sales overview report placement Left end attachment /uploads/purchaseoverview.pdf text Purchase overview report placement Left end`

Output

Attachment/s

This is how the attachment/s can appear on the screen:

Generated HTML

<div class="w-full flex justify-start">
  <ul class="border border-gray-200 rounded-md divide-y divide-gray-200 max-w-lg mb-3" style="list-style: none !important; margin-top: 0 !important; margin-bottom: 0 !important;">
    <li class="pr-4 py-3 flex items-center justify-between text-sm text-gray-400 focus-within:text-blue-600" style="content: none; position: static !important; margin-top: 0 !important; margin-bottom: 0 !important; padding-left: 0.75rem !important;">
      <div class="flex items-center max-w-32 md:max-w-max pr-4" style="">
        <svg focusable="false" aria-hidden="true" class="flex-shrink-0 h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M8 4a3 3 0 00-3 3v4a5 5 0 0010 0V7a1 1 0 112 0v4a7 7 0 11-14 0V7a5 5 0 0110 0v4a3 3 0 11-6 0V7a1 1 0 012 0v4a1 1 0 102 0V7a3 3 0 00-3-3z" clip-rule="evenodd"></path></svg>
        
        <span class="ml-2 truncate text-gray-800 max-w-xs" style="">Sales overview report</span>
      </div>

      <div class="ml-3 inline-flex space-x-4" style="">
        <a href="/uploads/salesoverview-report.pdf" target="_blank" rel="noopener noreferrer" aria-label="Show attachment in new tab" class="font-medium text-blue-600 hover:text-blue-500 outline-none focus:underline">Show</a>
        
        <a href="/uploads/salesoverview-report.pdf" download="" aria-label="Download attachment" class="font-medium text-blue-600 hover:text-blue-500 outline-none focus:underline">Download</a>
      </div>
    </li>

    <li class="pr-4 py-3 flex items-center justify-between text-sm text-gray-400 focus-within:text-blue-600" style="content: none; position: static !important; margin-top: 0 !important; margin-bottom: 0 !important; padding-left: 0.75rem !important;">
      <div class="flex items-center max-w-32 md:max-w-max pr-4" style="">
        <svg focusable="false" aria-hidden="true" class="flex-shrink-0 h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M8 4a3 3 0 00-3 3v4a5 5 0 0010 0V7a1 1 0 112 0v4a7 7 0 11-14 0V7a5 5 0 0110 0v4a3 3 0 11-6 0V7a1 1 0 012 0v4a1 1 0 102 0V7a3 3 0 00-3-3z" clip-rule="evenodd"></path></svg>
        
        <span class="ml-2 truncate text-gray-800 max-w-xs" style="" title="Purchase overview report">Purchase overview report</span>
      </div>
      
      <div class="ml-3 inline-flex space-x-4" style="">
        <a href="/uploads/purchaseoverview-report.pdf" target="_blank" rel="noopener noreferrer" aria-label="Show Purchase overview report in new tab" class="font-medium text-blue-600 hover:text-blue-500 outline-none focus:underline">Show</a>
        
        <a href="/uploads/purchaseoverview-report.pdf" download="" aria-label="Download Purchase overview report" class="font-medium text-blue-600 hover:text-blue-500 outline-none focus:underline">Download</a>
      </div>
    </li>
  </ul>
</div>

Errors

When the plugin detects errors, i.e. an incorrectly formatted attachment element, it will render a red fat error instead of the attachment.

License

MIT