Skip to content

Handles image references involved in markdown files during the webpack processing.

License

Notifications You must be signed in to change notification settings

lucsorel/markdown-image-loader

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Markdown logo Webpack logo

Markdown image loader

Handles image references involved in markdown files during the webpack processing.

Highly inspired from the Webpack: A simple loader article by Michael "Z" Goddard, rewritten with some ES6 flavor, use-case documentation and unit testing.

Additions:

  • the loader does not impact references to online images (eg: image path starting with http://, https:// or //)
  • the loader handles markdown image references with a title

Installation

Install the markdown-image-loader along other webpack development dependencies:

# via yarn
yarn add -D webpack file-loader markdown-image-loader

# via npm
npm i -D webpack file-loader markdown-image-loader

How it works

In the webpack process, this loader extracts image references of markdown documents with a regular expression, then converts them into image file requirements so that the file-loader can process them in your build chain.

Use cases

Web-based slideshows

This loader was originally designed to quickly setup web-based slideshows using markdown to build the content, webpack to produce the static files and webpack-dev-server to display the slideshow with live-reload, which can be interesting when editing the content while interacting with the audience.

Two full setups are given in the examples/ folder of this repository:

Both slideshow examples share the same philosophy, adapted to the technical choices of each framework:

The folder structure of such projects is:

dist // folder containing the static files generated by the webpack build (and served by webpack-dev-server)
src
┣ index.html
┣ [your slideshow app name]-slideshow.js
┣ slideshow.md
┣ slides.css // your personal style additions
┣ fonts // folder containing the fonts required in the slides.css file, if any
┣ img // folder containing the images referenced in slideshow.md
┃ ┗ markdown-logo.svg, webpack-logo.svg, etc.
webpack.config.js // involves this markdown-image-loader and the file-loader
package.json // devDependencies to make the slideshow framework and webpack work together
  • src/index.html:
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <!-- the title header can be dynamically set by bundled-app.js -->
    <title>My slideshow</title>
  </head>
  <body>
    <!-- RemarkJS expects the markdown content to be included by the webapp this way -->
    <textarea id="source" style="display: none"></textarea>
    <!-- RevealJS expects the markdown content to be included by the webapp this way -->
    <div class="reveal">
      <div class="slides">
        <!-- horizontal and vertical separators are my choices, tune them as you want -->
        <section data-markdown data-separator="^---" data-separator-vertical="^--">
          <textarea id="source" data-template></textarea>
        </section>
      </div>
    </div>

    <!-- the bundled webapp will be injected here by the html-webpack-plugin -->
  </body>
</html>
  • src/[slideshow app name]-slideshow.js:
// customize your CSS here
require('./slides.css')

// loads the markdown content with the markdown-image-loader (which processes its image references)
document.getElementById('source').innerHTML = require('./slideshow.md')

// starts the slideshow with a specific configuration object
remark.create({ ... })
// or
Reveal.initialize({ ... })
  • src/slideshow.md (each slideshow engine has its specific syntax, see the slideshow.md files in the examples):
# Slide 1 with a jpg reference

![test1](img/test1.jpg)

---

# Slide 2 with an inline png reference

In line ![test2](img/test2.png) image reference.
  • webpack.config.js. Loaders defined in the module.rules section are called from bottom to top: the file-loader must be called after the markdown-image-loader produces new file requirements: :
const path = require('path')

module.exports = {
  entry: path.join(__dirname, 'src', '[slideshow app name]-slideshow.js'),
  output: {
    filename: 'bundled-app.js',
    path: path.join(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        test: /\.(svg|png|jpg|gif)$/,
        use: [
          {
            loader: 'file-loader',
            options: {} // produces {hash}.[ext] files by default
          }
        ]
      },
      {
        test: /\.(md|markdown)$/,
        use: 'markdown-image-loader'
      }
    ]
  }
}

Use the file-loader options to customize the way image files must be handled (file naming, output path, url prefix, etc.).

  • package.json. Use the scripts.build to produce the static files ready to be served in production, for which you must include these mandatory dependencies in your project: webpack, file-loader and markdown-image-loader. You can optionally include the webpack-dev-server to serve your slideshow with live-reload with the scripts.start command.
{
  "scripts": {
    "build": "rm -rf dist && webpack",
    "start": "webpack-dev-server",
    "lint": "standard"
  },
  "devDependencies": {
    "file-loader": "...",
    "markdown-image-loader": "...",
    "webpack": "...",
    "webpack-dev-server": "..."
  },
}

The outputs generated in the dist folder will be:

  • the bundled-app.js file, handling the markdown content as follows:
// ...
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
module.exports = [
"# Slide 1 with a jpg reference\n\n",
"![test1](" + __webpack_require__(1) + ")",
"\n\n---\n\n# Slide 2 with an inline png reference\n\nIn line ",
"![test2](" + __webpack_require__(2) + ")",
" image reference.\n"
]
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__.p + "05bf210f71dda8913b3e9ac296da171f.jpg";
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__.p + "e3989c3353cceb13f5bb1ecf343f22a6.png";
/***/ })
  • the images referenced by the markdown content, processed by the file-loader plugin:
    • the dist/05bf210f71dda8913b3e9ac296da171f.jpg file (referenced in slide 1)
    • the dist/e3989c3353cceb13f5bb1ecf343f22a6.png file (referenced in slide 2)

Unit tests

Unit tests can be run with the npm test command.

Despite these efforts, should you find an issue or spot a vital feature, you are welcome to report bugs and submit code requests!

Change log

  • 3.0.1: [config] loader-utils is a production depndency, not a dev dependency; upgraded version of eslint and mocha
  • 3.0.0: [config] dependencies update, for webpack 5.x
  • 2.0.1: [config] dependencies update, [doc] reference to the file loader options for image file customization
  • 2.0.0: [config] dependencies update, for webpack 3.x and 4.x. Webpack configurations for RemarkJS and RevealJS slideshows in the /examples folder have been updated for Webpack 4.x support
  • 1.0.5: [feature] the loader handles image references with an optional title
  • 1.0.4: [doc] added sample slideshows for RemarkJS and RevealJS in the /examples folder
  • 1.0.3: [perf] made the loader outputs cacheable, [doc] added this change log section
  • 1.0.2: [fix] removed the comma surrounding image requirements in the exported module content
  • 1.0.1: [fix] the loader should not not require URLed-image references
  • 1.0.0: initial release with unit-tests and documentation, for webpack 3.x

Contributions

Pull-requests are welcome and will be processed on a best-effort basis.

License

Unless stated otherwise all works are licensed under the MIT license, a copy of which is included here.

Copyright (c) 2017-2024 Luc Sorel-Giffo

About

Handles image references involved in markdown files during the webpack processing.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •