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.9.0 to 0.10.0

lib/types/dark-style.d.ts

261

lib/cjs/tags.js

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

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

@@ -13,22 +14,15 @@ exports.parse = parse;

var _shiki = require("shiki");
var _starryNight = require("@wooorm/starry-night");
(0, _shiki.setCDN)('https://esm.sh/shiki@latest/');
let highlighter = null;
var _darkStyle = _interopRequireDefault(require("./dark-style"));
async function ready(options) {
if (highlighter == null) {
highlighter = await (0, _shiki.getHighlighter)({
themes: ['github-dark'].concat((options === null || options === void 0 ? void 0 : options.themes) ?? []),
langs: (options === null || options === void 0 ? void 0 : options.languages) ?? []
});
} else {
for (const language of (options === null || options === void 0 ? void 0 : options.languages) ?? []) {
await highlighter.loadLanguage(language);
}
var _wcwidth = _interopRequireDefault(require("wcwidth"));
for (const theme of (options === null || options === void 0 ? void 0 : options.themes) ?? []) {
await highlighter.loadTheme(theme);
}
}
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;
}

@@ -53,122 +47,164 @@

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 (highlighter == null) {
throw new Error('you must await ready() before parsing code');
if (typeof scope !== 'string') {
throw new Error(`language ${code.language} not found`);
}
const parsed = highlighter.codeToThemedTokens(raw, code.language, (options === null || options === void 0 ? void 0 : options.theme) ?? 'github-dark');
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 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
}));
}
function getColor(scopes, codeStyle, fallback = '#C9D1D9') {
function hasScope(target) {
return scopes.some(scope => scope.scopeName.startsWith(target));
}
const rules = new Map(Object.entries(_darkStyle.default).map(([k, v]) => [k, new Map(Object.entries(v))]));
const styleMap = [[['pl-s'], s => {
var _s$stringContent;
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');
return (_s$stringContent = s.stringContent) === null || _s$stringContent === void 0 ? void 0 : _s$stringContent.text;
}], [['pl-s', 'pl-pds'], s => {
var _s$stringPunctuation;
if (isRegex && !isStringPunctuation && !isKeyword) {
var _codeStyle$regexpCont, _codeStyle$regexp, _codeStyle$regexp2;
return (_s$stringPunctuation = s.stringPunctuation) === null || _s$stringPunctuation === void 0 ? void 0 : _s$stringPunctuation.text;
}], [['pl-c'], s => {
var _s$comment;
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 (_s$comment = s.comment) === null || _s$comment === void 0 ? void 0 : _s$comment.text;
}], [['pl-smi'], s => {
var _s$variable;
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;
return (_s$variable = s.variable) === null || _s$variable === void 0 ? void 0 : _s$variable.text;
}], [['pl-v'], s => {
var _s$parameter;
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 (_s$parameter = s.parameter) === null || _s$parameter === void 0 ? void 0 : _s$parameter.text;
}], [['pl-s', 'pl-sr'], s => {
var _s$regexp, _s$regexp2;
return ((_codeStyle$stringPunc = codeStyle.stringPunctuation) === null || _codeStyle$stringPunc === void 0 ? void 0 : _codeStyle$stringPunc.text) ?? fallback;
} else if (isString) {
var _codeStyle$stringCont;
return ((_s$regexp = s.regexp) === null || _s$regexp === void 0 ? void 0 : _s$regexp.content) ?? ((_s$regexp2 = s.regexp) === null || _s$regexp2 === void 0 ? void 0 : _s$regexp2.text);
}], [['pl-s', 'pl-sr', 'pl-pds'], s => {
var _s$regexp3, _s$regexp4;
return ((_codeStyle$stringCont = codeStyle.stringContent) === null || _codeStyle$stringCont === void 0 ? void 0 : _codeStyle$stringCont.text) ?? fallback;
} else if (isParameter) {
var _codeStyle$parameter;
return ((_s$regexp3 = s.regexp) === null || _s$regexp3 === void 0 ? void 0 : _s$regexp3.brackets) ?? ((_s$regexp4 = s.regexp) === null || _s$regexp4 === void 0 ? void 0 : _s$regexp4.text);
}], [['pl-s', 'pl-sr', 'pl-k'], s => {
var _s$regexp5, _s$regexp6;
return ((_codeStyle$parameter = codeStyle.parameter) === null || _codeStyle$parameter === void 0 ? void 0 : _codeStyle$parameter.text) ?? fallback;
} else if (isVaraible) {
var _codeStyle$variable;
return ((_s$regexp5 = s.regexp) === null || _s$regexp5 === void 0 ? void 0 : _s$regexp5.flags) ?? ((_s$regexp6 = s.regexp) === null || _s$regexp6 === void 0 ? void 0 : _s$regexp6.text);
}], [['pl-c1'], s => {
var _s$literal;
return ((_codeStyle$variable = codeStyle.variable) === null || _codeStyle$variable === void 0 ? void 0 : _codeStyle$variable.text) ?? fallback;
} else if (isComment) {
var _codeStyle$comment;
return (_s$literal = s.literal) === null || _s$literal === void 0 ? void 0 : _s$literal.text;
}], [['pl-k'], s => {
var _s$keyword;
return ((_codeStyle$comment = codeStyle.comment) === null || _codeStyle$comment === void 0 ? void 0 : _codeStyle$comment.text) ?? fallback;
} else if (isNumber) {
var _codeStyle$number, _codeStyle$literal;
return (_s$keyword = s.keyword) === null || _s$keyword === void 0 ? void 0 : _s$keyword.text;
}], [['pl-en'], s => {
var _s$entityName;
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;
return (_s$entityName = s.entityName) === null || _s$entityName === void 0 ? void 0 : _s$entityName.text;
}]];
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;
function findAssociated(styleMap, target, notFound) {
let best = notFound;
let specificity = 0;
return ((_codeStyle$keyword = codeStyle.keyword) === null || _codeStyle$keyword === void 0 ? void 0 : _codeStyle$keyword.text) ?? fallback;
} else if (isEntityName) {
var _codeStyle$entityName;
for (const [keys, value] of styleMap) {
if (keys.length <= specificity) {
continue;
}
return ((_codeStyle$entityName = codeStyle.entityName) === null || _codeStyle$entityName === void 0 ? void 0 : _codeStyle$entityName.text) ?? fallback;
} else {
return fallback;
let keyIndex = 0;
let targetIndex = 0;
while (targetIndex < target.length && keyIndex < keys.length) {
const key = keys[keyIndex];
const targetKey = target[targetIndex];
if (targetKey === key) {
keyIndex++;
}
targetIndex++;
}
if (keyIndex === keys.length) {
// all keys found
best = value;
specificity = keys.length;
}
}
return best;
}
function maybeReplace(node, codeStyle) {
const result = [];
function getColor(classList, codeStyle) {
const fn = findAssociated(styleMap, classList, () => undefined);
const result = fn(codeStyle);
for (const {
content,
scopes
} of node.explanation ?? []) {
result.push({
content,
color: getColor(scopes, codeStyle, node.color)
});
if (result != null) {
return result;
}
const aggregated = [];
const styles = rules.get(`.${classList.at(-1)}`);
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');
}
for (const {
content,
color
} of result) {
const last = aggregated.at(-1);
function colorRecurse(parsed, codeStyle, classList = []) {
if (parsed.type === 'text') {
return [{
code: parsed.value,
color: ''
}];
} else if (parsed.type === 'element') {
var _parsed$properties;
if (last == null || last.color !== color) {
aggregated.push({
content,
color
});
} else {
last.content += content;
const className = ((_parsed$properties = parsed.properties) === null || _parsed$properties === void 0 ? void 0 : _parsed$properties.className) ?? [];
const color = getColor(classList.concat(className), codeStyle);
const children = parsed.children.map(child => colorRecurse(child, codeStyle, classList.concat(className)));
const result = [];
const emit = () => {
if (temp !== '') {
if (color != '') {
result.push({
code: temp,
color
});
} else {
result.push({
code: temp,
color: ''
});
}
temp = '';
}
};
let temp = '';
for (const child of children) {
for (const item of child) {
if (item.color === '') {
temp += item.code;
} else {
emit();
result.push(item);
}
}
emit();
}
emit();
return result;
} else {
throw new Error();
}
return aggregated;
}

@@ -406,4 +442,9 @@

} else {
if (morph !== 'create') sat++;
if (morph !== 'delete') eat++;
if (morph !== 'create') {
sat += (0, _wcwidth.default)(code);
}
if (morph !== 'delete') {
eat += (0, _wcwidth.default)(code);
}
}

@@ -410,0 +451,0 @@

@@ -1,19 +0,8 @@

import { getHighlighter, setCDN } from 'shiki';
setCDN('https://esm.sh/shiki@latest/');
let highlighter = null;
export async function ready(options) {
if (highlighter == null) {
highlighter = await getHighlighter({
themes: ['github-dark'].concat(options?.themes ?? []),
langs: options?.languages ?? []
});
} else {
for (const language of options?.languages ?? []) {
await highlighter.loadLanguage(language);
}
for (const theme of options?.themes ?? []) {
await highlighter.loadTheme(theme);
}
}
import { createStarryNight, all } from '@wooorm/starry-night';
import style from './dark-style';
import wcwidth from 'wcwidth';
const starryNight = createStarryNight(all);
let starryNightCache = null;
export async function ready() {
starryNightCache = await starryNight;
}

@@ -35,98 +24,117 @@ 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 (highlighter == null) {
throw new Error('you must await ready() before parsing code');
if (typeof scope !== 'string') {
throw new Error(`language ${code.language} not found`);
}
const parsed = highlighter.codeToThemedTokens(raw, code.language, options?.theme ?? 'github-dark');
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 parsed = sn.highlight(raw, scope);
return parsed.children.map(child => colorRecurse(child, options?.codeStyle ?? {})).flat().map(({
color,
...rest
}) => ({ ...rest,
color: color === '' ? '#c9d1d9' : color
}));
}
const rules = new Map(Object.entries(style).map(([k, v]) => [k, new Map(Object.entries(v))]));
const styleMap = [[['pl-s'], s => s.stringContent?.text], [['pl-s', 'pl-pds'], s => s.stringPunctuation?.text], [['pl-c'], s => s.comment?.text], [['pl-smi'], s => s.variable?.text], [['pl-v'], s => s.parameter?.text], [['pl-s', 'pl-sr'], s => s.regexp?.content ?? s.regexp?.text], [['pl-s', 'pl-sr', 'pl-pds'], s => s.regexp?.brackets ?? s.regexp?.text], [['pl-s', 'pl-sr', 'pl-k'], s => s.regexp?.flags ?? s.regexp?.text], [['pl-c1'], s => s.literal?.text], [['pl-k'], s => s.keyword?.text], [['pl-en'], s => s.entityName?.text]];
function getColor(scopes, codeStyle, fallback = '#C9D1D9') {
function hasScope(target) {
return scopes.some(scope => scope.scopeName.startsWith(target));
}
function findAssociated(styleMap, target, notFound) {
let best = notFound;
let specificity = 0;
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');
for (const [keys, value] of styleMap) {
if (keys.length <= specificity) {
continue;
}
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;
let keyIndex = 0;
let targetIndex = 0;
while (targetIndex < target.length && keyIndex < keys.length) {
const key = keys[keyIndex];
const targetKey = target[targetIndex];
if (targetKey === key) {
keyIndex++;
}
targetIndex++;
}
if (keyIndex === keys.length) {
// all keys found
best = value;
specificity = keys.length;
}
}
return best;
}
function maybeReplace(node, codeStyle) {
const result = [];
export function getColor(classList, codeStyle) {
const fn = findAssociated(styleMap, classList, () => undefined);
const result = fn(codeStyle);
for (const {
content,
scopes
} of node.explanation ?? []) {
result.push({
content,
color: getColor(scopes, codeStyle, node.color)
});
if (result != null) {
return result;
}
const aggregated = [];
const styles = rules.get(`.${classList.at(-1)}`);
console.assert((styles?.size ?? 0) <= 1, `more styles than just color`);
return styles?.get('color');
}
for (const {
content,
color
} of result) {
const last = aggregated.at(-1);
function colorRecurse(parsed, codeStyle, classList = []) {
if (parsed.type === 'text') {
return [{
code: parsed.value,
color: ''
}];
} else if (parsed.type === 'element') {
const className = parsed.properties?.className ?? [];
const color = getColor(classList.concat(className), codeStyle);
const children = parsed.children.map(child => colorRecurse(child, codeStyle, classList.concat(className)));
const result = [];
if (last == null || last.color !== color) {
aggregated.push({
content,
color
});
} else {
last.content += content;
const emit = () => {
if (temp !== '') {
if (color != '') {
result.push({
code: temp,
color
});
} else {
result.push({
code: temp,
color: ''
});
}
temp = '';
}
};
let temp = '';
for (const child of children) {
for (const item of child) {
if (item.color === '') {
temp += item.code;
} else {
emit();
result.push(item);
}
}
emit();
}
emit();
return result;
} else {
throw new Error();
}
return aggregated;
}

@@ -362,4 +370,9 @@

} else {
if (morph !== 'create') sat++;
if (morph !== 'delete') eat++;
if (morph !== 'create') {
sat += wcwidth(code);
}
if (morph !== 'delete') {
eat += wcwidth(code);
}
}

@@ -366,0 +379,0 @@

@@ -74,11 +74,2 @@ export declare type Colors = {

/**
* @deprecated Use {@link regexp} instead
* The colors for a Regular Expression's content.
* ```ts
* /regex/g // "regex" is the content
* ```
*/
regexpContent?: Colors;
/**
* @deprecated Use {@link number} or {@link boolean} instead
* The colors for a literal value, like "true" or "5".

@@ -91,16 +82,2 @@ * ```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`.

@@ -107,0 +84,0 @@ */

@@ -1,8 +0,8 @@

import { Lang, Theme } from 'shiki';
import type { Root } from 'hast';
import type { CodeStyle } from './style';
export type { Theme, Lang } from 'shiki';
export declare function ready(options?: {
languages?: Lang[];
themes?: Theme[];
}): Promise<void>;
export interface StarryNight {
flagToScope: (flag: string) => string | undefined;
highlight: (value: string, scope: string) => Root;
}
export declare function ready(): Promise<void>;
export interface CodeTree {

@@ -29,7 +29,9 @@ language: string;

codeStyle?: CodeStyle;
theme?: Theme;
}
export declare function parse(code: CodeTree, options?: ParseOptions): Token[];
export declare function parse(code: CodeTree, options?: {
codeStyle?: CodeStyle;
}): Token[];
export declare function getColor(classList: string[], codeStyle: CodeStyle): string | undefined;
export declare function toString(tokens: Token[]): string;
export declare function diff(start: CodeTree, end: CodeTree, options?: ParseOptions): MorphToken[];
//# sourceMappingURL=tags.d.ts.map
{
"name": "code-fns",
"version": "0.9.0",
"version": "0.10.0",
"description": "A library for visualizing code.",

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

"scripts": {
"test": "vitest run --silent",
"test": "vitest run",
"test:watch": "vitest --ui",

@@ -46,2 +46,3 @@ "dev": "vite",

"@types/css": "^0.0.33",
"@types/wcwidth": "^1.0.0",
"@typescript-eslint/eslint-plugin": "^5.36.1",

@@ -60,5 +61,2 @@ "@typescript-eslint/parser": "^5.36.1",

},
"dependencies": {
"shiki": "^0.14.1"
},
"prettier": {

@@ -68,3 +66,8 @@ "singleQuote": true,

"trailingComma": "all"
},
"dependencies": {
"@wooorm/starry-night": "^2.0.0",
"hast": "^1.0.0",
"wcwidth": "^1.0.1"
}
}

@@ -30,3 +30,3 @@ # code-fns

To parse code into highlighted tokens, use `language.lang-name` to select your
To parse code into highlighted tokens, use `language.langName` to select your
language, and `parse` to highlight it.

@@ -37,3 +37,3 @@

await ready({ languages: ['tsx'] });
await ready();
const tsx = language.tsx;

@@ -59,3 +59,3 @@ parse(tsx`() => true`);

await ready({ languages: ['tsx'] });
await ready();
const tsx = language.tsx;

@@ -79,3 +79,3 @@ const generate = (result: string) => tsx`(${result});`;

await ready({ languages: ['tsx'] });
await ready();
const tsx = language.tsx;

@@ -82,0 +82,0 @@ const generate = (result: string) => tsx`(${result});`;

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