Skip to content

Commit

Permalink
Add show-invisibles plugins ( #8 )
Browse files Browse the repository at this point in the history
  • Loading branch information
Bunlong authored Dec 17, 2022
2 parents a42f01c + ddddccf commit 97ccc89
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 4 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## 0.4.0 (2022-12-17)

### ✨ Features

* Add show-invisibles plugins

Credits

* [@Bunlong](https://github.com/Bunlong)

## 0.3.0 (2022-12-14)

### ✨ Features
Expand Down
34 changes: 32 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -788,11 +788,41 @@ export default function App() {
}
```

### Show Invisibles

Show hidden characters such as tabs and line breaks.

```javascript
import { usePrism } from 'next-prism'

// Import a theme.css
import 'next-prism/themes/tomorrow.css'

// Import show-invisibles source
import 'next-prism/plugins/show-invisibles/show-invisibles';
// Import show-invisibles.css
import 'next-prism/plugins/show-invisibles/show-invisibles.css';

export default function App() {
const { Code } = usePrism()

return (
<>
<Code language='javascript' lineNumbers={true}>
{`<div className="example">
{Math.random()}
</div>`}
</Code>
</>
)
}
```

## 📜 Changelog

Latest version 0.3.0 (2022-12-14):
Latest version 0.4.0 (2022-12-17):

* Add highlightAll() function
* Add show-invisibles plugins

Details changes for each release are documented in the [CHANGELOG.md](https://github.com/Bunlong/next-prism/blob/master/CHANGELOG.md).

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "next-prism",
"version": "0.3.1",
"version": "0.4.0",
"description": "A lightweight, robust, and elegant syntax highlighting component for your next React apps.",
"author": "Bunlong <bunlong.van@gmail.com>",
"license": "MIT",
Expand Down
40 changes: 39 additions & 1 deletion plugins/line-numbers/line-numbers.css
Original file line number Diff line number Diff line change
@@ -1 +1,39 @@
pre[class*=language-].line-numbers{position:relative;padding-left:3.8em;counter-reset:linenumber}pre[class*=language-].line-numbers>code{position:relative;white-space:inherit}.line-numbers .line-numbers-rows{position:absolute;pointer-events:none;top:0;font-size:100%;left:-3.8em;width:3em;letter-spacing:-1px;border-right:1px solid #999;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.line-numbers-rows>span{display:block;counter-increment:linenumber}.line-numbers-rows>span:before{content:counter(linenumber);color:#999;display:block;padding-right:.8em;text-align:right}
pre[class*="language-"].line-numbers {
position: relative;
padding-left: 3.8em;
counter-reset: linenumber;
}

pre[class*="language-"].line-numbers > code {
position: relative;
white-space: inherit;
}

.line-numbers .line-numbers-rows {
position: absolute;
pointer-events: none;
top: 0;
font-size: 100%;
left: -3.8em;
width: 3em; /* works for line-numbers below 1000 lines */
letter-spacing: -1px;
border-right: 1px solid #999;

-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}

.line-numbers-rows > span {
display: block;
counter-increment: linenumber;
}

.line-numbers-rows > span:before {
content: counter(linenumber);
color: #999;
display: block;
padding-right: 0.8em;
text-align: right;
}
34 changes: 34 additions & 0 deletions plugins/show-invisibles/show-invisibles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
.token.tab:not(:empty),
.token.cr,
.token.lf,
.token.space {
position: relative;
}

.token.tab:not(:empty):before,
.token.cr:before,
.token.lf:before,
.token.space:before {
color: #808080;
opacity: 0.6;
position: absolute;
}

.token.tab:not(:empty):before {
content: '\21E5';
}

.token.cr:before {
content: '\240D';
}

.token.crlf:before {
content: '\240D\240A';
}
.token.lf:before {
content: '\240A';
}

.token.space:before {
content: '\00B7';
}
83 changes: 83 additions & 0 deletions plugins/show-invisibles/show-invisibles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
(function () {

if (typeof Prism === 'undefined') {
return;
}


var invisibles = {
'tab': /\t/,
'crlf': /\r\n/,
'lf': /\n/,
'cr': /\r/,
'space': / /
};


/**
* Handles the recursive calling of `addInvisibles` for one token.
*
* @param {Object|Array} tokens The grammar or array which contains the token.
* @param {string|number} name The name or index of the token in `tokens`.
*/
function handleToken(tokens, name) {
var value = tokens[name];

var type = Prism.util.type(value);
switch (type) {
case 'RegExp':
var inside = {};
tokens[name] = {
pattern: value,
inside: inside
};
addInvisibles(inside);
break;

case 'Array':
for (var i = 0, l = value.length; i < l; i++) {
handleToken(value, i);
}
break;

default: // 'Object'
// eslint-disable-next-line no-redeclare
var inside = value.inside || (value.inside = {});
addInvisibles(inside);
break;
}
}

/**
* Recursively adds patterns to match invisible characters to the given grammar (if not added already).
*
* @param {Object} grammar
*/
function addInvisibles(grammar) {
if (!grammar || grammar['tab']) {
return;
}

// assign invisibles here to "mark" the grammar in case of self references
for (var name in invisibles) {
if (invisibles.hasOwnProperty(name)) {
grammar[name] = invisibles[name];
}
}

// eslint-disable-next-line no-redeclare
for (var name in grammar) {
if (grammar.hasOwnProperty(name) && !invisibles[name]) {
if (name === 'rest') {
addInvisibles(grammar['rest']);
} else {
handleToken(grammar, name);
}
}
}
}

Prism.hooks.add('before-highlight', function (env) {
addInvisibles(env.grammar);
});
}());
3 changes: 3 additions & 0 deletions supports/create-react-app/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { usePrism } from 'next-prism';

import 'next-prism/themes/tomorrow.css';

import 'next-prism/plugins/show-invisibles/show-invisibles.css';
import 'next-prism/plugins/show-invisibles/show-invisibles';

function App() {
const [count, setCount] = useState(0);
const { Code, highlightAll } = usePrism();
Expand Down

0 comments on commit 97ccc89

Please sign in to comment.