Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

code-fns

Package Overview
Dependencies
Maintainers
1
Versions
29
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

code-fns - npm Package Compare versions

Comparing version 0.8.2 to 0.9.0-beta.0

184

lib/cjs/tags.js

@@ -7,3 +7,2 @@ "use strict";

exports.diff = diff;
exports.getColor = getColor;
exports.language = void 0;

@@ -14,13 +13,10 @@ exports.parse = parse;

var _starryNight = require("@wooorm/starry-night");
var _shiki = require("shiki");
var _darkStyle = _interopRequireDefault(require("./dark-style"));
let highlighter = null;
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const starryNight = (0, _starryNight.createStarryNight)(_starryNight.all);
let starryNightCache = null;
async function ready() {
starryNightCache = await starryNight;
highlighter = await (0, _shiki.getHighlighter)({
theme: 'github-dark'
});
}

@@ -45,96 +41,124 @@

const raw = integrate(reindent(code));
if (starryNightCache == null) throw new Error(`you must await ready()`);
const sn = starryNightCache;
const scope = sn.flagToScope(code.language);
if (typeof scope !== 'string') {
throw new Error(`language ${code.language} not found`);
if (highlighter == null) {
throw new Error('you must await ready() before parsing code');
}
const parsed = sn.highlight(raw, scope);
return parsed.children.map(child => colorRecurse(child, (options === null || options === void 0 ? void 0 : options.codeStyle) ?? {})).flat().map(({
color,
...rest
}) => ({ ...rest,
color: color === '' ? '#c9d1d9' : color
}));
const parsed = highlighter.codeToThemedTokens(raw, code.language);
return parsed.flatMap(line => line.concat([{
content: '\n',
explanation: [{
content: '\n',
scopes: []
}]
}])).flatMap(token => maybeReplace(token, (options === null || options === void 0 ? void 0 : options.codeStyle) ?? {})).map(themed => ({
code: themed.content,
color: themed.color || '#C9D1D9'
})).slice(0, -1);
}
const rules = new Map(Object.entries(_darkStyle.default).map(([k, v]) => [k, new Map(Object.entries(v))]));
const styleMap = new Map([['pl-s', 'stringContent'], ['pl-pds', 'stringPunctuation'], ['pl-c', 'comment'], ['pl-smi', 'variable'], ['pl-v', 'parameter'], ['pl-sr', 'regexpContent'], ['pl-c1', 'literal'], ['pl-k', 'keyword'], ['pl-en', 'entityName']]);
function getColor(scopes, codeStyle, fallback = '#C9D1D9') {
function hasScope(target) {
return scopes.some(scope => scope.scopeName.startsWith(target));
}
function getColor(classList, codeStyle) {
console.assert(classList.length <= 1, `classList too long`);
const isStringPunctuation = hasScope('punctuation.definition.string');
const isRegex = hasScope('string.regexp');
const isKeyword = hasScope('keyword');
const isString = hasScope('string');
const isVaraible = hasScope('variable');
const isParameter = hasScope('variable.parameter');
const isComment = hasScope('comment');
const isNumber = hasScope('constant.numeric');
const isBoolean = hasScope('constant.language.boolean');
const isStorageType = hasScope('storage.type');
const isEntityName = hasScope('entity.name');
if (classList.length === 1) {
const key = styleMap.get(classList[0]);
if (isRegex && !isStringPunctuation && !isKeyword) {
var _codeStyle$regexpCont, _codeStyle$regexp, _codeStyle$regexp2;
if (key != null && codeStyle[key] != null) {
var _codeStyle$key;
return ((_codeStyle$regexpCont = codeStyle.regexpContent) === null || _codeStyle$regexpCont === void 0 ? void 0 : _codeStyle$regexpCont.text) ?? ((_codeStyle$regexp = codeStyle.regexp) === null || _codeStyle$regexp === void 0 ? void 0 : _codeStyle$regexp.content) ?? ((_codeStyle$regexp2 = codeStyle.regexp) === null || _codeStyle$regexp2 === void 0 ? void 0 : _codeStyle$regexp2.text) ?? fallback;
} else if (isRegex && isStringPunctuation) {
var _codeStyle$regexp3, _codeStyle$regexp4;
return (_codeStyle$key = codeStyle[key]) === null || _codeStyle$key === void 0 ? void 0 : _codeStyle$key.text;
}
return ((_codeStyle$regexp3 = codeStyle.regexp) === null || _codeStyle$regexp3 === void 0 ? void 0 : _codeStyle$regexp3.brackets) ?? ((_codeStyle$regexp4 = codeStyle.regexp) === null || _codeStyle$regexp4 === void 0 ? void 0 : _codeStyle$regexp4.text) ?? fallback;
} else if (isRegex && isKeyword) {
var _codeStyle$regexp5, _codeStyle$regexp6;
const styles = rules.get(`.${classList[0]}`);
console.assert(((styles === null || styles === void 0 ? void 0 : styles.size) ?? 0) <= 1, `more styles than just color`);
return styles === null || styles === void 0 ? void 0 : styles.get('color');
}
return ((_codeStyle$regexp5 = codeStyle.regexp) === null || _codeStyle$regexp5 === void 0 ? void 0 : _codeStyle$regexp5.flags) ?? ((_codeStyle$regexp6 = codeStyle.regexp) === null || _codeStyle$regexp6 === void 0 ? void 0 : _codeStyle$regexp6.text) ?? fallback;
} else if (isStringPunctuation) {
var _codeStyle$stringPunc;
return undefined;
}
return ((_codeStyle$stringPunc = codeStyle.stringPunctuation) === null || _codeStyle$stringPunc === void 0 ? void 0 : _codeStyle$stringPunc.text) ?? fallback;
} else if (isString) {
var _codeStyle$stringCont;
function colorRecurse(parsed, codeStyle) {
if (parsed.type === 'text') {
return [{
code: parsed.value,
color: ''
}];
} else if (parsed.type === 'element') {
var _parsed$properties;
return ((_codeStyle$stringCont = codeStyle.stringContent) === null || _codeStyle$stringCont === void 0 ? void 0 : _codeStyle$stringCont.text) ?? fallback;
} else if (isParameter) {
var _codeStyle$parameter;
const className = (_parsed$properties = parsed.properties) === null || _parsed$properties === void 0 ? void 0 : _parsed$properties.className;
const color = getColor(className ?? [], codeStyle);
const children = parsed.children.map(child => colorRecurse(child, codeStyle));
const result = [];
return ((_codeStyle$parameter = codeStyle.parameter) === null || _codeStyle$parameter === void 0 ? void 0 : _codeStyle$parameter.text) ?? fallback;
} else if (isVaraible) {
var _codeStyle$variable;
const emit = () => {
if (temp !== '') {
if (color != '') {
result.push({
code: temp,
color
});
} else {
result.push({
code: temp,
color: ''
});
}
return ((_codeStyle$variable = codeStyle.variable) === null || _codeStyle$variable === void 0 ? void 0 : _codeStyle$variable.text) ?? fallback;
} else if (isComment) {
var _codeStyle$comment;
temp = '';
}
};
return ((_codeStyle$comment = codeStyle.comment) === null || _codeStyle$comment === void 0 ? void 0 : _codeStyle$comment.text) ?? fallback;
} else if (isNumber) {
var _codeStyle$number, _codeStyle$literal;
let temp = '';
return ((_codeStyle$number = codeStyle.number) === null || _codeStyle$number === void 0 ? void 0 : _codeStyle$number.text) ?? ((_codeStyle$literal = codeStyle.literal) === null || _codeStyle$literal === void 0 ? void 0 : _codeStyle$literal.text) ?? fallback;
} else if (isBoolean) {
var _codeStyle$boolean, _codeStyle$literal2;
for (const child of children) {
for (const item of child) {
if (item.color === '') {
temp += item.code;
} else {
emit();
result.push(item);
}
}
return ((_codeStyle$boolean = codeStyle.boolean) === null || _codeStyle$boolean === void 0 ? void 0 : _codeStyle$boolean.text) ?? ((_codeStyle$literal2 = codeStyle.literal) === null || _codeStyle$literal2 === void 0 ? void 0 : _codeStyle$literal2.text) ?? fallback;
} else if (isStorageType) {
var _codeStyle$keyword;
emit();
}
return ((_codeStyle$keyword = codeStyle.keyword) === null || _codeStyle$keyword === void 0 ? void 0 : _codeStyle$keyword.text) ?? fallback;
} else if (isEntityName) {
var _codeStyle$entityName;
emit();
return result;
return ((_codeStyle$entityName = codeStyle.entityName) === null || _codeStyle$entityName === void 0 ? void 0 : _codeStyle$entityName.text) ?? fallback;
} else {
throw new Error();
return fallback;
}
}
function maybeReplace(node, codeStyle) {
const result = [];
for (const {
content,
scopes
} of node.explanation ?? []) {
result.push({
content,
color: getColor(scopes, codeStyle, node.color)
});
}
const aggregated = [];
for (const {
content,
color
} of result) {
const last = aggregated.at(-1);
if (last == null || last.color !== color) {
aggregated.push({
content,
color
});
} else {
last.content += content;
}
}
return aggregated;
}
function toString(tokens) {

@@ -141,0 +165,0 @@ return tokens.map(token => token.code).join('');

@@ -1,7 +0,7 @@

import { createStarryNight, all } from '@wooorm/starry-night';
import style from './dark-style';
const starryNight = createStarryNight(all);
let starryNightCache = null;
import { getHighlighter } from 'shiki';
let highlighter = null;
export async function ready() {
starryNightCache = await starryNight;
highlighter = await getHighlighter({
theme: 'github-dark'
});
}

@@ -23,88 +23,98 @@ const handler = {

const raw = integrate(reindent(code));
if (starryNightCache == null) throw new Error(`you must await ready()`);
const sn = starryNightCache;
const scope = sn.flagToScope(code.language);
if (typeof scope !== 'string') {
throw new Error(`language ${code.language} not found`);
if (highlighter == null) {
throw new Error('you must await ready() before parsing code');
}
const parsed = sn.highlight(raw, scope);
return parsed.children.map(child => colorRecurse(child, options?.codeStyle ?? {})).flat().map(({
color,
...rest
}) => ({ ...rest,
color: color === '' ? '#c9d1d9' : color
}));
const parsed = highlighter.codeToThemedTokens(raw, code.language);
return parsed.flatMap(line => line.concat([{
content: '\n',
explanation: [{
content: '\n',
scopes: []
}]
}])).flatMap(token => maybeReplace(token, options?.codeStyle ?? {})).map(themed => ({
code: themed.content,
color: themed.color || '#C9D1D9'
})).slice(0, -1);
}
const rules = new Map(Object.entries(style).map(([k, v]) => [k, new Map(Object.entries(v))]));
const styleMap = new Map([['pl-s', 'stringContent'], ['pl-pds', 'stringPunctuation'], ['pl-c', 'comment'], ['pl-smi', 'variable'], ['pl-v', 'parameter'], ['pl-sr', 'regexpContent'], ['pl-c1', 'literal'], ['pl-k', 'keyword'], ['pl-en', 'entityName']]);
export function getColor(classList, codeStyle) {
console.assert(classList.length <= 1, `classList too long`);
if (classList.length === 1) {
const key = styleMap.get(classList[0]);
function getColor(scopes, codeStyle, fallback = '#C9D1D9') {
function hasScope(target) {
return scopes.some(scope => scope.scopeName.startsWith(target));
}
if (key != null && codeStyle[key] != null) {
return codeStyle[key]?.text;
}
const isStringPunctuation = hasScope('punctuation.definition.string');
const isRegex = hasScope('string.regexp');
const isKeyword = hasScope('keyword');
const isString = hasScope('string');
const isVaraible = hasScope('variable');
const isParameter = hasScope('variable.parameter');
const isComment = hasScope('comment');
const isNumber = hasScope('constant.numeric');
const isBoolean = hasScope('constant.language.boolean');
const isStorageType = hasScope('storage.type');
const isEntityName = hasScope('entity.name');
const styles = rules.get(`.${classList[0]}`);
console.assert((styles?.size ?? 0) <= 1, `more styles than just color`);
return styles?.get('color');
if (isRegex && !isStringPunctuation && !isKeyword) {
return codeStyle.regexpContent?.text ?? codeStyle.regexp?.content ?? codeStyle.regexp?.text ?? fallback;
} else if (isRegex && isStringPunctuation) {
return codeStyle.regexp?.brackets ?? codeStyle.regexp?.text ?? fallback;
} else if (isRegex && isKeyword) {
return codeStyle.regexp?.flags ?? codeStyle.regexp?.text ?? fallback;
} else if (isStringPunctuation) {
return codeStyle.stringPunctuation?.text ?? fallback;
} else if (isString) {
return codeStyle.stringContent?.text ?? fallback;
} else if (isParameter) {
return codeStyle.parameter?.text ?? fallback;
} else if (isVaraible) {
return codeStyle.variable?.text ?? fallback;
} else if (isComment) {
return codeStyle.comment?.text ?? fallback;
} else if (isNumber) {
return codeStyle.number?.text ?? codeStyle.literal?.text ?? fallback;
} else if (isBoolean) {
return codeStyle.boolean?.text ?? codeStyle.literal?.text ?? fallback;
} else if (isStorageType) {
return codeStyle.keyword?.text ?? fallback;
} else if (isEntityName) {
return codeStyle.entityName?.text ?? fallback;
} else {
return fallback;
}
return undefined;
}
function colorRecurse(parsed, codeStyle) {
if (parsed.type === 'text') {
return [{
code: parsed.value,
color: ''
}];
} else if (parsed.type === 'element') {
const className = parsed.properties?.className;
const color = getColor(className ?? [], codeStyle);
const children = parsed.children.map(child => colorRecurse(child, codeStyle));
const result = [];
function maybeReplace(node, codeStyle) {
const result = [];
const emit = () => {
if (temp !== '') {
if (color != '') {
result.push({
code: temp,
color
});
} else {
result.push({
code: temp,
color: ''
});
}
for (const {
content,
scopes
} of node.explanation ?? []) {
result.push({
content,
color: getColor(scopes, codeStyle, node.color)
});
}
temp = '';
}
};
const aggregated = [];
let temp = '';
for (const {
content,
color
} of result) {
const last = aggregated.at(-1);
for (const child of children) {
for (const item of child) {
if (item.color === '') {
temp += item.code;
} else {
emit();
result.push(item);
}
}
emit();
if (last == null || last.color !== color) {
aggregated.push({
content,
color
});
} else {
last.content += content;
}
}
emit();
return result;
} else {
throw new Error();
}
return aggregated;
}

@@ -111,0 +121,0 @@

@@ -20,5 +20,5 @@ export declare type Colors = {

/**
* The color for an erroneous token, like a mismatched bracket.
* The color for a variable
* ```ts
* (5 + 3)) // <== extra token
* const what; // "what" is a variable
* ```

@@ -42,2 +42,36 @@ */

/**
* The colors for a regular expressions
*/
regexp?: {
/**
* The colors for the whole Regular Expression literal
* ```ts
* /regex/g
* ```
*/
text?: string;
/**
* The colors for a Regular Expression's content.
* ```ts
* /regex/g // "regex" is the content
* ```
*/
content?: string;
/**
* The colors for a Regular Expression's brackets.
* ```ts
* /regex/g // "/" are the brackets
* ```
*/
brackets?: string;
/**
* The colors for a Regular Expression's falgs.
* ```ts
* /regex/g // "g" is the only flag
* ```
*/
flags?: string;
};
/**
* @deprecated Use {@link regexp} instead
* The colors for a Regular Expression's content.

@@ -50,2 +84,3 @@ * ```ts

/**
* @deprecated Use {@link number} or {@link boolean} instead
* The colors for a literal value, like "true" or "5".

@@ -58,2 +93,16 @@ * ```ts

/**
* The colors for a literal number
* ```ts
* 5
* ```
*/
number?: Colors;
/**
* The colors for a literal boolean
* ```ts
* true
* ```
*/
boolean?: Colors;
/**
* The colors for a language keyword, like `function`.

@@ -60,0 +109,0 @@ */

@@ -1,7 +0,2 @@

import type { Root } from 'hast';
import type { CodeStyle } from './style';
export interface StarryNight {
flagToScope: (flag: string) => string | undefined;
highlight: (value: string, scope: string) => Root;
}
export declare function ready(): Promise<void>;

@@ -30,3 +25,2 @@ export interface CodeTree {

}): Token[];
export declare function getColor(classList: string[], codeStyle: CodeStyle): string | undefined;
export declare function toString(tokens: Token[]): string;

@@ -33,0 +27,0 @@ export declare function diff(start: CodeTree, end: CodeTree, options?: {

{
"name": "code-fns",
"version": "0.8.2",
"version": "0.9.0-beta.0",
"description": "A library for visualizing code.",

@@ -59,3 +59,3 @@ "license": "MIT",

"dependencies": {
"@wooorm/starry-night": "^1.2.0"
"shiki": "^0.14.1"
},

@@ -62,0 +62,0 @@ "prettier": {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc