@vrcd-community/zhlint
Version:
A linting tool for Chinese language.
83 lines (82 loc) • 2.75 kB
JavaScript
/**
* @fileoverview
*
* This rule is used to revert changes of abbreviations.
*
* Details:
* - the point is rever the trailing dot
*/
import { CharType } from '../parser/index.js';
import { ValidationTarget } from '../report.js';
import { findTokenAfter, findTokenBefore, removeValidationOnTarget } from './util.js';
const defaultSkippedAbbrs = [
'Mr.',
'Mrs.',
'Dr.',
'Jr.',
'Sr.',
'vs.',
'etc.',
'i.e.',
'e.g.',
'a.k.a.'
];
const reverseAbbrsIntoChars = (abbrs) => {
return abbrs.map((str) => str.split('.').reverse().slice(1));
};
const matchAbbr = (token, group, reversedAbbrChars) => {
// find previous token
const tokenBefore = findTokenBefore(group, token);
if (tokenBefore && !tokenBefore.spaceAfter) {
// get the next matching abbr chars by removing the last char and filtering
const matchedAbbrChars = reversedAbbrChars
.filter((abbr) => tokenBefore.value && abbr[0].toLowerCase() === tokenBefore.value.toLowerCase())
.map((abbr) => abbr.slice(1));
// keep matching until any abbr chars fully matched
// then return true
if (matchedAbbrChars.length) {
const lastMatched = matchedAbbrChars[matchedAbbrChars.length - 1];
if (lastMatched.length) {
const tokenBeforeBefore = findTokenBefore(group, tokenBefore);
if (tokenBeforeBefore &&
!tokenBeforeBefore.spaceAfter &&
tokenBeforeBefore.value === '.') {
const result = matchAbbr(tokenBeforeBefore, group, matchedAbbrChars);
if (result) {
return true;
}
}
}
else {
return true;
}
}
}
return false;
};
const generateHandler = (options) => {
const reversedAbbrChars = reverseAbbrsIntoChars(options.skipAbbrs || []);
return (token, _, group) => {
// skip non-dot tokens
if (token.value !== '.') {
return;
}
// make sure it's the ending dot of the abbr
const tokenAfter = findTokenAfter(group, token);
if (tokenAfter &&
tokenAfter.type === CharType.WESTERN_LETTER &&
!token.spaceAfter) {
return;
}
// keep the dot if the previous tokens match any abbr
if (matchAbbr(token, group, reversedAbbrChars)) {
token.modifiedValue = '.';
token.modifiedType = token.type;
removeValidationOnTarget(token, ValidationTarget.VALUE);
}
};
};
export const defaultConfig = {
skipAbbrs: defaultSkippedAbbrs
};
export default generateHandler;