Skip to content

Commit

Permalink
Merge pull request #20 from florianeckerstorfer/gatsby-plugin
Browse files Browse the repository at this point in the history
Add Gatsby plugin
  • Loading branch information
florianeckerstorfer committed Mar 7, 2021
2 parents 6f8812f + 0bbcf4c commit 5967257
Show file tree
Hide file tree
Showing 13 changed files with 259 additions and 57 deletions.
26 changes: 26 additions & 0 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Integration tests

on: [push]

jobs:
test_integration:
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [12.x, 14.x, 15.x]

steps:
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
run: npm install
- name: Build project
run: npm run build
- name: Run integration tests
run: npm run test:integration
env:
CI: true
28 changes: 14 additions & 14 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
name: Test
name: Unit tests

on: [push]

jobs:
test:
test_unit:
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [10.x, 12.x, 14.x]
node-version: [10.x, 12.x, 14.x, 15.x]

steps:
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
run: npm install
- name: Run tests
run: npm test -- --coverage
env:
CI: true
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
run: npm install
- name: Run tests
run: npm test -- --coverage
env:
CI: true
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,8 @@ coverage
package-lock.json
dist
.DS_Store
gatsby-integration-test
scripts/htpasswd
scripts/storage
gatsby/index.js
.npmrc
30 changes: 24 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
# remark-a11y-emoji

[![Badge for Tests](https://github.com/florianeckerstorfer/remark-a11y-emoji/workflows/Test/badge.svg)](https://github.com/florianeckerstorfer/remark-a11y-emoji/actions?query=workflow%3A%22Test)

[![Unit tests](https://github.com/florianeckerstorfer/remark-a11y-emoji/actions/workflows/test.yml/badge.svg)](https://github.com/florianeckerstorfer/remark-a11y-emoji/actions/workflows/test.yml)
[![Integration tests](https://github.com/florianeckerstorfer/remark-a11y-emoji/actions/workflows/integration.yml/badge.svg)](https://github.com/florianeckerstorfer/remark-a11y-emoji/actions/workflows/integration.yml)

Plugin for [Remark](https://remark.js.org) to make emoji accessible. This plugin wraps emoji in a `<span>` and sets the name of the emoji as `aria-label`.

Made by 👨‍💻[Florian Eckerstorfer](https://florian.ec) in beautiful 🎡 Vienna, Europe.


## Table of Contents

1. [Installation](#installation)
Expand Down Expand Up @@ -35,9 +34,28 @@ import rehypeStringify from 'rehype-stringify';
import remarkRehype from 'remark-rehype';

const processor = remark()
.use(a11yEmoji)
.use(remarkRehype)
.use(rehypeStringify);
.use(a11yEmoji)
.use(remarkRehype)
.use(rehypeStringify);
```

## Configuration with Gatsby

```
module.exports = {
// ...
plugins: [
{
resolve: `gatsby-transformer-remark`,
options: {
plugins: [
// ...
'@fec/remark-a11y-emoji/gatsby',
],
},
},
],
};
```

# Contributing
Expand Down
47 changes: 47 additions & 0 deletions __tests__/gatsby-integration.spec.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/bin/bash

set -e

echo ">>> Clean up previous integration test run..."
sh -c "rm -rf gatsby-integration-test"
sh -c "rm -rf ./scripts/storage"

local_registry="http://localhost:4873"

echo ">>> Starting Gatsby installation..."
mkdir -p ~/.config/gatsby
echo '{ "telemetry": { "enabled": false }, "cli": { "packageManager": "npm" } }' > ~/.config/gatsby/config.json
npx gatsby new gatsby-integration-test https://github.com/gatsbyjs/gatsby-starter-blog

echo ">>> Start local registry..."
tmp_registry_log=`mktemp`
echo "Local registry output file=$tmp_registry_log"
nohup npx verdaccio --config ./scripts/verdaccio.yaml &>$tmp_registry_log &
grep -q 'http address' <(tail -f $tmp_registry_log)

echo ">>> Login to local registry and publish package..."
npx npm-auth-to-token -u test -p test -e test@test.com --registry $local_registry
npm --registry $local_registry publish

echo ">>> Install '@fec/remark-a11y-emoji' from local registry..."
cd gatsby-integration-test
npm install @fec/remark-a11y-emoji --registry $local_registry

echo ">>> Configure plugin and add emoji to a page..."
sed -i -e 's/gatsby-remark-smartypants/@fec\/remark-a11y-emoji\/gatsby/g' gatsby-config.js
echo '🎸🎤👯‍♂️' >> content/blog/hello-world/index.md

echo ">>> Build Gatsby..."
npx gatsby build

echo ">>> Check if Emoji was been converted..."
# grep guitar public/hello-world/index.html
echo "another check"
if grep -q guitar public/hello-world/index.html
then
echo "Success, emoji is wrapped with A11y information"
exit 0
else
echo "Failure, emoji is not wrapped with A11y information"
exit 1
fi
45 changes: 45 additions & 0 deletions __tests__/gatsby.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import plugin from '../src/gatsby';
import Remark from 'remark';
import visit from 'unist-util-visit';

describe('remark-a11y-emoji/gatsby', () => {
let remark;

beforeEach(() => {
remark = new Remark().data('settings', {
commonmark: true,
footnotes: true,
pedantic: true,
});
});

it('should return HTML for "🎸"', () => {
const markdownAST = remark.parse('🎸');
const result = plugin({ markdownAST });

visit(result, 'html', (node) => {
expect(node.value).toBe('<span role="img" aria-label="guitar">🎸</span>');
});
});

it('should return HTML for "foo 🎸 bar 🎧 qoo"', () => {
const markdownAST = remark.parse('foo 🎸 bar 🎧 qoo');
const result = plugin({ markdownAST });

visit(result, 'html', (node) => {
expect(node.value).toBe(
'foo <span role="img" aria-label="guitar">🎸</span> bar <span role="img" aria-label="headphone">🎧</span> qoo'
);
});
});

it('should return do nothing to other nodes', async () => {
const markdownAST = remark.parse('foo **bar**');

const transformed = await plugin({
markdownAST: Object.assign({}, markdownAST),
});

expect(transformed).toEqual(markdownAST);
});
});
4 changes: 4 additions & 0 deletions gatsby/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "@fec/gatsby-remark-a11y-emoji",
"main": "index.js"
}
11 changes: 8 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"scripts": {
"build": "rollup -c",
"test": "jest",
"test:integration": "./__tests__/gatsby-integration.spec.sh",
"prepare": "npm run build"
},
"keywords": [
Expand All @@ -24,6 +25,7 @@
"collectCoverageFrom": [
"src/**/*.js"
],
"testRegex": "/__tests__/.*\\.[jt]sx?$",
"coverageThreshold": {
"global": {
"branches": 100,
Expand All @@ -44,17 +46,20 @@
"rehype-stringify": "^8.0.0",
"remark": "^13.0.0",
"remark-rehype": "^8.0.0",
"rollup": "^2.34.0"
"rollup": "^2.34.0",
"verdaccio": "^4.11.2"
},
"dependencies": {
"emoji-regex": "^9.2.0",
"gemoji": "^6.1.0",
"mdast-util-find-and-replace": "^1.0.0"
"mdast-util-find-and-replace": "^1.0.0",
"unist-util-visit": "^2.0.3"
},
"engines": {
"node": ">=10.0"
},
"files": [
"dist"
"dist",
"gatsby"
]
}
17 changes: 9 additions & 8 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,22 @@ export default [
output: {
name: 'remarkA11yEmoji',
file: pkg.browser,
format: 'umd'
format: 'umd',
},
plugins: [
json(),
resolve(),
commonjs(),
]
plugins: [json(), resolve(), commonjs()],
},
{
input: 'src/index.js',
external: [ 'emoji-regex', 'gemoji', 'unist-util-visit' ],
external: ['emoji-regex', 'gemoji', 'mdast-util-find-and-replace'],
output: [
{ file: pkg.main, format: 'cjs', exports: 'default' },
{ file: pkg.module, format: 'esm' },
],
plugins: [ json() ],
plugins: [json()],
},
{
input: 'src/gatsby.js',
external: ['emoji-regex', 'gemoji', 'unist-util-visit'],
output: { file: 'gatsby/index.js', format: 'cjs', exports: 'default' },
},
];
31 changes: 31 additions & 0 deletions scripts/verdaccio.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
storage: ./storage

auth:
htpasswd:
file: ./htpasswd

uplinks:
npmjs:
url: https://registry.npmjs.org/
cache: true

packages:
'@fec/remark-a11y-emoji':
access: $all
publish: $all

'@*/*':
access: $all
publish: $all
proxy: npmjs

'**':
access: $all
publish: $all
proxy: npmjs

logs:
- { type: stdout, format: pretty, level: http }

server:
keepAliveTimeout: 0
18 changes: 18 additions & 0 deletions src/gatsby.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import emojiRegex from 'emoji-regex';
import visit from 'unist-util-visit';
import { getEmojiDescription } from './helper';

function a11yEmoji({ markdownAST }) {
function visitor(node) {
node.value = node.value.replace(emojiRegex(), (match) => {
node.type = 'html';
const description = getEmojiDescription(match);
return `<span role="img" aria-label="${description}">${match}</span>`;
});
}

visit(markdownAST, 'text', visitor);
return markdownAST;
}

export default a11yEmoji;
26 changes: 26 additions & 0 deletions src/helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import gemoji from 'gemoji';
import { skintoneMap, stripSkintone } from './skintone';

function emojiToName(emoji) {
return gemoji.find((item) => item.emoji === emoji);
}

export function getEmojiDescription(emoji) {
const { skintone, genericEmoji } = stripSkintone(emoji);

let info = emojiToName(genericEmoji);

if (!info) {
const appleEmoji = genericEmoji + '\uFE0F';
info = emojiToName(appleEmoji);

if (!info) {
return '';
}
}

const skintoneDescription = skintoneMap[skintone] || '';
return skintoneDescription
? `${info.description} (${skintoneDescription})`
: info.description;
}
Loading

0 comments on commit 5967257

Please sign in to comment.