simpler is better sometimes

This commit is contained in:
Emiliano Heyns
2022-04-19 19:25:34 +02:00
parent 922bda44e2
commit a4a38b697a
8 changed files with 95 additions and 38 deletions

View File

@@ -1,3 +1,5 @@
import { toSentenceCase } from '@retorquere/bibtex-parser'
import type { MarkupNode } from '../typings/markup'
import { titleCased } from './csl-titlecase'
@@ -106,25 +108,7 @@ export function titleCase(text: string): string {
}
export function sentenceCase(text: string): string {
let haslowercase = false
const restore: [number, number, string][] = []
let sentencecased = text.replace(/((?:^|[?!]|[-.:;[\]<>'*\\(),{}—_“”])?\s*)([^-\s;?:.![\]<>'*\\(),{}—_“”]+)/g, (match: string, leader:string, word:string, offset: number) => {
if (word.match(/^[A-Z]$/)) {
const leaderlen = leader?.length
restore.push([offset + leaderlen, offset + leaderlen + word.length, word])
}
else if (word.match(/^[a-z]/)) {
haslowercase = true
}
if (leader && !leader.match(/^[?!]/) && word.match(/^[A-Z][^A-Z]*$/)) word = word.toLowerCase()
return (leader || '') + word
})
if (haslowercase) {
for (const [start, end, word] of restore) {
sentencecased = sentencecased.substr(0, start) + word + sentencecased.substr(end)
}
}
let sentencecased: string = toSentenceCase(text)
// restore protected parts from original
text.replace(/<span class="nocase">.*?<\/span>|<nc>.*?<\/nc>/gi, (match: string, offset: number) => {

28
package-lock.json generated
View File

@@ -41,11 +41,11 @@
"xregexp": "^5.1.0"
},
"devDependencies": {
"@retorquere/bibtex-parser": "^6.1.4",
"@retorquere/bibtex-parser": "^6.2.2",
"@retorquere/zotero-sync": "^1.0.23",
"@types/bluebird": "^3.5.36",
"@types/lokijs": "^1.5.7",
"@types/node": "^17.0.24",
"@types/node": "^17.0.25",
"@xmldom/xmldom": "^0.8.2",
"ajv-keywords": "^5.1.0",
"archiver": "^5.3.1",
@@ -2809,9 +2809,9 @@
}
},
"node_modules/@retorquere/bibtex-parser": {
"version": "6.1.4",
"resolved": "https://registry.npmjs.org/@retorquere/bibtex-parser/-/bibtex-parser-6.1.4.tgz",
"integrity": "sha512-Pd8hrJhUDB3bHTiqc9NtpM57dyFzR4iUK/OG185HDAtmDCtaEmWZcpeRH/VzC1Abhekz5CygLBgEl1GmZ98MbA==",
"version": "6.2.2",
"resolved": "https://registry.npmjs.org/@retorquere/bibtex-parser/-/bibtex-parser-6.2.2.tgz",
"integrity": "sha512-8pRZLNCwIbkghdpKW2jXbX2sA82ZqcolosGO+3KYUbQDTwAVmuji2XLYEO96wAC9slnpF5XGKGqpLjoMFB/FrA==",
"dev": true,
"dependencies": {
"unicode2latex": "^3.0.0",
@@ -2954,9 +2954,9 @@
"dev": true
},
"node_modules/@types/node": {
"version": "17.0.24",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz",
"integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==",
"version": "17.0.25",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.25.tgz",
"integrity": "sha512-wANk6fBrUwdpY4isjWrKTufkrXdu1D2YHCot2fD/DfWxF5sMrVSA+KN7ydckvaTCh0HiqX9IVl0L5/ZoXg5M7w==",
"dev": true
},
"node_modules/@types/normalize-package-data": {
@@ -17906,9 +17906,9 @@
}
},
"@retorquere/bibtex-parser": {
"version": "6.1.4",
"resolved": "https://registry.npmjs.org/@retorquere/bibtex-parser/-/bibtex-parser-6.1.4.tgz",
"integrity": "sha512-Pd8hrJhUDB3bHTiqc9NtpM57dyFzR4iUK/OG185HDAtmDCtaEmWZcpeRH/VzC1Abhekz5CygLBgEl1GmZ98MbA==",
"version": "6.2.2",
"resolved": "https://registry.npmjs.org/@retorquere/bibtex-parser/-/bibtex-parser-6.2.2.tgz",
"integrity": "sha512-8pRZLNCwIbkghdpKW2jXbX2sA82ZqcolosGO+3KYUbQDTwAVmuji2XLYEO96wAC9slnpF5XGKGqpLjoMFB/FrA==",
"dev": true,
"requires": {
"unicode2latex": "^3.0.0",
@@ -18048,9 +18048,9 @@
"dev": true
},
"@types/node": {
"version": "17.0.24",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz",
"integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==",
"version": "17.0.25",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.25.tgz",
"integrity": "sha512-wANk6fBrUwdpY4isjWrKTufkrXdu1D2YHCot2fD/DfWxF5sMrVSA+KN7ydckvaTCh0HiqX9IVl0L5/ZoXg5M7w==",
"dev": true
},
"@types/normalize-package-data": {

View File

@@ -89,11 +89,11 @@
"xregexp": "^5.1.0"
},
"devDependencies": {
"@retorquere/bibtex-parser": "^6.1.4",
"@retorquere/bibtex-parser": "^6.2.2",
"@retorquere/zotero-sync": "^1.0.23",
"@types/bluebird": "^3.5.36",
"@types/lokijs": "^1.5.7",
"@types/node": "^17.0.24",
"@types/node": "^17.0.25",
"@xmldom/xmldom": "^0.8.2",
"ajv-keywords": "^5.1.0",
"archiver": "^5.3.1",

View File

@@ -58,6 +58,7 @@ Feature: Import
Examples:
| file | references |
| Lowercase A in BBT Sentence Case #2078 | 1 |
| Map the call-number field from Bib(La)TeX to call number #2021 | 1 |
| Detect journal abbreviation in the publication field #1951 | 1 |
| Improve import of films #1837 | 4 |

View File

@@ -0,0 +1,18 @@
@article{ludeckeInsightUnifiedInterface2019,
title = {Insight: A Unified Interface to Access Information from Model Objects in {{R}}},
shorttitle = {Insight},
author = {Lüdecke, Daniel and Waggoner, Philip and Makowski, Dominique},
date = {2019-06-25},
journaltitle = {Journal of Open Source Software},
shortjournal = {JOSS},
volume = {4},
number = {38},
pages = {1412},
issn = {2475-9066},
doi = {10.21105/joss.01412},
url = {http://joss.theoj.org/papers/10.21105/joss.01412},
urldate = {2022-03-23}
}

View File

@@ -0,0 +1,50 @@
{
"config": {
"id": "36a3b0b5-bad0-4a04-b79b-441c7cef77db",
"label": "BetterBibTeX JSON",
"localeDateOrder": "mdy",
"options": {
"exportNotes": true
},
"preferences": {
"caching": false
}
},
"items": [
{
"DOI": "10.21105/joss.01412",
"ISSN": "2475-9066",
"accessDate": "2022-03-23T13:22:10Z",
"citationKey": "ludeckeInsightUnifiedInterface2019",
"creators": [
{
"creatorType": "author",
"firstName": "Daniel",
"lastName": "L\u00fcdecke"
},
{
"creatorType": "author",
"firstName": "Philip",
"lastName": "Waggoner"
},
{
"creatorType": "author",
"firstName": "Dominique",
"lastName": "Makowski"
}
],
"date": "2019-06-25",
"issue": "38",
"itemID": 1,
"itemType": "journalArticle",
"journalAbbreviation": "JOSS",
"libraryCatalog": "DOI.org (Crossref)",
"pages": "1412",
"publicationTitle": "Journal of Open Source Software",
"shortTitle": "Insight",
"title": "insight: A Unified Interface to Access Information from Model Objects in R",
"url": "http://joss.theoj.org/papers/10.21105/joss.01412",
"volume": "4"
}
]
}

View File

@@ -80,7 +80,7 @@ with open(args.data) as f:
parser = Parser()
doc = Munch.fromDict(parser.parse(args.feature))
outlines = [child for child in doc.feature.children if child.type == 'ScenarioOutline' and args.translator in child.name]
outlines = [child for child in doc.feature.children if child.type == 'ScenarioOutline' and (args.translator in child.name or args.mode == 'import')]
assert len(outlines) == 1, f'{len(outlines)} outlines found containing {args.translator}'
with open(args.feature) as f:
@@ -111,7 +111,11 @@ if contents:
# copy/create test fixtures
fixture = os.path.join(root, f'test/fixtures/{args.mode}', args.title)
shutil.copyfile(args.data, fixture + '.json')
with open(fixture + '.' + args.translator.lower().replace('-', '.').replace('yaml', 'yml'), 'w') as f:
if args.mode == 'import':
ext = 'bib'
else:
ext = args.translator.lower().replace('-', '.').replace('yaml', 'yml')
with open(fixture + '.' + ext, 'w') as f:
if args.translator == 'CSL-JSON':
f.write('{}')