rehype-citation
Version:
rehype plugin to add citation and bibliography from bibtex files
233 lines (232 loc) • 7.55 kB
JavaScript
// @ts-nocheck
function _defineProperty(obj, key, value) {
key = _toPropertyKey(key);
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true,
});
}
else {
obj[key] = value;
}
return obj;
}
function _toPropertyKey(t) {
var i = _toPrimitive(t, 'string');
return 'symbol' == typeof i ? i : i + '';
}
function _toPrimitive(t, r) {
if ('object' != typeof t || !t)
return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var i = e.call(t, r || 'default');
if ('object' != typeof i)
return i;
throw new TypeError('@@toPrimitive must return a primitive value.');
}
return ('string' === r ? String : Number)(t);
}
import { type, typeMatcher } from './type.js';
class TypeParser {
constructor(data) {
_defineProperty(this, 'validDataTypes', [
'String',
'Array',
'SimpleObject',
'ComplexObject',
'Primitive',
]);
this.data = data;
}
validateDataType() {
const dataType = this.data.dataType;
if (dataType && !this.validDataTypes.includes(dataType)) {
throw new RangeError(`dataType was ${dataType}; expected one of ${this.validDataTypes}`);
}
}
validateParseType() {
const predicate = this.data.predicate;
if (predicate && !(predicate instanceof RegExp || typeof predicate === 'function')) {
throw new TypeError(`predicate was ${typeof predicate}; expected RegExp or function`);
}
}
validateTokenList() {
const tokenList = this.data.tokenList;
if (tokenList && typeof tokenList !== 'object') {
throw new TypeError(`tokenList was ${typeof tokenList}; expected object or RegExp`);
}
}
validatePropertyConstraint() {
const propertyConstraint = this.data.propertyConstraint;
if (propertyConstraint && typeof propertyConstraint !== 'object') {
throw new TypeError(`propertyConstraint was ${typeof propertyConstraint}; expected array or object`);
}
}
validateElementConstraint() {
const elementConstraint = this.data.elementConstraint;
if (elementConstraint && typeof elementConstraint !== 'string') {
throw new TypeError(`elementConstraint was ${typeof elementConstraint}; expected string`);
}
}
validateExtends() {
const extend = this.data.extends;
if (extend && typeof extend !== 'string') {
throw new TypeError(`extends was ${typeof extend}; expected string`);
}
}
validate() {
if (this.data === null || typeof this.data !== 'object') {
throw new TypeError(`typeParser was ${typeof this.data}; expected object`);
}
this.validateDataType();
this.validateParseType();
this.validateTokenList();
this.validatePropertyConstraint();
this.validateElementConstraint();
this.validateExtends();
}
parseTokenList() {
let tokenList = this.data.tokenList;
if (!tokenList) {
return [];
}
else if (tokenList instanceof RegExp) {
tokenList = {
token: tokenList,
};
}
const { token, split = /\s+/, trim = true, every = true } = tokenList;
const trimInput = (input) => (trim ? input.trim() : input);
const testTokens = every ? 'every' : 'some';
const predicate = (input) => trimInput(input)
.split(split)[testTokens]((part) => token.test(part));
return [predicate];
}
parsePropertyConstraint() {
const constraints = [].concat(this.data.propertyConstraint || []);
return constraints.map(({ props, match, value }) => {
props = [].concat(props);
switch (match) {
case 'any':
case 'some':
return (input) => props.some((prop) => prop in input && (!value || value(input[prop])));
case 'none':
return (input) => !props.some((prop) => prop in input && (!value || value(input[prop])));
case 'every':
default:
return (input) => props.every((prop) => prop in input && (!value || value(input[prop])));
}
});
}
parseElementConstraint() {
const constraint = this.data.elementConstraint;
return !constraint ? [] : [(input) => input.every((entry) => type(entry) === constraint)];
}
parsePredicate() {
if (this.data.predicate instanceof RegExp) {
return [this.data.predicate.test.bind(this.data.predicate)];
}
else if (this.data.predicate) {
return [this.data.predicate];
}
else {
return [];
}
}
getCombinedPredicate() {
const predicates = [
...this.parsePredicate(),
...this.parseTokenList(),
...this.parsePropertyConstraint(),
...this.parseElementConstraint(),
];
if (predicates.length === 0) {
return () => true;
}
else if (predicates.length === 1) {
return predicates[0];
}
else {
return (input) => predicates.every((predicate) => predicate(input));
}
}
getDataType() {
if (this.data.dataType) {
return this.data.dataType;
}
else if (this.data.predicate instanceof RegExp) {
return 'String';
}
else if (this.data.tokenList) {
return 'String';
}
else if (this.data.elementConstraint) {
return 'Array';
}
else {
return 'Primitive';
}
}
get dataType() {
return this.getDataType();
}
get predicate() {
return this.getCombinedPredicate();
}
get extends() {
return this.data.extends;
}
}
class DataParser {
constructor(parser, { async } = {}) {
this.parser = parser;
this.async = async;
}
validate() {
const parser = this.parser;
if (typeof parser !== 'function') {
throw new TypeError(`parser was ${typeof parser}; expected function`);
}
}
}
class FormatParser {
constructor(format, parsers = {}) {
this.format = format;
if (parsers.parseType) {
this.typeParser = new TypeParser(parsers.parseType);
}
if (parsers.parse) {
this.dataParser = new DataParser(parsers.parse, {
async: false,
});
}
if (parsers.parseAsync) {
this.asyncDataParser = new DataParser(parsers.parseAsync, {
async: true,
});
}
}
validateFormat() {
const format = this.format;
if (!typeMatcher.test(format)) {
throw new TypeError(`format name was "${format}"; didn't match expected pattern`);
}
}
validate() {
this.validateFormat();
if (this.typeParser) {
this.typeParser.validate();
}
if (this.dataParser) {
this.dataParser.validate();
}
if (this.asyncDataParser) {
this.asyncDataParser.validate();
}
}
}
export { TypeParser, DataParser, FormatParser };