mirror of
https://github.com/retorquere/zotero-better-bibtex.git
synced 2022-05-23 09:36:29 +03:00
cleanup
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import type { XUL } from '../typings/xul'
|
||||
|
||||
declare const document: any
|
||||
declare const window: any
|
||||
declare const Zotero: any
|
||||
|
||||
@@ -5,6 +5,8 @@ declare const Zotero: any
|
||||
Components.utils.import('resource://gre/modules/FileUtils.jsm')
|
||||
declare const FileUtils: any
|
||||
|
||||
import type { XUL } from '../typings/xul'
|
||||
// import { OS } from '../typings/xpcom'
|
||||
import { clean_pane_persist, patch as $patch$ } from './monkey-patch'
|
||||
import { flash } from './flash'
|
||||
|
||||
@@ -288,7 +290,7 @@ import * as DateParser from './dateparser'
|
||||
import { qualityReport } from './qr-check'
|
||||
import { titleCase } from './case'
|
||||
import { HTMLParser } from './markupparser'
|
||||
import { ParsedDate } from './typings/bbt'
|
||||
import type { ParsedDate } from './dateparser'
|
||||
|
||||
Zotero.Translate.Export.prototype.Sandbox.BetterBibTeX = {
|
||||
qrCheck(_sandbox: any, value: string, test: string, params = null) { return qualityReport(value, test, params) },
|
||||
@@ -657,9 +659,9 @@ class Progress {
|
||||
}
|
||||
else {
|
||||
document.getElementById('better-bibtex-startup').hidden = false
|
||||
this.progressmeter = (document.getElementById('better-bibtex-startup-progress') as XUL.ProgressMeter)
|
||||
this.progressmeter = (document.getElementById('better-bibtex-startup-progress') as unknown as XUL.ProgressMeter)
|
||||
this.progressmeter.value = 0
|
||||
this.label = (document.getElementById('better-bibtex-startup-label') as XUL.Label)
|
||||
this.label = (document.getElementById('better-bibtex-startup-label') as unknown as XUL.Label)
|
||||
this.label.value = msg
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,22 @@ import edtfy = require('edtfy')
|
||||
// import escapeStringRegexp = require('escape-string-regexp')
|
||||
|
||||
import * as months from '../gen/dateparser-months.json'
|
||||
import { ParsedDate } from './typings/bbt'
|
||||
|
||||
export type ParsedDate = {
|
||||
type?: 'date' | 'open' | 'verbatim' | 'season' | 'interval' | 'list'
|
||||
year?: number
|
||||
month?: number
|
||||
day?: number
|
||||
orig?: ParsedDate
|
||||
verbatim?: string
|
||||
from?: ParsedDate
|
||||
to?: ParsedDate
|
||||
dates?: ParsedDate[]
|
||||
season?: number
|
||||
uncertain?: boolean
|
||||
approximate?: boolean
|
||||
}
|
||||
|
||||
const months_re = new RegExp(Object.keys(months).sort((a, b) => b.length - a.length).join('|'), 'i')
|
||||
|
||||
/*
|
||||
|
||||
@@ -5,6 +5,7 @@ declare const Components: any
|
||||
declare const Services: any
|
||||
|
||||
import { log } from '../logger'
|
||||
import 'xpcom'
|
||||
|
||||
Components.utils.import('resource://gre/modules/osfile.jsm')
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import type { MarkupNode } from '../typings/markup'
|
||||
|
||||
import parse5 = require('parse5/lib/parser')
|
||||
const htmlParser = new parse5({ sourceCodeLocationInfo: true })
|
||||
import { titleCase } from './case'
|
||||
@@ -93,10 +95,10 @@ export const HTMLParser = new class { // eslint-disable-line @typescript-eslint/
|
||||
private html: string
|
||||
private ligatures = new RegExp(`[${Object.keys(ligatures).join('')}]`, 'g')
|
||||
|
||||
public parse(html, options: HTMLParserOptions): IZoteroMarkupNode {
|
||||
public parse(html, options: HTMLParserOptions): MarkupNode {
|
||||
this.html = html
|
||||
|
||||
let doc: IZoteroMarkupNode
|
||||
let doc: MarkupNode
|
||||
|
||||
this.caseConversion = options.caseConversion
|
||||
this.braceProtection = options.caseConversion && options.exportBraceProtection
|
||||
@@ -155,7 +157,7 @@ export const HTMLParser = new class { // eslint-disable-line @typescript-eslint/
|
||||
return doc
|
||||
}
|
||||
|
||||
private titleCase(node: IZoteroMarkupNode) {
|
||||
private titleCase(node: MarkupNode) {
|
||||
if (node.nodeName === '#text') {
|
||||
node.value = this.titleCased.substr(node.titleCased, node.value.length)
|
||||
return
|
||||
@@ -167,7 +169,7 @@ export const HTMLParser = new class { // eslint-disable-line @typescript-eslint/
|
||||
}
|
||||
}
|
||||
|
||||
private unwrapSpurious(node: IZoteroMarkupNode) {
|
||||
private unwrapSpurious(node: MarkupNode) {
|
||||
// debug('spurious:', { nodeName: node.nodeName, attrs: Object.keys(node.attr).length, nocase: node.nocase, childNodes: node.childNodes.length })
|
||||
|
||||
if (node.nodeName === '#text') return node
|
||||
@@ -180,7 +182,7 @@ export const HTMLParser = new class { // eslint-disable-line @typescript-eslint/
|
||||
}
|
||||
|
||||
// BibLaTeX is beyond insane https://github.com/retorquere/zotero-better-bibtex/issues/541#issuecomment-240999396
|
||||
private unwrapNocase(node: IZoteroMarkupNode): IZoteroMarkupNode[] {
|
||||
private unwrapNocase(node: MarkupNode): MarkupNode[] {
|
||||
if (node.nodeName === '#text') return [ node ]
|
||||
|
||||
// unwrap and flatten
|
||||
@@ -205,7 +207,7 @@ export const HTMLParser = new class { // eslint-disable-line @typescript-eslint/
|
||||
})
|
||||
}
|
||||
|
||||
private cleanupNocase(node: IZoteroMarkupNode, nocased = false): IZoteroMarkupNode[] {
|
||||
private cleanupNocase(node: MarkupNode, nocased = false): MarkupNode[] {
|
||||
if (node.nodeName === '#text') return null
|
||||
|
||||
if (nocased) delete node.nocase
|
||||
@@ -215,7 +217,7 @@ export const HTMLParser = new class { // eslint-disable-line @typescript-eslint/
|
||||
}
|
||||
}
|
||||
|
||||
private collectText(node: IZoteroMarkupNode) {
|
||||
private collectText(node: MarkupNode) {
|
||||
switch (node.nodeName) {
|
||||
case '#text':
|
||||
node.titleCased = this.titleCased.length
|
||||
@@ -237,7 +239,7 @@ export const HTMLParser = new class { // eslint-disable-line @typescript-eslint/
|
||||
}
|
||||
}
|
||||
|
||||
private plaintext(childNodes: IZoteroMarkupNode[], text, offset) {
|
||||
private plaintext(childNodes: MarkupNode[], text, offset) {
|
||||
// replace ligatures so titlecasing works for things like "figures"
|
||||
text = text.replace(this.ligatures, (ligature: string) => (ligatures[ligature] as string))
|
||||
const l = childNodes.length
|
||||
@@ -267,7 +269,7 @@ export const HTMLParser = new class { // eslint-disable-line @typescript-eslint/
|
||||
|
||||
private walk(node, isNocased = false) {
|
||||
// debug('walk:', node.nodeName)
|
||||
const normalized_node: IZoteroMarkupNode = { nodeName: node.nodeName, childNodes: [], attr: {}, class: {} }
|
||||
const normalized_node: MarkupNode = { nodeName: node.nodeName, childNodes: [], attr: {}, class: {} }
|
||||
for (const {name, value} of (node.attrs || [])) {
|
||||
normalized_node.attr[name] = value
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ declare class ChromeWorker extends Worker { }
|
||||
Components.utils.import('resource://zotero/config.js')
|
||||
declare const ZOTERO_CONFIG: any
|
||||
|
||||
import type { Translators as Translator } from '../typings/translators'
|
||||
import { Preference } from '../gen/preferences'
|
||||
import { Serializer } from './serializer'
|
||||
import { log } from './logger'
|
||||
@@ -84,9 +85,9 @@ const trace: Trace[] = []
|
||||
|
||||
// export singleton: https://k94n.com/es6-modules-single-instance-pattern
|
||||
export const Translators = new class { // eslint-disable-line @typescript-eslint/naming-convention,no-underscore-dangle,id-blacklist,id-match
|
||||
public byId: Record<string, ITranslatorHeader>
|
||||
public byName: Record<string, ITranslatorHeader>
|
||||
public byLabel: Record<string, ITranslatorHeader>
|
||||
public byId: Record<string, Translator.Header>
|
||||
public byName: Record<string, Translator.Header>
|
||||
public byLabel: Record<string, Translator.Header>
|
||||
public itemType: { note: number, attachment: number, annotation: number }
|
||||
|
||||
private queue = new Queue
|
||||
@@ -314,7 +315,7 @@ export const Translators = new class { // eslint-disable-line @typescript-eslint
|
||||
return this.exportItems(translatorID, displayOptions, job.scope, job.path)
|
||||
}
|
||||
|
||||
const config: BBTWorker.Config = {
|
||||
const config: Translator.Worker.Config = {
|
||||
preferences: { ...Preference.all, ...job.preferences },
|
||||
options: displayOptions || {},
|
||||
items: [],
|
||||
@@ -324,7 +325,7 @@ export const Translators = new class { // eslint-disable-line @typescript-eslint
|
||||
}
|
||||
|
||||
let items: any[] = []
|
||||
worker.onmessage = (e: { data: BBTWorker.Message }) => {
|
||||
worker.onmessage = (e: { data: Translator.Worker.Message }) => {
|
||||
switch (e.data?.kind) {
|
||||
case 'error':
|
||||
log.status({error: true, translator: translator.label, worker: id}, 'QBW failed:', Date.now() - start, e.data)
|
||||
|
||||
14
content/typings/bbt.d.ts
vendored
14
content/typings/bbt.d.ts
vendored
@@ -1,14 +0,0 @@
|
||||
export type ParsedDate = {
|
||||
type?: 'date' | 'open' | 'verbatim' | 'season' | 'interval' | 'list'
|
||||
year?: number
|
||||
month?: number
|
||||
day?: number
|
||||
orig?: ParsedDate
|
||||
verbatim?: string
|
||||
from?: ParsedDate
|
||||
to?: ParsedDate
|
||||
dates?: ParsedDate[]
|
||||
season?: number
|
||||
uncertain?: boolean
|
||||
approximate?: boolean
|
||||
}
|
||||
8
content/typings/translator-header.d.ts
vendored
8
content/typings/translator-header.d.ts
vendored
@@ -1,8 +0,0 @@
|
||||
interface ITranslatorHeader {
|
||||
translatorID: string
|
||||
label: string
|
||||
target: string
|
||||
configOptions?: {
|
||||
getCollections?: boolean
|
||||
}
|
||||
}
|
||||
22
content/typings/xpcom.d.ts
vendored
22
content/typings/xpcom.d.ts
vendored
@@ -1,22 +0,0 @@
|
||||
namespace OS {
|
||||
namespace File {
|
||||
function exists(path: string): Promise<boolean>
|
||||
function read(path: string, options: { encoding: string } ): Promise<string>
|
||||
function move(from: string, to: string): Promise<void>
|
||||
function remove(path: string, options?: { ignoreAbsent: boolean }): Promise<void>
|
||||
function writeAtomic(path: string, data: string, options: { tmpPath: string, encoding: string }): Promise<void>
|
||||
function makeDir(path: string, options: { ignoreExisting: boolean }): Promise<void>
|
||||
function stat(path: string): { isDir: boolean, size: number, unixMode?: number }
|
||||
|
||||
class DirectoryIterator {
|
||||
constructor(path: string)
|
||||
forEach(handler: any): Promise<void>
|
||||
}
|
||||
}
|
||||
|
||||
namespace Path {
|
||||
function join(...args: string[]): string
|
||||
function dirname(path: string): string
|
||||
function basename(path: string): string
|
||||
}
|
||||
}
|
||||
@@ -17,14 +17,16 @@
|
||||
"releaseURL": "https://github.com/retorquere/zotero-better-bibtex/releases/download/release/"
|
||||
},
|
||||
"scripts": {
|
||||
"par": "tmux new-session 'npm run esbuild' \\; split-window 'npm run tsc' \\; split-window 'npm run lint'",
|
||||
"pretest": "npm run build",
|
||||
"test": "./test/behave --stop",
|
||||
"lint": "eslint . --ext .ts",
|
||||
"webpack": "webpack",
|
||||
"setup": "./setup/setup.py && ts-node setup/index.ts",
|
||||
"prebuild": "pnpm install && npm run setup && npm run lint && npm run tsc",
|
||||
"prebuild": "pnpm install && npm run setup && npm run lint",
|
||||
"tsc": "tsc --noEmit",
|
||||
"build": "node esbuild.js",
|
||||
"esbuild": "node esbuild.js",
|
||||
"build": "npm run webpack",
|
||||
"postbuild": "./util/patch-install-rdf.py && npm run zipup-better-bibtex && npm run zipup-debug-bridge",
|
||||
"zipup-better-bibtex": "zotero-plugin-zipup build zotero-better-bibtex",
|
||||
"zipup-debug-bridge": "zotero-plugin-zipup test/fixtures/debug-bridge debug-bridge",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable id-blacklist, @typescript-eslint/no-unsafe-return, @typescript-eslint/explicit-module-boundary-types */
|
||||
|
||||
import { client } from '../../content/client'
|
||||
import { ZoteroTranslator } from '../typings/serialized-item'
|
||||
import { Item } from '../typings/serialized-item'
|
||||
const jurism = client === 'jurism'
|
||||
const zotero = !jurism
|
||||
|
||||
@@ -85,7 +85,7 @@ function unalias(item: any) {
|
||||
}
|
||||
|
||||
// import & export translators expect different creator formats... nice
|
||||
export function simplifyForExport(item: any, dropAttachments = false): ZoteroTranslator.Item {
|
||||
export function simplifyForExport(item: any, dropAttachments = false): Item {
|
||||
unalias(item)
|
||||
|
||||
if (item.filingDate) item.filingDate = item.filingDate.replace(/^0000-00-00 /, '')
|
||||
@@ -109,10 +109,10 @@ export function simplifyForExport(item: any, dropAttachments = false): ZoteroTra
|
||||
item.attachments = (!dropAttachments && item.attachments) || []
|
||||
}
|
||||
|
||||
return (item as ZoteroTranslator.Item)
|
||||
return (item as Item)
|
||||
}
|
||||
|
||||
export function simplifyForImport(item: any): ZoteroTranslator.Item {
|
||||
export function simplifyForImport(item: any): Item {
|
||||
unalias(item)
|
||||
|
||||
if (item.creators) {
|
||||
@@ -129,5 +129,5 @@ export function simplifyForImport(item: any): ZoteroTranslator.Item {
|
||||
|
||||
if (!jurism) delete item.multi
|
||||
|
||||
return (item as ZoteroTranslator.Item)
|
||||
return (item as Item)
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ import { Events } from '../content/events'
|
||||
declare const Zotero: any
|
||||
const prefix = '${prefix}'
|
||||
import * as preferences from './preferences.json'
|
||||
import * as meta from '../content/prefs-meta.ts'
|
||||
import { fromEntries } from '../content/object.ts'
|
||||
import * as meta from '../content/prefs-meta'
|
||||
import { fromEntries } from '../content/object'
|
||||
|
||||
<%
|
||||
for pref in preferences:
|
||||
|
||||
@@ -50,7 +50,7 @@ with open(os.path.join(root, 'gen/preferences.json')) as f:
|
||||
variables.labels = translators.byLabel.keys()
|
||||
|
||||
template = """
|
||||
interface ITranslator {
|
||||
export interface ITranslator {
|
||||
preferences: IPreferences
|
||||
skipFields: string[]
|
||||
skipField: {[key: string]: boolean}
|
||||
|
||||
@@ -2,7 +2,7 @@ declare const Zotero: any
|
||||
|
||||
import { Translator } from './lib/translator'
|
||||
export { Translator }
|
||||
import { ZoteroTranslator } from '../gen/typings/serialized-item'
|
||||
import { Item } from '../gen/typings/serialized-item'
|
||||
|
||||
import { Reference } from './bibtex/reference'
|
||||
import { Exporter } from './bibtex/exporter'
|
||||
@@ -287,7 +287,7 @@ export function doExport(): void {
|
||||
// Zotero.write(`\n% ${Translator.header.label}\n`)
|
||||
Zotero.write('\n')
|
||||
|
||||
let item: ZoteroTranslator.Item
|
||||
let item: Item
|
||||
while (item = Exporter.nextItem()) {
|
||||
Zotero.debug(`exporting ${item.citationKey}`)
|
||||
const ref = new Reference(item)
|
||||
|
||||
@@ -3,7 +3,7 @@ declare const Zotero: any
|
||||
|
||||
import { Translator } from './lib/translator'
|
||||
export { Translator }
|
||||
import { ZoteroTranslator } from '../gen/typings/serialized-item'
|
||||
import { Item } from '../gen/typings/serialized-item'
|
||||
|
||||
import { Exporter } from './bibtex/exporter'
|
||||
|
||||
@@ -143,7 +143,7 @@ const Mode = {
|
||||
export function doExport(): void {
|
||||
Translator.init('export')
|
||||
|
||||
let item: ZoteroTranslator.Item
|
||||
let item: Item
|
||||
const items = []
|
||||
while ((item = Exporter.nextItem())) {
|
||||
if (item.citationKey) items.push(item)
|
||||
|
||||
@@ -2,7 +2,7 @@ declare const Zotero: any
|
||||
|
||||
import { log } from '../content/logger'
|
||||
|
||||
import { ZoteroTranslator } from '../gen/typings/serialized-item'
|
||||
import { Item } from '../gen/typings/serialized-item'
|
||||
|
||||
const toWordsOrdinal = require('number-to-words/src/toWordsOrdinal')
|
||||
function edition(n: string | number): string {
|
||||
@@ -258,7 +258,7 @@ export function doExport(): void {
|
||||
// Zotero.write(`\n% ${Translator.header.label}\n`)
|
||||
Zotero.write('\n')
|
||||
|
||||
let item: ZoteroTranslator.Item
|
||||
let item: Item
|
||||
while (item = Exporter.nextItem()) {
|
||||
const ref = new Reference(item)
|
||||
if (item.itemType === 'report' && item.type?.toLowerCase().includes('manual')) ref.referencetype = 'manual'
|
||||
|
||||
@@ -3,6 +3,7 @@ declare const Zotero: any
|
||||
import YAML = require('js-yaml')
|
||||
|
||||
import { Translator } from './lib/translator'
|
||||
import type { MarkupNode } from '../typings/markup'
|
||||
export { Translator }
|
||||
|
||||
import { CSLExporter as Exporter } from './csl/csl'
|
||||
@@ -17,7 +18,7 @@ const htmlConverter = new class HTML {
|
||||
return this.markdown
|
||||
}
|
||||
|
||||
private walk(tag: IZoteroMarkupNode) {
|
||||
private walk(tag: MarkupNode) {
|
||||
if (!tag) return
|
||||
|
||||
if (['#text', 'pre', 'script'].includes(tag.nodeName)) {
|
||||
|
||||
@@ -7,12 +7,12 @@ export { Translator }
|
||||
import { log } from '../content/logger'
|
||||
import { fromEntries } from '../content/object'
|
||||
|
||||
import { ZoteroTranslator } from '../gen/typings/serialized-item'
|
||||
import { Item } from '../gen/typings/serialized-item'
|
||||
|
||||
import * as escape from '../content/escape'
|
||||
import * as Extra from '../content/extra'
|
||||
|
||||
function clean(item: ZoteroTranslator.Item): ZoteroTranslator.Item {
|
||||
function clean(item: Item): Item {
|
||||
item = {...item, ...Extra.get(item.extra, 'zotero') }
|
||||
item.extra = item.extra.split('\n').filter(line => !line.match(/^OCLC:/i)).join('\n')
|
||||
return item
|
||||
@@ -20,7 +20,7 @@ function clean(item: ZoteroTranslator.Item): ZoteroTranslator.Item {
|
||||
|
||||
type ExpandedCollection = {
|
||||
name: string
|
||||
items: ZoteroTranslator.Item[]
|
||||
items: Item[]
|
||||
collections: ExpandedCollection[]
|
||||
root: boolean
|
||||
}
|
||||
@@ -35,7 +35,7 @@ class Exporter {
|
||||
public html = ''
|
||||
|
||||
constructor() {
|
||||
const items: Record<number, ZoteroTranslator.Item> = {}
|
||||
const items: Record<number, Item> = {}
|
||||
const filed: Set<number> = new Set
|
||||
const collections: Record<string, ExpandedCollection> = {}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
||||
|
||||
import { ParsedDate } from '../../content/typings/bbt'
|
||||
import type { ParsedDate } from '../../content/dateparser'
|
||||
import { Translator } from '../lib/translator'
|
||||
import type { Translators } from '../../typings/translators'
|
||||
|
||||
function pad(v:string, padding: string): string {
|
||||
if (v.length >= padding.length) return v
|
||||
@@ -48,7 +49,7 @@ function format(date) {
|
||||
return formatted
|
||||
}
|
||||
|
||||
export function datefield(date: ParsedDate, field: IField): IField {
|
||||
export function datefield(date: ParsedDate, field: Translators.BibTeX.Field): Translators.BibTeX.Field {
|
||||
field = JSON.parse(JSON.stringify({ ...field, value: '', enc: 'latex' }))
|
||||
|
||||
if (!date) return field
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
declare const Zotero: any
|
||||
|
||||
import { Translator } from '../lib/translator'
|
||||
import { ZoteroTranslator } from '../../gen/typings/serialized-item'
|
||||
import { Item } from '../../gen/typings/serialized-item'
|
||||
import { Cache } from '../../typings/cache'
|
||||
|
||||
import { JabRef } from '../bibtex/jabref' // not so nice... BibTeX-specific code
|
||||
import * as itemfields from '../../gen/items/items'
|
||||
import * as bibtexParser from '@retorquere/bibtex-parser'
|
||||
import { Postfix } from '../bibtex/postfix.ts'
|
||||
import { Postfix } from './postfix'
|
||||
import * as Extra from '../../content/extra'
|
||||
|
||||
// export singleton: https://k94n.com/es6-modules-single-instance-pattern
|
||||
@@ -40,10 +41,10 @@ export const Exporter = new class {
|
||||
return uniq
|
||||
}
|
||||
|
||||
public nextItem(): ZoteroTranslator.Item {
|
||||
public nextItem(): Item {
|
||||
this.postfix = this.postfix || (new Postfix(Translator.preferences.qualityReport))
|
||||
|
||||
let item: ZoteroTranslator.Item
|
||||
let item: Item
|
||||
while (item = Translator.nextItem()) {
|
||||
if (['note', 'attachment'].includes(item.itemType)) continue
|
||||
|
||||
@@ -55,7 +56,7 @@ export const Exporter = new class {
|
||||
this.jabref.citekeys.set(item.itemID, item.citationKey)
|
||||
|
||||
// this is not automatically lazy-evaluated?!?!
|
||||
const cached: Types.DB.Cache.ExportedItem = item.cachable ? Zotero.BetterBibTeX.cacheFetch(item.itemID, Translator.options, Translator.preferences) : null
|
||||
const cached: Cache.ExportedItem = item.cachable ? Zotero.BetterBibTeX.cacheFetch(item.itemID, Translator.options, Translator.preferences) : null
|
||||
Translator.cache[cached ? 'hits' : 'misses'] += 1
|
||||
|
||||
if (cached) {
|
||||
|
||||
18
translators/bibtex/field.d.ts
vendored
18
translators/bibtex/field.d.ts
vendored
@@ -1,18 +0,0 @@
|
||||
export interface IField {
|
||||
name: string
|
||||
verbatim?: string
|
||||
value: string | string[] | number | null | { path: string, title?: string, mimeType?: string } | { tag: string, type?: number }[]
|
||||
enc?: 'raw' | 'url' | 'verbatim' | 'creators' | 'literal' | 'latex' | 'tags' | 'attachments' | 'date'
|
||||
orig?: { name?: string, verbatim?: string, inherit?: boolean }
|
||||
bibtexStrings?: boolean
|
||||
bare?: boolean
|
||||
raw?: boolean
|
||||
|
||||
// kept as seperate booleans for backwards compat
|
||||
replace?: boolean
|
||||
fallback?: boolean
|
||||
|
||||
html?: boolean
|
||||
|
||||
bibtex?: string
|
||||
}
|
||||
@@ -3,7 +3,9 @@
|
||||
|
||||
declare const Zotero: any
|
||||
|
||||
import { ZoteroTranslator } from '../../gen/typings/serialized-item'
|
||||
import { Item } from '../../gen/typings/serialized-item'
|
||||
import { Cache } from '../../typings/cache'
|
||||
import type { Translators } from '../../typings/translators'
|
||||
|
||||
import { Translator } from '../lib/translator'
|
||||
|
||||
@@ -296,7 +298,7 @@ const fieldOrder = [
|
||||
*/
|
||||
export class Reference {
|
||||
public has: { [key: string]: any } = {}
|
||||
public item: ZoteroTranslator.Item
|
||||
public item: Item
|
||||
public referencetype: string
|
||||
public referencetype_source: string
|
||||
public useprefix: boolean
|
||||
@@ -340,7 +342,7 @@ export class Reference {
|
||||
private _enc_creators_relax_marker = '\u200C' // zero-width non-joiner
|
||||
|
||||
private isBibString = /^[a-z][-a-z0-9_]*$/i
|
||||
private metadata: Types.DB.Cache.ExportedItemMetadata = { DeclarePrefChars: '', noopsort: false, packages: [] }
|
||||
private metadata: Cache.ExportedItemMetadata = { DeclarePrefChars: '', noopsort: false, packages: [] }
|
||||
private packages: { [key: string]: boolean }
|
||||
private juniorcomma: boolean
|
||||
|
||||
@@ -492,7 +494,7 @@ export class Reference {
|
||||
* 'enc' means 'enc_latex'. If you pass both 'bibtex' and 'latex', 'bibtex' takes precedence (and 'value' will be
|
||||
* ignored)
|
||||
*/
|
||||
public add(field: IField): string {
|
||||
public add(field: Translators.BibTeX.Field): string {
|
||||
if (Translator.preferences.testing && !this.inPostscript && field.name !== field.name.toLowerCase()) throw new Error(`Do not add mixed-case field ${field.name}`)
|
||||
|
||||
if (!field.value && !field.bibtex && this.inPostscript) {
|
||||
@@ -676,7 +678,7 @@ export class Reference {
|
||||
|
||||
public hasCreator(type): boolean { return (this.item.creators || []).some(creator => creator.creatorType === type) }
|
||||
|
||||
public override(field: IField): void {
|
||||
public override(field: Translators.BibTeX.Field): void {
|
||||
const itemtype_name = field.name.split('.')
|
||||
let name
|
||||
if (itemtype_name.length === 2) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
declare const Zotero: any
|
||||
|
||||
import { Translator } from '../lib/translator'
|
||||
import type { MarkupNode } from '../../typings/markup'
|
||||
|
||||
import { log } from '../../content/logger'
|
||||
import HE = require('he')
|
||||
@@ -111,7 +112,7 @@ const htmlConverter = new class HTMLConverter {
|
||||
|
||||
this.stack = []
|
||||
|
||||
const ast: IZoteroMarkupNode = Zotero.BetterBibTeX.parseHTML(html, this.options)
|
||||
const ast: MarkupNode = Zotero.BetterBibTeX.parseHTML(html, this.options)
|
||||
this.walk(ast)
|
||||
|
||||
if (!options.commandspacers) this.latex = replace_command_spacers(this.latex)
|
||||
@@ -127,7 +128,7 @@ const htmlConverter = new class HTMLConverter {
|
||||
return { latex: this.latex, raw: ast.nodeName === 'pre', packages: Object.keys(this.packages) }
|
||||
}
|
||||
|
||||
private walk(tag: IZoteroMarkupNode, nocased = false) {
|
||||
private walk(tag: MarkupNode, nocased = false) {
|
||||
if (!tag) return
|
||||
|
||||
switch (tag.nodeName) {
|
||||
|
||||
@@ -7,6 +7,7 @@ import { Translator } from '../lib/translator'
|
||||
|
||||
import * as itemfields from '../../gen/items/items'
|
||||
import * as Extra from '../../content/extra'
|
||||
import { Cache } from '../../typings/cache'
|
||||
import * as ExtraFields from '../../gen/items/extra-fields.json'
|
||||
import { log } from '../../content/logger'
|
||||
import { worker } from '../../content/worker'
|
||||
@@ -53,7 +54,7 @@ export const CSLExporter = new class { // eslint-disable-line @typescript-eslint
|
||||
|
||||
order.push({ citationKey: item.citationKey, i: items.length })
|
||||
|
||||
let cached: Types.DB.Cache.ExportedItem
|
||||
let cached: Cache.ExportedItem
|
||||
if (cached = Zotero.BetterBibTeX.cacheFetch(item.itemID, Translator.options, Translator.preferences)) {
|
||||
items.push(cached.reference)
|
||||
continue
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-return */
|
||||
|
||||
import { stringify } from '../../content/stringify'
|
||||
import { ZoteroTranslator } from '../../gen/typings/serialized-item'
|
||||
import { Item, Collection } from '../../gen/typings/serialized-item'
|
||||
|
||||
function rjust(str: string | number, width: number, padding: string): string {
|
||||
if (typeof str === 'number') str = `${str}`
|
||||
@@ -121,7 +121,7 @@ export function normalize(library: Library): void {
|
||||
strip(item)
|
||||
|
||||
if (item.extra?.length) {
|
||||
item.extra = (item as ZoteroTranslator.Item).extra.split('\n')
|
||||
item.extra = (item as Item).extra.split('\n')
|
||||
}
|
||||
else {
|
||||
delete item.extra
|
||||
@@ -143,9 +143,9 @@ export function normalize(library: Library): void {
|
||||
}, {})
|
||||
|
||||
if (library.collections && Object.keys(library.collections).length) {
|
||||
const collectionOrder: ZoteroTranslator.Collection[] = Object.values(library.collections)
|
||||
.sort((a: ZoteroTranslator.Collection, b: ZoteroTranslator.Collection): number => stringify({...a, key: '', parent: ''}).localeCompare(stringify({...b, key: '', parent: ''})))
|
||||
const collectionKeys: Record<string, string> = collectionOrder.reduce((acc: Record<string, string>, coll: ZoteroTranslator.Collection, i: number): Record<string, string> => {
|
||||
const collectionOrder: Collection[] = Object.values(library.collections)
|
||||
.sort((a: Collection, b: Collection): number => stringify({...a, key: '', parent: ''}).localeCompare(stringify({...b, key: '', parent: ''})))
|
||||
const collectionKeys: Record<string, string> = collectionOrder.reduce((acc: Record<string, string>, coll: Collection, i: number): Record<string, string> => {
|
||||
coll.key = acc[coll.key] = `coll:${rjust(i, 5, '0')}` // eslint-disable-line no-magic-numbers
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
@@ -3,7 +3,8 @@ declare const ZOTERO_TRANSLATOR_INFO: any
|
||||
|
||||
import { defaults } from '../../content/prefs-meta'
|
||||
import { client } from '../../content/client'
|
||||
import { ZoteroTranslator } from '../../gen/typings/serialized-item'
|
||||
import { Item, Collection } from '../../gen/typings/serialized-item'
|
||||
import { ITranslator } from '../../gen/typings/translator'
|
||||
import type { Preferences } from '../../gen/preferences'
|
||||
import { log } from '../../content/logger'
|
||||
|
||||
@@ -21,7 +22,7 @@ const cacheDisabler = new class {
|
||||
type NestedCollection = {
|
||||
key: string
|
||||
name: string
|
||||
items: ZoteroTranslator.Item[]
|
||||
items: Item[]
|
||||
collections: NestedCollection[]
|
||||
parent?: NestedCollection
|
||||
}
|
||||
@@ -103,12 +104,12 @@ export const Translator = new class implements ITranslator { // eslint-disable-l
|
||||
|
||||
public header: TranslatorHeader
|
||||
|
||||
public collections: Record<string, ZoteroTranslator.Collection>
|
||||
public collections: Record<string, Collection>
|
||||
private _items: {
|
||||
remaining: ZoteroTranslator.Item[]
|
||||
map: Record<number, ZoteroTranslator.Item>
|
||||
remaining: Item[]
|
||||
map: Record<number, Item>
|
||||
}
|
||||
private currentItem: ZoteroTranslator.Item
|
||||
private currentItem: Item
|
||||
|
||||
public isJurisM: boolean
|
||||
public isZotero: boolean
|
||||
@@ -267,11 +268,11 @@ export const Translator = new class implements ITranslator { // eslint-disable-l
|
||||
get collectionTree(): NestedCollection[] {
|
||||
return Object.values(this.collections).filter(coll => !coll.parent).map(coll => this.nestedCollection(coll))
|
||||
}
|
||||
private nestedCollection(collection: ZoteroTranslator.Collection): NestedCollection {
|
||||
private nestedCollection(collection: Collection): NestedCollection {
|
||||
const nested: NestedCollection = {
|
||||
key: collection.key,
|
||||
name: collection.name,
|
||||
items: collection.items.map((itemID: number) => this.items.map[itemID]).filter((item: ZoteroTranslator.Item) => item),
|
||||
items: collection.items.map((itemID: number) => this.items.map[itemID]).filter((item: Item) => item),
|
||||
collections: collection.collections.map((key: string) => this.nestedCollection(this.collections[key])).filter((coll: NestedCollection) => coll),
|
||||
}
|
||||
for (const coll of nested.collections) {
|
||||
@@ -280,12 +281,12 @@ export const Translator = new class implements ITranslator { // eslint-disable-l
|
||||
return nested
|
||||
}
|
||||
|
||||
get items(): { remaining: ZoteroTranslator.Item[], map: Record<number, ZoteroTranslator.Item> } {
|
||||
get items(): { remaining: Item[], map: Record<number, Item> } {
|
||||
if (!this._items) {
|
||||
const remaining: ZoteroTranslator.Item[] = []
|
||||
const map: Record<number, ZoteroTranslator.Item> = {}
|
||||
let item: ZoteroTranslator.Item
|
||||
while (item = (Zotero.nextItem() as ZoteroTranslator.Item)) {
|
||||
const remaining: Item[] = []
|
||||
const map: Record<number, Item> = {}
|
||||
let item: Item
|
||||
while (item = (Zotero.nextItem() as Item)) {
|
||||
item.cachable = this.cachable
|
||||
item.journalAbbreviation = item.journalAbbreviation || item.autoJournalAbbreviation
|
||||
remaining.push(map[item.itemID] = new Proxy(item, cacheDisabler))
|
||||
|
||||
16
translators/typings/worker.d.ts
vendored
16
translators/typings/worker.d.ts
vendored
@@ -1,16 +0,0 @@
|
||||
namespace BBTWorker {
|
||||
type Config = {
|
||||
preferences: any,
|
||||
options: any,
|
||||
items: ISerializedItem[]
|
||||
collections: ZoteroCollection[]
|
||||
cslItems?: Record<number, any>
|
||||
cache: Record<number, {itemID: number, reference: string, metadata: any, meta: { updated: number }}>
|
||||
}
|
||||
|
||||
type Message = { kind: 'done', output: boolean | string }
|
||||
| { kind: 'debug', message: string }
|
||||
| { kind: 'error', message: string }
|
||||
| { kind: 'cache', itemID: number, reference: string, metadata: any }
|
||||
| { kind: 'item', item: number }
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
/* eslint-disable @typescript-eslint/restrict-template-expressions, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-assignment */
|
||||
|
||||
import { ITranslator } from '../../gen/typings/translator'
|
||||
import type { Translators } from '../../typings/translators'
|
||||
|
||||
declare const doExport: () => void
|
||||
declare const Translator: ITranslator
|
||||
|
||||
@@ -16,7 +19,7 @@ import { titleCase } from '../../content/case'
|
||||
import * as itemCreators from '../../gen/items/creators.json'
|
||||
import { client } from '../../content/client'
|
||||
import { log } from '../../content/logger'
|
||||
import { ZoteroTranslator } from '../../gen/typings/serialized-item'
|
||||
import { Collection } from '../../gen/typings/serialized-item'
|
||||
|
||||
const ctx: DedicatedWorkerGlobalScope = self as any
|
||||
|
||||
@@ -180,7 +183,7 @@ function saveFile(path, overwrite) {
|
||||
}
|
||||
|
||||
class WorkerZotero {
|
||||
public config: BBTWorker.Config
|
||||
public config: Translators.Worker.Config
|
||||
public output: string
|
||||
public exportDirectory: string
|
||||
public exportFile: string
|
||||
@@ -230,7 +233,7 @@ class WorkerZotero {
|
||||
this.send({ kind: 'done', output: this.exportFile ? true : this.output })
|
||||
}
|
||||
|
||||
public send(message: BBTWorker.Message) {
|
||||
public send(message: Translators.Worker.Message) {
|
||||
ctx.postMessage(message)
|
||||
}
|
||||
|
||||
@@ -258,7 +261,7 @@ class WorkerZotero {
|
||||
return this.config.items.shift()
|
||||
}
|
||||
|
||||
public nextCollection(): ZoteroTranslator.Collection {
|
||||
public nextCollection(): Collection {
|
||||
return this.config.collections.shift()
|
||||
}
|
||||
|
||||
@@ -282,7 +285,7 @@ class WorkerZotero {
|
||||
|
||||
export const Zotero = new WorkerZotero // eslint-disable-line @typescript-eslint/naming-convention,no-underscore-dangle,id-blacklist,id-match
|
||||
|
||||
export function onmessage(e: { data: BBTWorker.Config }): void {
|
||||
export function onmessage(e: { data: Translators.Worker.Config }): void {
|
||||
Zotero.BetterBibTeX.localeDateOrder = workerContext.localeDateOrder
|
||||
|
||||
if (e.data?.items && !Zotero.config) {
|
||||
|
||||
@@ -15,18 +15,22 @@
|
||||
"sourceMap": false,
|
||||
"downlevelIteration": true,
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true,
|
||||
"typeRoots": [
|
||||
"./node_modules/@types",
|
||||
"./gen/typings",
|
||||
"./typings"
|
||||
],
|
||||
"lib": [ "es2017", "dom", "dom.iterable", "webworker" ]
|
||||
},
|
||||
"include": [
|
||||
"content/**/*",
|
||||
"translators/**/*",
|
||||
"zotero-webpack/**/*",
|
||||
"setup/**/*",
|
||||
"gen/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"**/*.spec.ts",
|
||||
"typings"
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
}
|
||||
|
||||
2
content/db/db.d.ts → typings/cache.d.ts
vendored
2
content/db/db.d.ts → typings/cache.d.ts
vendored
@@ -1,4 +1,4 @@
|
||||
export namespace Cache {
|
||||
export declare namespace Cache {
|
||||
interface ExportedItemMetadata {
|
||||
DeclarePrefChars: string
|
||||
noopsort: boolean
|
||||
@@ -1,4 +1,4 @@
|
||||
interface IZoteroMarkupNode {
|
||||
export interface MarkupNode {
|
||||
nodeName: string
|
||||
childNodes?: IZoteroMarkupNode[]
|
||||
attr?: { [key: string]: string }
|
||||
51
typings/translators.d.ts
vendored
Normal file
51
typings/translators.d.ts
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
import { Item, Collection } from '../gen/typings/serialized-item'
|
||||
|
||||
export namespace Translators {
|
||||
namespace Worker {
|
||||
type Config = {
|
||||
preferences: any,
|
||||
options: any,
|
||||
items: Item[]
|
||||
collections: Collection[]
|
||||
cslItems?: Record<number, any>
|
||||
cache: Record<number, {itemID: number, reference: string, metadata: any, meta: { updated: number }}>
|
||||
}
|
||||
|
||||
type Message =
|
||||
{ kind: 'done', output: boolean | string }
|
||||
| { kind: 'debug', message: string }
|
||||
| { kind: 'error', message: string }
|
||||
| { kind: 'cache', itemID: number, reference: string, metadata: any }
|
||||
| { kind: 'item', item: number }
|
||||
}
|
||||
|
||||
namespace BibTeX {
|
||||
interface Field {
|
||||
name: string
|
||||
verbatim?: string
|
||||
value: string | string[] | number | null | { path: string, title?: string, mimeType?: string } | { tag: string, type?: number }[]
|
||||
enc?: 'raw' | 'url' | 'verbatim' | 'creators' | 'literal' | 'latex' | 'tags' | 'attachments' | 'date'
|
||||
orig?: { name?: string, verbatim?: string, inherit?: boolean }
|
||||
bibtexStrings?: boolean
|
||||
bare?: boolean
|
||||
raw?: boolean
|
||||
|
||||
// kept as seperate booleans for backwards compat
|
||||
replace?: boolean
|
||||
fallback?: boolean
|
||||
|
||||
html?: boolean
|
||||
|
||||
bibtex?: string
|
||||
}
|
||||
}
|
||||
|
||||
interface Header {
|
||||
translatorID: string
|
||||
label: string
|
||||
target: string
|
||||
configOptions?: {
|
||||
getCollections?: boolean
|
||||
}
|
||||
}
|
||||
}
|
||||
26
typings/xpcom.d.ts
vendored
Normal file
26
typings/xpcom.d.ts
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
declare interface DirectoryIterator {
|
||||
forEach: (handler: any) => Promise<void>
|
||||
}
|
||||
declare interface DirectoryIteratorConstructable {
|
||||
new(path: string): DirectoryIterator
|
||||
}
|
||||
|
||||
export declare const OS: {
|
||||
File: {
|
||||
exists: (path: string) => Promise<boolean>
|
||||
read: (path: string, options: { encoding: string } ) => Promise<string>
|
||||
move: (from: string, to: string) => Promise<void>
|
||||
remove: (path: string, options?: { ignoreAbsent: boolean }) => Promise<void>
|
||||
writeAtomic: (path: string, data: string, options: { tmpPath: string, encoding: string }) => Promise<void>
|
||||
makeDir: (path: string, options: { ignoreExisting: boolean }) => Promise<void>
|
||||
stat: (path: string) => { isDir: boolean, size: number, unixMode?: number }
|
||||
|
||||
DirectoryIterator: DirectoryIteratorConstructable
|
||||
}
|
||||
|
||||
Path: {
|
||||
join: (...args: string[]) => string
|
||||
dirname: (path: string) => string
|
||||
basename: (path: string) => string
|
||||
}
|
||||
}
|
||||
24
content/xul.d.ts → typings/xul.d.ts
vendored
24
content/xul.d.ts → typings/xul.d.ts
vendored
@@ -3,37 +3,45 @@ export namespace XUL {
|
||||
public hidden: boolean
|
||||
public getAttribute(name: string): string
|
||||
public setAttribute(name: string, value: string): void
|
||||
public classList: ClassList
|
||||
}
|
||||
|
||||
class Label extends XUL.Element {
|
||||
|
||||
class Label extends Element {
|
||||
public value: string
|
||||
}
|
||||
|
||||
|
||||
class Textbox extends XUL.Element {
|
||||
public value: string
|
||||
public readonly: boolean
|
||||
}
|
||||
|
||||
|
||||
class Checkbox extends XUL.Element {
|
||||
public checked: boolean
|
||||
}
|
||||
|
||||
|
||||
class Menuitem extends XUL.Element {
|
||||
public value: string
|
||||
public label: string
|
||||
}
|
||||
|
||||
|
||||
class ProgressMeter extends XUL.Element {
|
||||
public value: string | number
|
||||
}
|
||||
|
||||
|
||||
class Menupopup extends XUL.Element {
|
||||
public children: Menuitem[]
|
||||
}
|
||||
|
||||
|
||||
class Menulist extends XUL.Element {
|
||||
public firstChild: Menupopup
|
||||
public selectedItem: Menuitem
|
||||
public value: string
|
||||
}
|
||||
}
|
||||
|
||||
class ClassList {
|
||||
public add(classname: string): void
|
||||
public remove(classname: string): void
|
||||
public contains(classname: string): boolean
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ const common = {
|
||||
},
|
||||
|
||||
resolve: {
|
||||
extensions: ['.ts', '.js'],
|
||||
extensions: ['.js', '.ts', '.d.ts'],
|
||||
// https://github.com/webpack/webpack/pull/8460/commits/a68426e9255edcce7822480b78416837617ab065
|
||||
fallback: {
|
||||
fs: false,
|
||||
|
||||
Reference in New Issue
Block a user