quarto-utils 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qtils/__init__.py +0 -0
- qtils/examples/update_refs.py +18 -0
- qtils/examples/update_refs_example.py +7 -0
- qtils/tests/__init__.py +0 -0
- qtils/tests/data/update_test.py +5 -0
- qtils/tests/test_all.py +95 -0
- qtils/utils.py +159 -0
- quarto_utils-1.0.0.dist-info/METADATA +130 -0
- quarto_utils-1.0.0.dist-info/RECORD +12 -0
- quarto_utils-1.0.0.dist-info/WHEEL +5 -0
- quarto_utils-1.0.0.dist-info/licenses/LICENSE.md +46 -0
- quarto_utils-1.0.0.dist-info/top_level.txt +1 -0
qtils/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/python3
|
|
2
|
+
import sys
|
|
3
|
+
from qtils.utils import update_references
|
|
4
|
+
import pathlib as pl
|
|
5
|
+
|
|
6
|
+
for x in sys.argv:
|
|
7
|
+
if not isinstance(x, str):
|
|
8
|
+
print("Inputs must be strings")
|
|
9
|
+
sys.exit(0)
|
|
10
|
+
|
|
11
|
+
# choose a paper!
|
|
12
|
+
qmdfile = pl.Path(sys.argv[0])
|
|
13
|
+
bibfile = pl.Path(sys.argv[1])
|
|
14
|
+
|
|
15
|
+
print(qmdfile)
|
|
16
|
+
print(bibfile)
|
|
17
|
+
|
|
18
|
+
update_references(qmdfile,bibfile,inplace=True)
|
qtils/tests/__init__.py
ADDED
|
File without changes
|
qtils/tests/test_all.py
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
import pathlib as pl
|
|
3
|
+
import urllib.request
|
|
4
|
+
from urllib.error import HTTPError, URLError
|
|
5
|
+
import shutil, os
|
|
6
|
+
from text_unidecode import unidecode
|
|
7
|
+
|
|
8
|
+
DATA_DIR = pl.Path('qtils/tests/data')
|
|
9
|
+
|
|
10
|
+
def test_url():
|
|
11
|
+
doi = 'hTTps://doi.org/10.1038/nclimate2425'
|
|
12
|
+
BASE_URL = 'https://dx.doi.org/'
|
|
13
|
+
url = BASE_URL + doi.lower().replace('https://doi.org','').replace(' ','')
|
|
14
|
+
req = urllib.request.Request(url,
|
|
15
|
+
headers={'Accept': 'text/bibliography; style=bibtex'} )
|
|
16
|
+
|
|
17
|
+
with urllib.request.urlopen(req) as f:
|
|
18
|
+
bibtex = f.read().decode()
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def test_getbib():
|
|
22
|
+
from qtils.utils import doi2bib
|
|
23
|
+
bib = '\n\t'.join(doi2bib('hTTps://doi.org/10.1038/nclimate2425'))
|
|
24
|
+
refbib = unidecode(''.join([i for i in open(DATA_DIR / 'one_entry.tst', 'r').readlines()]))
|
|
25
|
+
assert refbib == bib
|
|
26
|
+
|
|
27
|
+
def test_update_bib():
|
|
28
|
+
from qtils.utils import update_bibfile
|
|
29
|
+
# make a copy to test with
|
|
30
|
+
shutil.copy2(DATA_DIR / 'ref.bib_backup',
|
|
31
|
+
DATA_DIR / 'ref.bib')
|
|
32
|
+
# set up dois to update with
|
|
33
|
+
dois = ['junkus fail','10.1111/gwat.12536',
|
|
34
|
+
'10.1111/gwat.13083',
|
|
35
|
+
'10.3133/tm7C9',
|
|
36
|
+
'10.1007/978-3-030-45367-1_2',
|
|
37
|
+
'https://doi.org/10.1080/02626660009492371']
|
|
38
|
+
|
|
39
|
+
# run the update - one should fail
|
|
40
|
+
update_bibfile(DATA_DIR / 'ref.bib', dois)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def test_doi_parser():
|
|
44
|
+
from qtils.utils import _strip_doi
|
|
45
|
+
qfile = DATA_DIR / 'example.dois.qmd'
|
|
46
|
+
dat = qfile.read_text().split('_doi:')
|
|
47
|
+
dois = [_strip_doi(i) for i in dat[1:]]
|
|
48
|
+
assert dois == ['10.1145/2492517.2500290',
|
|
49
|
+
'hTTps://doi.org/10.1038/nclimate2425',
|
|
50
|
+
'10.1080/14650040590946584',
|
|
51
|
+
'10.1029/WR020i004p00415',
|
|
52
|
+
'https://doi.org/10.1577/1548-8659(2001)130<0809:SVIDOL>2.0.CO;2',
|
|
53
|
+
'https://doi.org/10.1890/1051-0761(2006)016[2035:BIRFUP]2.0.CO;2',
|
|
54
|
+
'https://doi.org/10.1641/0006-3568(2000)050[0053:EAECON]2.3.CO;2',
|
|
55
|
+
'https://doi.org/10.2193/0022-541X(2006)70[255:EAAIHE]2.0.CO;2']
|
|
56
|
+
|
|
57
|
+
def test_underscore_warning():
|
|
58
|
+
from qtils.utils import update_references
|
|
59
|
+
if (DATA_DIR / 'underscore.bib').exists():
|
|
60
|
+
os.remove(DATA_DIR / 'underscore.bib')
|
|
61
|
+
update_references(DATA_DIR / 'underscore_test.qmd',
|
|
62
|
+
DATA_DIR / 'underscore.bib',
|
|
63
|
+
False,
|
|
64
|
+
DATA_DIR / 'underscoreout.qmd')
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def test_dois_to_bibtex_qmd():
|
|
68
|
+
from qtils.utils import update_references
|
|
69
|
+
# make a copy to test with
|
|
70
|
+
shutil.copy2(DATA_DIR / 'ref.bib_backup',
|
|
71
|
+
DATA_DIR / 'references.bib')
|
|
72
|
+
|
|
73
|
+
# try with automatic update of filename
|
|
74
|
+
update_references(DATA_DIR / 'example.dois.qmd',
|
|
75
|
+
DATA_DIR / 'references.bib',
|
|
76
|
+
False,
|
|
77
|
+
None)
|
|
78
|
+
|
|
79
|
+
# now try inplace test
|
|
80
|
+
shutil.copy2(DATA_DIR / 'ref.bib_backup',
|
|
81
|
+
DATA_DIR / 'references.bib')
|
|
82
|
+
shutil.copy2(DATA_DIR / 'example.dois.qmd',
|
|
83
|
+
DATA_DIR / 'inplace.qmd')
|
|
84
|
+
update_references(DATA_DIR / 'inplace.qmd',
|
|
85
|
+
DATA_DIR / 'references.bib',
|
|
86
|
+
True,
|
|
87
|
+
None)
|
|
88
|
+
|
|
89
|
+
# and, finally try writing to custom filename
|
|
90
|
+
update_references(DATA_DIR / 'inplace.qmd',
|
|
91
|
+
DATA_DIR / 'references.bib',
|
|
92
|
+
False,
|
|
93
|
+
DATA_DIR / 'newfile.qmd')
|
|
94
|
+
|
|
95
|
+
|
qtils/utils.py
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import urllib.request
|
|
2
|
+
from urllib.error import HTTPError, URLError
|
|
3
|
+
import pathlib as pl
|
|
4
|
+
from text_unidecode import unidecode
|
|
5
|
+
|
|
6
|
+
BASE_URL = 'http://dx.doi.org/'
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def doi2bib(doi='10.1016/j.jhydrol.2014.04.061', skip_url=True):
|
|
10
|
+
"""function to return a bibTex entry for a doi string
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
doi (str, optional): string for doi. Defaults to '10.1016/j.jhydrol.2014.04.061'.
|
|
15
|
+
skip_url (bool, optional): flag for skipping the url entry from bibTex.
|
|
16
|
+
Defaults to True
|
|
17
|
+
Returns:
|
|
18
|
+
list: list of lines for bibTex entry, skipping url if skip_url is True
|
|
19
|
+
"""
|
|
20
|
+
url = BASE_URL + doi.lower().replace('https://doi.org','').replace(' ','')
|
|
21
|
+
req = urllib.request.Request(url)
|
|
22
|
+
req.add_header('Accept', 'application/x-bibtex')
|
|
23
|
+
try:
|
|
24
|
+
with urllib.request.urlopen(req) as f:
|
|
25
|
+
bibtex = unidecode(f.read().decode())
|
|
26
|
+
return bibtex.strip().split(None, 1)
|
|
27
|
+
# return [i for i in bibtex.split('\n') if not i.strip().startswith('url')]
|
|
28
|
+
except HTTPError as e:
|
|
29
|
+
print(e)
|
|
30
|
+
if e.code == 404:
|
|
31
|
+
print('DOI not found.')
|
|
32
|
+
else:
|
|
33
|
+
print('Service unavailable.')
|
|
34
|
+
return f'FAIL'
|
|
35
|
+
except URLError as e:
|
|
36
|
+
return e.reason.strerror
|
|
37
|
+
|
|
38
|
+
def update_bibfile(bib_file, dois):
|
|
39
|
+
"""updates an bibliography file with a new list of dois. If the bibliography
|
|
40
|
+
file doesn't exist, it is created.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
bib_file (str): Name of bib file to update
|
|
44
|
+
dois (list): List of dois (strings) to add to bib_file
|
|
45
|
+
Returns:
|
|
46
|
+
bib_dict (dict): Dictionary with keys of value dois and values of entry
|
|
47
|
+
records in the resulting bib file
|
|
48
|
+
"""
|
|
49
|
+
# read in the existing bib file for updating
|
|
50
|
+
bib_file = pl.Path(bib_file)
|
|
51
|
+
if not bib_file.exists():
|
|
52
|
+
bib_file.touch(exist_ok = False)
|
|
53
|
+
inbib = ' '.join(open(bib_file, 'r', encoding='utf-8').readlines())
|
|
54
|
+
|
|
55
|
+
# get the bibtex entries
|
|
56
|
+
with open(bib_file, 'a') as ofp:
|
|
57
|
+
bibs = [doi2bib(cdoi) for cdoi in dois]
|
|
58
|
+
for cdoi, cbib in zip(dois,bibs):
|
|
59
|
+
if cbib == 'FAIL':
|
|
60
|
+
# doi2bib failed - just warn and move on
|
|
61
|
+
print (f'Could not obtain bibTex entry for doi="{cdoi}"')
|
|
62
|
+
elif 'failed' in cbib:
|
|
63
|
+
print(f'Could not obtain bibTex entry for doi="{cdoi}". Error message from urllib:\n{cbib}')
|
|
64
|
+
elif cbib[0].strip() in inbib:
|
|
65
|
+
# entry already in the bib file
|
|
66
|
+
print(f'doi: "{cdoi}" already in {bib_file}. Skipping')
|
|
67
|
+
else:
|
|
68
|
+
# write the new entry into the bib file
|
|
69
|
+
print(f'Adding doi: "{cdoi}" to bib file')
|
|
70
|
+
ofp.write('\n' + '\n '.join(cbib))
|
|
71
|
+
# make a dictionary with the dois and the key for references
|
|
72
|
+
bib_dict = {}
|
|
73
|
+
for cdoi,i in zip(dois,bibs):
|
|
74
|
+
if i != 'FAIL' and 'failed' not in i:
|
|
75
|
+
bib_dict[cdoi] = i[0].split('{')[1].strip().replace(',','')
|
|
76
|
+
return bib_dict
|
|
77
|
+
|
|
78
|
+
def _strip_doi(doistring):
|
|
79
|
+
"""Function to get the doi ID out of a string
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
doistring (_type_): string containing a doi
|
|
83
|
+
"""
|
|
84
|
+
doistring = doistring.strip().replace("\t",' ').replace("\n",' ')
|
|
85
|
+
locbraks = locbrakp = locsep = locsepend = locspace = 1e6
|
|
86
|
+
locbackslash = loccomma = locbrakpars = locbracketend= 1e6
|
|
87
|
+
if "; " in doistring:
|
|
88
|
+
locsep = doistring.index('; ')
|
|
89
|
+
if doistring.endswith(';'):
|
|
90
|
+
locsepend = doistring.index(';')
|
|
91
|
+
if doistring.endswith(']'):
|
|
92
|
+
locbracketend = doistring.index(']')
|
|
93
|
+
if '] ' in doistring:
|
|
94
|
+
locbraks = doistring.index('] ')
|
|
95
|
+
if '].' in doistring:
|
|
96
|
+
locbrakp = doistring.index('].')
|
|
97
|
+
if '])' in doistring:
|
|
98
|
+
locbrakpars = doistring.index('])')
|
|
99
|
+
if ' ' in doistring:
|
|
100
|
+
locspace = doistring.index(' ')
|
|
101
|
+
if ',' in doistring:
|
|
102
|
+
loccomma = doistring.index(',')
|
|
103
|
+
if "\\" in doistring:
|
|
104
|
+
locbackslash = doistring.index('\\')
|
|
105
|
+
|
|
106
|
+
doilimit = min((locbraks, locbrakp, locsep, locsepend, locbrakpars,
|
|
107
|
+
locspace, locbackslash, loccomma, locbracketend))
|
|
108
|
+
return(doistring[:doilimit])
|
|
109
|
+
|
|
110
|
+
def _write_updated_qmd(qmd_file, qmd_text, inplace=False, new_qmd_file=None):
|
|
111
|
+
if inplace == True:
|
|
112
|
+
with open(qmd_file, 'w') as ofp:
|
|
113
|
+
ofp.write(qmd_text)
|
|
114
|
+
elif new_qmd_file is None:
|
|
115
|
+
with open(pl.Path(f'{qmd_file.parent}/{qmd_file.stem}.updated.qmd'), 'w') as ofp:
|
|
116
|
+
ofp.write(qmd_text)
|
|
117
|
+
else:
|
|
118
|
+
with open(new_qmd_file, 'w') as ofp:
|
|
119
|
+
ofp.write(qmd_text)
|
|
120
|
+
|
|
121
|
+
def update_references(qmd_file, bibfile,
|
|
122
|
+
inplace=False, new_qmd_file=None):
|
|
123
|
+
"""Updates an entire qmd file, replacing doi callouts (which must
|
|
124
|
+
be listed as `_doi:<actual_doi_here>` in the text) with references
|
|
125
|
+
to the updated bibliography file.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
qmd_file (str,): input qmd file.
|
|
129
|
+
bibfile (str, optional): original bib file.
|
|
130
|
+
inplace (bool, optional): Option to replace existing file or to save as a copy.
|
|
131
|
+
If False, and if new_qmd_file is provided, the new file is written to new_qmd_file.
|
|
132
|
+
If False and no new_wmd_file value is provided, the new file is written to a file
|
|
133
|
+
that simply updates qmd_file to include "updated" in the filename. Defaults to True.
|
|
134
|
+
new_qmd_file (_type_, optional): New file to which updated qmd file is written.
|
|
135
|
+
Ignored if inplace==True. Defaults to None.
|
|
136
|
+
"""
|
|
137
|
+
# make sure the paths are legit pathlib objects
|
|
138
|
+
qmd_file = pl.Path(qmd_file)
|
|
139
|
+
if new_qmd_file is not None:
|
|
140
|
+
new_qmd_file = pl.Path(new_qmd_file)
|
|
141
|
+
# first find the dois
|
|
142
|
+
qmd_text = qmd_file.read_text(encoding='utf-8')
|
|
143
|
+
if '\_doi' in qmd_text:
|
|
144
|
+
doiflag = '\_doi'
|
|
145
|
+
else:
|
|
146
|
+
doiflag = '_doi'
|
|
147
|
+
dois = qmd_text.split('_doi:')
|
|
148
|
+
if len(dois)>1:
|
|
149
|
+
dois = [_strip_doi(i) for i in dois[1:]]
|
|
150
|
+
# next update the references
|
|
151
|
+
bib_dict = update_bibfile(bibfile, dois)
|
|
152
|
+
for ck,cv in bib_dict.items():
|
|
153
|
+
qmd_text = qmd_text.replace(f'{doiflag}:{ck}',f'@{cv}')
|
|
154
|
+
else:
|
|
155
|
+
print('no dois found. No updates to make.')
|
|
156
|
+
|
|
157
|
+
# finally write out the updated file
|
|
158
|
+
_write_updated_qmd(qmd_file, qmd_text,
|
|
159
|
+
inplace=inplace, new_qmd_file=new_qmd_file)
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: quarto-utils
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Utilities to update references in Quarto using DOIs
|
|
5
|
+
Home-page: https://github.com/mnfienen/quarto-utils
|
|
6
|
+
Author: Michael N. Fienen, Richard A. Erickson
|
|
7
|
+
Author-email: Michael Fienen <mnfienen@usgs.gov>, Richard Erickson <rerickson@usgs.gov>
|
|
8
|
+
Maintainer-email: Michael Fienen <mnfienen@usgs.gov>
|
|
9
|
+
Project-URL: documentation, https://github.com/DOI-USGS/quarto-utils
|
|
10
|
+
Project-URL: repository, https://github.com/DOI-USGS/quarto-utils
|
|
11
|
+
Keywords: quarto,references,doi
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
|
+
Requires-Python: >=3.7
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE.md
|
|
18
|
+
Requires-Dist: requests
|
|
19
|
+
Requires-Dist: jupyter
|
|
20
|
+
Requires-Dist: notebook
|
|
21
|
+
Requires-Dist: ipykernel
|
|
22
|
+
Requires-Dist: text-unidecode
|
|
23
|
+
Requires-Dist: pytest
|
|
24
|
+
Provides-Extra: test
|
|
25
|
+
Requires-Dist: pytest; extra == "test"
|
|
26
|
+
Requires-Dist: pytest-timeout; extra == "test"
|
|
27
|
+
Dynamic: author
|
|
28
|
+
Dynamic: home-page
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
Dynamic: requires-python
|
|
31
|
+
|
|
32
|
+
# quarto-utils
|
|
33
|
+
|
|
34
|
+
**Package note:** A static copy of this project exists on code.usgs.gov as the official release.
|
|
35
|
+
The dynamic, living version of this project exists on GitHub at https://github.com/DOI-USGS/quarto-utils.
|
|
36
|
+
The code.usgs.gov page will be updated with major releases with active development occuring on the GitHub repo.
|
|
37
|
+
|
|
38
|
+
#### Authors: Michael N. Fienen, Richard A. Erickson
|
|
39
|
+
#### Point of contact: Michael N. Fienen (mnfienen@usgs.gov)
|
|
40
|
+
#### Repository Type: Formal Python package
|
|
41
|
+
#### Year of Origin: 2024 (original publication)
|
|
42
|
+
#### Year of Version: 2024
|
|
43
|
+
#### Version: 1.0.0
|
|
44
|
+
#### Digital Object Identifier (DOI): https://doi.org/10.5066/P1GZPONT
|
|
45
|
+
#### USGS Information Product Data System (IPDS) no.: IP-158658
|
|
46
|
+
|
|
47
|
+
***
|
|
48
|
+
|
|
49
|
+
_Suggested Citation:_
|
|
50
|
+
|
|
51
|
+
Fienen MN, Erickson RA. 2024.
|
|
52
|
+
quarto-utils
|
|
53
|
+
U.S. Geological Survey software release. Reston, Va.,
|
|
54
|
+
https://doi.org/10.5066/P1GZPONT.
|
|
55
|
+
|
|
56
|
+
_Authors' [ORCID](https://orcid.org) nos.:_
|
|
57
|
+
|
|
58
|
+
- Michael N. Fienen, [0000-0002-7756-4651](https://orcid.org/0000-0002-7756-4651)
|
|
59
|
+
- Richard A. Erickson, [0000-0003-4649-482X](https://orcid.org/0000-0003-4649-482X)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
***
|
|
63
|
+
***
|
|
64
|
+
|
|
65
|
+
This python package works with Quarto MarkDown files to allow authors to supply `dois` for references while writing a document. Tools in this utilities package provide the ability to automatically query https://doi.org to return valid `BiBTeX` entries from `dois`.
|
|
66
|
+
|
|
67
|
+
Further utilities allow users to supply a list of `dois`, look up the `BiBTeX` entries, and update them into a new or existing `BiBTeX` file.
|
|
68
|
+
|
|
69
|
+
Finally, this package allows authors to compose Quarto MarkDown documents (`.qmd` files) using tagged `dois` as references. From these, the code replaces such `dois` with valid `BiBTeX` references which are also downloaded into a `.bib` file.
|
|
70
|
+
|
|
71
|
+
The jupyter notebook in `/qtils/examples/examples.ipynb` includes example applications of all the functions in the package.
|
|
72
|
+
|
|
73
|
+
# Getting Started
|
|
74
|
+
|
|
75
|
+
This code will work with python 3.10 and greater with `requests` and `text-unidecode` packages (optional additional packages include `jupyter notebook` to run the notebook example and `pytest` to evaluate the tests).
|
|
76
|
+
|
|
77
|
+
To install, download this repo (such as `git clone ...`) and then run `python setup.py install` (or possibly `python3` depending upon your local path configurations).
|
|
78
|
+
|
|
79
|
+
# SSL certificates
|
|
80
|
+
|
|
81
|
+
Department of Interior users may experience SSL certificate errors due to The site https://code.usgs.gov/usgs/best-practices/-/blob/master/ssl/WorkingWithinSSLIntercept.md?ref_type=heads provides some best practices for working with these security settings.
|
|
82
|
+
|
|
83
|
+
# Repository Files
|
|
84
|
+
|
|
85
|
+
This repository contains a Quarto-based template for the _Journal of Fish and Wildlife Management_.
|
|
86
|
+
To support this, the following files are located here:
|
|
87
|
+
|
|
88
|
+
- `README.md` is this file.
|
|
89
|
+
- `LICENSE.md` is the Official USGS License.
|
|
90
|
+
- `code.json` is the code metadata.
|
|
91
|
+
- `CONTRIBUTING.md` describes how to contribute to this project.
|
|
92
|
+
- `DISCLAIMER.md` is the standard USGS disclaimer.
|
|
93
|
+
- `.gitignore` is a file telling git which files to not track.
|
|
94
|
+
- `ci` a folder for automated testing of this repository and contains a `yaml` file.
|
|
95
|
+
- `quarto-utils` a folder with the Python package an examples. This includes an `examples` folder and `test` folder.
|
|
96
|
+
- `setup.py` is a Python file for the package.
|
|
97
|
+
|
|
98
|
+
# Background knowledge
|
|
99
|
+
|
|
100
|
+
This template assumes the user knows, or at least wants to learn, how to use Markdown-based text programs such as Quarto.
|
|
101
|
+
Knowing basic Markdown commands will help.
|
|
102
|
+
Additionally, knowing LaTeX will assist in helping with advanced formatting.
|
|
103
|
+
|
|
104
|
+
# Explanation of examples and other tips
|
|
105
|
+
|
|
106
|
+
The `test.qmd` and `example.dois.qmd` include references that Fienen created to demonstrate the package.
|
|
107
|
+
The content of the example is not meaningful, but the references are real - just inasmcuh as they can be pulled from the web.
|
|
108
|
+
|
|
109
|
+
`test.qmd` becomes `test.updated.qmd` after processing and the second file should be rendered as a Quarto file.
|
|
110
|
+
|
|
111
|
+
References in a bib files often require manual formatting.
|
|
112
|
+
For example, proper nouns like Mississippi River may need an extra `{}` to be capitalized, for example `title = {{Mississippi River:} my story on {Old Man River}}` to keep "Mississippi River" and "Old Man River capitalized.
|
|
113
|
+
The automatic references also often do not have correct capitalization and these may need to be changed by the user.
|
|
114
|
+
|
|
115
|
+
# Run time
|
|
116
|
+
|
|
117
|
+
This code takes minimal run time (< 1 minute) under most situations.
|
|
118
|
+
|
|
119
|
+
# Known Issues
|
|
120
|
+
|
|
121
|
+
- In some cases, special characters (such as em-dash or en-dash) in BiBTeX will be encoded as short character strings when written to the bib file. These characters will be seen on render or may crash quarto rendering. Users are advised to inspect references after they are downloaded.
|
|
122
|
+
- Some DOIs contain the underscore character (`_`) and this cause this package to not find any new DOIs or otherwise fail. If this occurs, use `\_doi` rather than `_doi` to tag your DOIs in the Quarto file.
|
|
123
|
+
|
|
124
|
+
# Acknowledgments
|
|
125
|
+
|
|
126
|
+
We thank the U.S. Geological Survey Biological Threats and Invasive Species Research Program and U.S. Geological Survey Water Mission Area Integrated Information Dissemination Division for funding.
|
|
127
|
+
Any use of trade, firm, or product names is for descriptive purposes only and does not imply endorsement by the U.S. Government.
|
|
128
|
+
The findings and opinions expressed in this manuscript are those of the authors and do not necessarily represent the views of the US Fish and Wildlife Service.
|
|
129
|
+
|
|
130
|
+
[quarto]: https://quarto.org/
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
qtils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
qtils/utils.py,sha256=C6aoCB9PO1wAIRUOdJ8sETSeNLajjyaahccuwJ5Dn94,6352
|
|
3
|
+
qtils/examples/update_refs.py,sha256=qOzh4TUsw2Tm00w245QVixySOfu6sB1u2fi7_ATdJ8g,373
|
|
4
|
+
qtils/examples/update_refs_example.py,sha256=xjXjwpjSAPXAhc3RfhsdoGRog3-JUp3jextVkdkm5nk,176
|
|
5
|
+
qtils/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
qtils/tests/test_all.py,sha256=AiHUc4kL7r0lQOepXfaBNXI2XxuPp2DDvSeZ_F5v3a8,3425
|
|
7
|
+
qtils/tests/data/update_test.py,sha256=G8W0a6OMPQEoqsALb762IijZggiYYoFrVycYG91eiT0,192
|
|
8
|
+
quarto_utils-1.0.0.dist-info/licenses/LICENSE.md,sha256=j3-fCgUr1LmIPipq2I71L94P7PBedauuZ0xMegcuMEM,1650
|
|
9
|
+
quarto_utils-1.0.0.dist-info/METADATA,sha256=pY_WfKKJKSVuTpqs7OHQxqx6CdAUVm_C2K3l1p2bab8,6603
|
|
10
|
+
quarto_utils-1.0.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
|
|
11
|
+
quarto_utils-1.0.0.dist-info/top_level.txt,sha256=RFzShkQWZhr-_XWihGGl46u4k4EbmyPh_tWFyxv0VBo,6
|
|
12
|
+
quarto_utils-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
License
|
|
2
|
+
=======
|
|
3
|
+
|
|
4
|
+
Unless otherwise noted, This project is in the public domain in the United
|
|
5
|
+
States because it contains materials that originally came from the United
|
|
6
|
+
States Geological Survey, an agency of the United States Department of
|
|
7
|
+
Interior. For more information, see the official USGS copyright policy at
|
|
8
|
+
https://www.usgs.gov/information-policies-and-instructions/copyrights-and-credits
|
|
9
|
+
|
|
10
|
+
Additionally, we waive copyright and related rights in the work
|
|
11
|
+
worldwide through the CC0 1.0 Universal public domain dedication.
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
CC0 1.0 Universal Summary
|
|
15
|
+
-------------------------
|
|
16
|
+
|
|
17
|
+
This is a human-readable summary of the
|
|
18
|
+
[Legal Code (read the full text)][1].
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### No Copyright
|
|
22
|
+
|
|
23
|
+
The person who associated a work with this deed has dedicated the work to
|
|
24
|
+
the public domain by waiving all of his or her rights to the work worldwide
|
|
25
|
+
under copyright law, including all related and neighboring rights, to the
|
|
26
|
+
extent allowed by law.
|
|
27
|
+
|
|
28
|
+
You can copy, modify, distribute and perform the work, even for commercial
|
|
29
|
+
purposes, all without asking permission.
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
### Other Information
|
|
33
|
+
|
|
34
|
+
In no way are the patent or trademark rights of any person affected by CC0,
|
|
35
|
+
nor are the rights that other persons may have in the work or in how the
|
|
36
|
+
work is used, such as publicity or privacy rights.
|
|
37
|
+
|
|
38
|
+
Unless expressly stated otherwise, the person who associated a work with
|
|
39
|
+
this deed makes no warranties about the work, and disclaims liability for
|
|
40
|
+
all uses of the work, to the fullest extent permitted by applicable law.
|
|
41
|
+
When using or citing the work, you should not imply endorsement by the
|
|
42
|
+
author or the affirmer.
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
[1]: https://creativecommons.org/publicdomain/zero/1.0/legalcode
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
qtils
|