添加期刊引用分析
This commit is contained in:
282
src/utils/referenceJournalAbbrev.js
Normal file
282
src/utils/referenceJournalAbbrev.js
Normal file
@@ -0,0 +1,282 @@
|
||||
import { htmlToPlainText } from '@/utils/exportTableWord';
|
||||
|
||||
const STOP_WORDS = new Set([
|
||||
'a', 'an', 'the', 'of', 'and', 'for', 'in', 'on', 'at', 'to', 'from', 'with', 'by',
|
||||
'de', 'du', 'des', 'la', 'le', 'les', 'et', 'und', 'der', 'die', 'das'
|
||||
]);
|
||||
|
||||
const KNOWN_WORD_ABBREVIATIONS = {
|
||||
journal: 'J',
|
||||
international: 'Int',
|
||||
american: 'Am',
|
||||
european: 'Eur',
|
||||
british: 'Br',
|
||||
medicine: 'Med',
|
||||
medical: 'Med',
|
||||
nursing: 'Nurs',
|
||||
inquiry: 'Inq',
|
||||
science: 'Sci',
|
||||
sciences: 'Sci',
|
||||
research: 'Res',
|
||||
review: 'Rev',
|
||||
reports: 'Rep',
|
||||
health: 'Health',
|
||||
healthcare: 'Health',
|
||||
clinical: 'Clin',
|
||||
surgery: 'Surg',
|
||||
pediatric: 'Pediatr',
|
||||
paediatric: 'Paediatr',
|
||||
oncology: 'Oncol',
|
||||
psychiatry: 'Psychiatry',
|
||||
psychology: 'Psychol',
|
||||
education: 'Educ',
|
||||
technology: 'Technol',
|
||||
engineering: 'Eng',
|
||||
management: 'Manage',
|
||||
studies: 'Stud',
|
||||
practice: 'Pract',
|
||||
traditional: 'Tradit',
|
||||
tradit: 'Tradit',
|
||||
clinical: 'Clin',
|
||||
complementary: 'Complement',
|
||||
alternative: 'Altern',
|
||||
integrative: 'Integr',
|
||||
pharmacology: 'Pharmacol',
|
||||
biochemistry: 'Biochem',
|
||||
physiology: 'Physiol',
|
||||
pathology: 'Pathol',
|
||||
radiology: 'Radiol',
|
||||
cardiology: 'Cardiol',
|
||||
neurology: 'Neurol',
|
||||
dermatology: 'Dermatol',
|
||||
obstetrics: 'Obstet',
|
||||
gynecology: 'Gynecol',
|
||||
gynaecology: 'Gynaecol',
|
||||
anesthesiology: 'Anesthesiol',
|
||||
anaesthesiology: 'Anaesthesiol',
|
||||
epidemiology: 'Epidemiol',
|
||||
immunology: 'Immunol',
|
||||
microbiology: 'Microbiol',
|
||||
nutrition: 'Nutr',
|
||||
public: 'Public',
|
||||
environmental: 'Environ',
|
||||
occupational: 'Occup',
|
||||
behavioral: 'Behav',
|
||||
behavioural: 'Behav',
|
||||
biological: 'Biol',
|
||||
molecular: 'Mol',
|
||||
cellular: 'Cell',
|
||||
applied: 'Appl',
|
||||
advanced: 'Adv',
|
||||
general: 'Gen',
|
||||
internal: 'Intern',
|
||||
family: 'Fam',
|
||||
community: 'Community',
|
||||
global: 'Glob',
|
||||
world: 'World',
|
||||
asian: 'Asian',
|
||||
chinese: 'Chin',
|
||||
japanese: 'Jpn',
|
||||
korean: 'Korean',
|
||||
indian: 'Indian',
|
||||
african: 'Afr',
|
||||
australian: 'Aust',
|
||||
canadian: 'Can',
|
||||
quarterly: 'Q',
|
||||
monthly: 'Mon',
|
||||
weekly: 'Wkly',
|
||||
annual: 'Annu',
|
||||
proceedings: 'Proc',
|
||||
transactions: 'Trans',
|
||||
bulletin: 'Bull',
|
||||
letters: 'Lett',
|
||||
communications: 'Commun',
|
||||
perspectives: 'Perspect',
|
||||
insights: 'Insights',
|
||||
trends: 'Trends',
|
||||
systems: 'Syst',
|
||||
informatics: 'Inform',
|
||||
bioinformatics: 'Bioinform',
|
||||
therapeutics: 'Ther',
|
||||
diagnostics: 'Diagn',
|
||||
imaging: 'Imaging',
|
||||
rehabilitation: 'Rehabil',
|
||||
emergency: 'Emerg',
|
||||
critical: 'Crit',
|
||||
care: 'Care',
|
||||
patient: 'Patient',
|
||||
patients: 'Patient',
|
||||
hospital: 'Hosp',
|
||||
hospitals: 'Hosp',
|
||||
university: 'Univ',
|
||||
academy: 'Acad',
|
||||
society: 'Soc',
|
||||
association: 'Assoc',
|
||||
federation: 'Fed',
|
||||
institute: 'Inst',
|
||||
college: 'Coll',
|
||||
school: 'Sch',
|
||||
department: 'Dep',
|
||||
division: 'Div',
|
||||
section: 'Sect',
|
||||
series: 'Ser',
|
||||
supplement: 'Suppl',
|
||||
edition: 'Ed',
|
||||
online: 'Online',
|
||||
open: 'Open',
|
||||
access: 'Access'
|
||||
};
|
||||
|
||||
function splitJournalWords(journalText) {
|
||||
return String(journalText || '')
|
||||
.replace(/\./g, ' ')
|
||||
.split(/[\s/&]+/)
|
||||
.map(function (part) {
|
||||
return part.trim();
|
||||
})
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
function abbreviateJournalWord(word) {
|
||||
const cleaned = String(word || '').replace(/[^\p{L}\-]/gu, '');
|
||||
if (!cleaned) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const lower = cleaned.toLowerCase();
|
||||
if (KNOWN_WORD_ABBREVIATIONS[lower]) {
|
||||
return KNOWN_WORD_ABBREVIATIONS[lower];
|
||||
}
|
||||
|
||||
if (cleaned.length <= 4) {
|
||||
return cleaned.charAt(0).toUpperCase() + cleaned.slice(1);
|
||||
}
|
||||
|
||||
const vowels = 'aeiouy';
|
||||
let result = cleaned.charAt(0).toUpperCase();
|
||||
const rest = cleaned.slice(1).toLowerCase();
|
||||
let index = 0;
|
||||
|
||||
while (result.length < 4 && index < rest.length) {
|
||||
const ch = rest.charAt(index);
|
||||
index += 1;
|
||||
if (!vowels.includes(ch)) {
|
||||
result += ch;
|
||||
} else if (result.length === 1) {
|
||||
result += ch;
|
||||
}
|
||||
}
|
||||
|
||||
if (result.length < 3) {
|
||||
const fallback = cleaned.slice(0, Math.min(4, cleaned.length));
|
||||
result = fallback.charAt(0).toUpperCase() + fallback.slice(1).toLowerCase();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function normalizeJournalText(text) {
|
||||
return String(text || '')
|
||||
.replace(/\./g, ' ')
|
||||
.replace(/\s+/g, ' ')
|
||||
.trim();
|
||||
}
|
||||
|
||||
/** 是否已是期刊缩写形式(如 Nurs Inq、Tradit Med Res) */
|
||||
export function isAbbreviatedJournalName(journalText) {
|
||||
const plain = normalizeJournalText(htmlToPlainText(journalText));
|
||||
if (!plain) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const words = splitJournalWords(plain);
|
||||
if (!words.length) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !words.some(function (word) {
|
||||
if (STOP_WORDS.has(word.toLowerCase())) {
|
||||
return false;
|
||||
}
|
||||
return word.length >= 7;
|
||||
});
|
||||
}
|
||||
|
||||
/** 将期刊全称转为无句点缩写(如 Nursing Inquiry -> Nurs Inq) */
|
||||
export function buildJournalAbbreviation(journalText) {
|
||||
const plain = normalizeJournalText(htmlToPlainText(journalText));
|
||||
if (!plain) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const abbreviated = splitJournalWords(plain)
|
||||
.map(function (word) {
|
||||
if (STOP_WORDS.has(word.toLowerCase())) {
|
||||
return '';
|
||||
}
|
||||
return abbreviateJournalWord(word);
|
||||
})
|
||||
.filter(Boolean);
|
||||
|
||||
return abbreviated.join(' ');
|
||||
}
|
||||
|
||||
/** journal 参考文献期刊名是否需要缩写建议 */
|
||||
export function needsJournalAbbreviation(journalText) {
|
||||
const plain = normalizeJournalText(htmlToPlainText(journalText));
|
||||
if (!plain || isAbbreviatedJournalName(plain)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const abbreviated = buildJournalAbbreviation(plain);
|
||||
if (!abbreviated) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return plain.toLowerCase() !== abbreviated.toLowerCase();
|
||||
}
|
||||
|
||||
function isJournalReference(ref) {
|
||||
return String(ref && ref.refer_type || '').toLowerCase() === 'journal';
|
||||
}
|
||||
|
||||
export function extractJournalSource(ref) {
|
||||
if (!isJournalReference(ref)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const jouraPlain = htmlToPlainText(ref.joura).trim();
|
||||
if (jouraPlain) {
|
||||
return jouraPlain;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
export function buildJournalAbbrevComment(ref) {
|
||||
const revision = buildJournalAbbrevRevision(ref);
|
||||
if (!revision) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return '期刊名称缩写:' + revision.suggested;
|
||||
}
|
||||
|
||||
export function buildJournalAbbrevRevision(ref) {
|
||||
const journalSource = extractJournalSource(ref);
|
||||
if (!journalSource || !needsJournalAbbreviation(journalSource)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const suggested = buildJournalAbbreviation(journalSource);
|
||||
if (!suggested || journalSource.toLowerCase() === suggested.toLowerCase()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
original: journalSource,
|
||||
suggested: suggested,
|
||||
suffix: '. ',
|
||||
italics: true
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user