Skip to content

Commit

Permalink
Initial Release v1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
samiahmedsiddiqui committed Apr 5, 2021
1 parent c7bae39 commit 68fd8a6
Show file tree
Hide file tree
Showing 19 changed files with 575 additions and 1 deletion.
9 changes: 9 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
root = true

[*]
indent_style = space
end_of_line = lf
charset = utf-8
indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/*
29 changes: 29 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"root": true,
"env": {
"es6": true,
"node": true,
"mocha": true
},
"extends": [
"eslint:recommended"
],
"overrides": [
{
"files": [
"*.ts",
"*.tsx"
],
"parser": "@typescript-eslint/parser",
"plugins": [
"@typescript-eslint"
],
"extends": [
"plugin:@typescript-eslint/recommended"
],
"parserOptions": {
"ecmaversion": "es6"
}
}
]
}
13 changes: 13 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Set the default behavior, in case people don't have `core.autocrlf` set.
* text=auto

# Declare files that will always have LF line endings on checkout.
*.js text eol=lf

# Remove files using `git archive`.
.* export-ignore
appveyor.yml export-ignore
src export-ignore
test/title export-ignore
tsconfig.json export-ignore
types/index.test-d.ts export-ignore
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.idea
.coverage
.DS_Store
node_modules
20 changes: 20 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
branches:
only:
- main
dist: xenial
language: node_js
node_js:
- 10
- 11
- 12
- 13
- 14
- node
os:
- linux
- osx
install:
npm install --dev
script:
- npm run lint
- npm run test:title
98 changes: 97 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,97 @@
# remarkable-seo
# remarkable-seo

[![Build Status][travis-image]][travis-url]
[![NPM version][npm-image]][npm-url]
[![Downloads][downloads-image]][npm-url]

[Remarkable](https://www.npmjs.com/package/remarkable) plugin adds `title` attribute on link and image tags.

## Install

Via `npm`

```bash
npm install remarkable-seo --save-dev
```

Via `Yarn`

```bash
yarn add remarkable-seo --dev
```

## Usage

```javascript
import { Remarkable } from 'remarkable';
import remarkableSeo from 'remarkable-seo';

const md = new Remarkable();

const testString = `Add 'title' attribute on link and image where missing.
Links to test Title:
* [Example](http://example.com)
* [Google](https://google.com)
* [Facebook](https://facebook.com "Facebook page")
Attached images:
1. ![Minion](https://octodex.github.com/images/minion.png)
1. ![Manufacturetocat](https://octodex.github.com/images/manufacturetocat.png)
1. ![Stormtroopocat](https://octodex.github.com/images/stormtroopocat.jpg "The Stormtroopocat")
`;

md.use(remarkableSeo);
console.log(md.render(testString));
```

### With CommonJS

```javascript
const { Remarkable } = require('remarkable');
const remarkableSeo = require('remarkable-seo');
const md = new Remarkable();

const testString = `Add 'title' attribute on link and image where missing.
Links to test Title:
* [Example](http://example.com)
* [Google](https://google.com)
* [Facebook](https://facebook.com "Facebook page")
Attached images:
1. ![Minion](https://octodex.github.com/images/minion.png)
1. ![Manufacturetocat](https://octodex.github.com/images/manufacturetocat.png)
1. ![Stormtroopocat](https://octodex.github.com/images/stormtroopocat.jpg "The Stormtroopocat")
`;

md.use(remarkableSeo);
console.log(md.render(testString));
```

### With Docusaurus `v1`

```javascript
const remarkableSeo = require('remarkable-seo');
const siteConfig = {
...

markdownPlugins: [
function (md) {
remarkableSeo(md);
}
]

...
}
```

[npm-image]: https://img.shields.io/npm/v/remarkable-seo.svg
[npm-url]: https://www.npmjs.com/package/remarkable-seo
[downloads-image]: https://img.shields.io/npm/dt/remarkable-seo.svg
[travis-image]: https://api.travis-ci.org/trunkcode/remarkable-seo.svg?branch=main
[travis-url]: https://travis-ci.org/trunkcode/remarkable-seo
26 changes: 26 additions & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
version: "{build}"

# branches to build
branches:
only:
- main

environment:
matrix:
# node.js
- nodejs_version: "10"
- nodejs_version: "11"
- nodejs_version: "12"
- nodejs_version: "13"
- nodejs_version: "14"
- nodejs_version: ""

install:
- ps: Install-Product node $env:nodejs_version
- npm install --dev

test_script:
- npm run lint
- npm run test:title

build: off
42 changes: 42 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const remarkableSeo = (md, options) => {
const defaultOptions = {
'image': [
'title'
],
'link': [
'title'
]
};
const config = Object.assign({}, defaultOptions, options);
if (config.image && config.image.includes('title')) {
const defaultImageRender = md.renderer.rules.image;
md.renderer.rules.image = (tokens, idx, ...args) => {
tokens.map((token) => {
if (token && token.alt !== '' && token.title === '') {
token.title = token.alt;
}
});
return defaultImageRender(tokens, idx, ...args);
};
}
if (config.link && config.link.includes('title')) {
const defaultLinkRender = md.renderer.rules.link_open;
md.renderer.rules.link_open = (tokens, idx, ...args) => {
tokens.map((token) => {
if (token && token.title === '') {
const linkTextId = idx + 1;
if (tokens[linkTextId]) {
const linkContent = tokens[linkTextId];
if (linkContent.type === 'text') {
token.title = linkContent.content;
}
}
}
});
return defaultLinkRender(tokens, idx, ...args);
};
}
};
module.exports = remarkableSeo;
51 changes: 51 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"name": "remarkable-seo",
"description": "Remarkable plugin adds `title` attribute on link and image tags.",
"version": "1.0.0",
"main": "index.js",
"types": "types/index.d.ts",
"files": [
"LICENSE",
"index.js",
"test/runkitExample.js",
"types/index.d.ts"
],
"scripts": {
"build": "rm -f index.js && tsc",
"lint": "eslint .",
"lint:js": "eslint . --ext .js",
"lint:ts": "eslint . --ext .ts",
"test:title": "mocha test/title/index.test.js"
},
"repository": {
"type": "git",
"url": "https://github.com/trunkcode/remarkable-seo.git"
},
"keywords": [
"remarkable",
"plugin",
"seo",
"Image Title",
"Link Title",
"docusaurus",
"search engine optimization"
],
"author": "TrunkCode <[email protected]>",
"license": "MIT",
"bugs": {
"url": "https://github.com/trunkcode/remarkable-seo/issues"
},
"homepage": "https://github.com/trunkcode/remarkable-seo#readme",
"runkitExampleFilename": "test/runkitExample.js",
"devDependencies": {
"@types/node": "^14.14.37",
"@types/remarkable": "^2.0.1",
"@typescript-eslint/eslint-plugin": "^4.20.0",
"@typescript-eslint/parser": "^4.20.0",
"eslint": "^7.15.0",
"mocha": "^8.3.2",
"remarkable": "^2.0.1",
"tsd": "^0.14.0",
"typescript": "^4.2.3"
}
}
58 changes: 58 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import * as types from '../types/index.d';
import { Remarkable } from 'remarkable';

/**
* Register as a plugin by passing `remarkableSeo` to remarkable's `.use()`
* method.
* @param md
* @param options
*/
const remarkableSeo = (md: Remarkable, options?: types.configOptions): void => {
// Remarkable.
const defaultOptions: types.defaultOptions = {
'image': [
'title'
],
'link': [
'title'
]
};
const config = Object.assign({}, defaultOptions, options);

if (config.image && config.image.includes('title')) {
const defaultImageRender = md.renderer.rules.image;

md.renderer.rules.image = (tokens: Remarkable.ImageToken[], idx: number, ...args: []) => {
tokens.map((token: Remarkable.ImageToken) => {
if (token && token.alt !== '' && token.title === '') {
token.title = token.alt;
}
});

return defaultImageRender(tokens, idx, ...args);
};
}

if (config.link && config.link.includes('title')) {
const defaultLinkRender = md.renderer.rules.link_open;

// eslint-disable-next-line camelcase
md.renderer.rules.link_open = (tokens: Remarkable.LinkOpenToken[], idx: number, ...args: []) => {
tokens.map((token: Remarkable.LinkOpenToken) => {
if (token && token.title === '') {
const linkTextId = idx + 1;
if (tokens[linkTextId]) {
const linkContent: Remarkable.ContentToken = tokens[linkTextId];
if (linkContent.type === 'text') {
token.title = linkContent.content;
}
}
}
});

return defaultLinkRender(tokens, idx, ...args);
};
}
}

module.exports = remarkableSeo;
24 changes: 24 additions & 0 deletions test/runkitExample.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use strict';

const { Remarkable } = require('remarkable');
const remarkableSeo = require('remarkable-seo');
const md = new Remarkable();

const testString = `Add 'title' attribute on link and image where missing.
Links to test Title:
* [Example](http://example.com)
* [Google](https://google.com)
* [Facebook](https://facebook.com "Facebook page")
Attached images:
1. ![Minion](https://octodex.github.com/images/minion.png)
1. ![Manufacturetocat](https://octodex.github.com/images/manufacturetocat.png)
1. ![Stormtroopocat](https://octodex.github.com/images/stormtroopocat.jpg "The Stormtroopocat")
`;

md.use(remarkableSeo);

console.log(md.render(testString));
Loading

0 comments on commit 68fd8a6

Please sign in to comment.