Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
2d96c58
feat: add some old updates
schneiderfelipe Apr 28, 2023
a30d461
feat: add an old Python rewrite idea
schneiderfelipe Apr 28, 2023
6f30430
feat: start a rewrite
schneiderfelipe Apr 28, 2023
1d5ac08
feat: move to the right place
schneiderfelipe Apr 28, 2023
9302fa9
feat: add the other rewrites
schneiderfelipe Apr 28, 2023
4109288
feat: rewrite doi2bib with the help of ChatGPT
schneiderfelipe Apr 28, 2023
77cee73
style: happy Clippy
schneiderfelipe Apr 28, 2023
0020dea
fix: headers
schneiderfelipe Apr 28, 2023
d0c9749
feat: start rewriting using clap
schneiderfelipe Apr 28, 2023
4823155
feat: use clap derive API
schneiderfelipe Apr 28, 2023
814ea5f
refactor: simplify and delegate
schneiderfelipe Apr 28, 2023
a754fc8
refactor: import stuff
schneiderfelipe Apr 28, 2023
5aa99f1
refactor: make things strongly typed
schneiderfelipe Apr 28, 2023
1baae70
refactor: use nutype
schneiderfelipe Apr 28, 2023
358146b
style: happy Clippy
schneiderfelipe Apr 28, 2023
2b9043a
chore: rename and reformat
schneiderfelipe Apr 28, 2023
01b2da3
feat: create a library
schneiderfelipe Apr 28, 2023
6cbc18f
refactor: lib
schneiderfelipe Apr 28, 2023
5e2f731
docs: improve
schneiderfelipe Apr 28, 2023
8319555
feat: validate with Regex
schneiderfelipe Apr 28, 2023
1461dbe
refactor: reorganize
schneiderfelipe Apr 28, 2023
416f520
fix: regex
schneiderfelipe Apr 28, 2023
ca2dc8f
chore(deps): clean up
schneiderfelipe Apr 28, 2023
f756add
chore(Cargo.toml): set MSRV
schneiderfelipe Apr 28, 2023
8004e6b
docs: add link
schneiderfelipe Apr 28, 2023
6f29c11
feat: improve writing
schneiderfelipe Apr 28, 2023
8c23d36
feat: align
schneiderfelipe Apr 28, 2023
340a37c
refactor: migrate error
schneiderfelipe Apr 28, 2023
3f4d704
feat: start implementing url2bib
schneiderfelipe Apr 28, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Created by https://www.toptal.com/developers/gitignore/api/rust
# Edit at https://www.toptal.com/developers/gitignore?templates=rust

### Rust ###
# Generated by Cargo
# will have compiled files and executables
debug/
target/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk

# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb

# End of https://www.toptal.com/developers/gitignore/api/rust
18 changes: 18 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "doi"
version = "0.1.0"
edition = "2021"
rust-version = "1.65.0"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
clap = { version = "4.2.5", features = ["derive"] }
either = "1.8.1"
itertools = "0.10.5"
nom-bibtex = "0.4.0"
nutype = { version = "0.2.0", features = ["regex"] }
once_cell = "1.17.1"
regex = "1.8.1"
reqwest = { version = "0.11", features = ["blocking"] }
url = "2.3.1"
66 changes: 37 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,49 +1,53 @@
[![DOI](https://zenodo.org/badge/67431697.svg)](https://zenodo.org/badge/latestdoi/67431697)

# doi2bib and friends

This repository provides scripts for converting from either [Digital Object Identifier (DOI)](https://www.doi.org) or [Uniform Resource Locator (URL)](https://en.wikipedia.org/wiki/URL) to [BibTeX](http://www.bibtex.org), or from DOI to plain text.

<p align="center">
<img alt="ASCII video" src="cast.svg">
</p>

## doi2bib
TODO: support storing to the clipboard automatically.
TODO: add the surname of the first author automatically if not given (if only the year is shown as id when retrieved)

Convert [Digital Object Identifier (DOI)](https://www.doi.org) to
[BibTeX](http://www.bibtex.org) using
[crosscite.org](https://citation.crosscite.org/).
DOIs are received and the corresponding BibTeX entries are output.
# Bibliography in your command-line

Inspired by <https://gist.github.com/mlund/4609288> and
<http://www.doi2bib.org/>.
This repository provides scripts for converting from either [Digital Object Identifier (DOI)](https://www.doi.org) or [Uniform Resource Locator (URL)](https://en.wikipedia.org/wiki/URL) to [BibTeX](http://www.bibtex.org), or from DOI to plain text.

## `doi2bib`

**October 16, 2017**: <http://www.doi2bib.org/> seems not to be working
any more.
Convert [Digital Object Identifier (DOI)](https://www.doi.org) to [BibTeX](http://www.bibtex.org) using [crosscite.org](https://citation.crosscite.org/).
DOIs are received and the corresponding BibTeX entries are output.
(Inspired by <https://gist.github.com/mlund/4609288> and <http://www.doi2bib.org/>.)

## doi2text
## `doi2text`

Convert [Digital Object Identifier (DOI)](https://www.doi.org) to plain text
using [crosscite.org](https://citation.crosscite.org/). DOIs are received and
the corresponding text entries are output. In theory, all the styles
available at <https://github.com/citation-style-language/styles> can be used.
Convert [Digital Object Identifier (DOI)](https://www.doi.org) to plain text using [crosscite.org](https://citation.crosscite.org/).
DOIs are received and the corresponding text entries are output. In theory, all the styles available at <https://github.com/citation-style-language/styles> can be used.

## url2bib
## `url2bib`

Convert [Uniform Resource Locator (URL)](https://en.wikipedia.org/wiki/URL) to
[BibTeX](http://www.bibtex.org) using pure
[Bash](https://en.wikipedia.org/wiki/Bash_(Unix_shell)).
Convert [Uniform Resource Locator (URL)](https://en.wikipedia.org/wiki/URL) to [BibTeX](http://www.bibtex.org) using pure [Bash](<https://en.wikipedia.org/wiki/Bash_(Unix_shell)>).
URLs are received and the corresponding BibTeX entries are output.
(This is made to be used exactly as one would use `doi2bib`.)

(This is made to be used exactly as one would use doi2bib.)
This requires `gawk` (`sudo apt install gawk`).

## Dependencies

`doi2bib` requires [curl](https://curl.haxx.se/):

$ sudo apt install curl

You will also need `make` to install:

$ sudo apt install make

## Installation

After downloading the tarball and using `cd` to go where the files are, simply do a `sudo make install` and everything will be installed.
By default, it will install in `/usr/local/bin/`.

## Usage

$ doi2bib 10.1021/acs.jpcc.8b06244 10.1021/acscatal.9b00210
$ doi2bib 10.1021/acs.jpcc.8b06244 10.1021/acscatal.9b00210
@article{Schneider_2018,
title={How Do Secondary Phosphine Oxides Interact with Silver Nanoclusters? Insights from Computation},
volume={122},
Expand Down Expand Up @@ -74,7 +78,7 @@ After downloading the tarball and using `cd` to go where the files are, simply d
pages={3792–3799}
}

$ url2bib google.com http://schneiderfelipe.xyz/ https://github.com/schneiderfelipe/doi2bib
$ url2bib google.com https://schneiderfelipe.github.io/ https://github.com/schneiderfelipe/doi
@misc{google,
title = {Google},
howpublished = {\url{google.com}},
Expand All @@ -83,12 +87,16 @@ After downloading the tarball and using `cd` to go where the files are, simply d

@misc{felipe-s-s-schneider,
title = {Felipe S. S. Schneider},
howpublished = {\url{http://schneiderfelipe.xyz/}},
howpublished = {\url{https://schneiderfelipe.github.io/}},
note = {Accessed: 2020-01-27}
}

@misc{github-schneiderfelipe-doi2bib-convert-dois-and-urls-to-bibtex,
title = {GitHub - schneiderfelipe/doi2bib: Convert DOIs and URLs to BibTeX},
howpublished = {\url{https://github.com/schneiderfelipe/doi2bib}},
@misc{github-schneiderfelipe-doi-convert-dois-and-urls-to-bibtex,
title = {GitHub - schneiderfelipe/doi: Convert DOIs and URLs to BibTeX},
howpublished = {\url{https://github.com/schneiderfelipe/doi}},
note = {Accessed: 2020-01-27}
}

## Citing doi2bib

If you use doi2bib in your research, please cite it.
15,058 changes: 15,057 additions & 1 deletion cast.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions src/bibmagic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env python

import sys
import bibtexparser as btp
from bibtexparser.bparser import BibTexParser
from bibtexparser.customization import homogenize_latex_encoding

with open(sys.argv[1]) as bib_file:
parser = BibTexParser()
# parser.customization = homogenize_latex_encoding
bib_db = btp.load(bib_file, parser=parser)

if len(sys.argv) > 2:
with open(sys.argv[2], 'w') as bib_file:
btp.dump(bib_db, bib_file)
else:
print(btp.dumps(bib_db))
63 changes: 63 additions & 0 deletions src/bin/doi2bib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use std::process;
use std::str::FromStr;

use clap::Parser;
use doi::Doi;
use either::Either;
use itertools::Itertools;
use itertools::Position;
use nom_bibtex::Bibliography;
use nom_bibtex::Bibtex;
use reqwest::blocking::Client;
use reqwest::blocking::Response;
use reqwest::header;
use reqwest::Url;

/// Retrieve BibTeX data for a given DOI.
#[derive(Clone, Debug, Parser)]
#[command(author, version, about, arg_required_else_help(true))]
struct Cli {
/// DOI to retrieve BibTeX data for.
#[arg(value_parser(Doi::from_str))]
doi: Vec<Doi>,
}

fn main() {
let cli = Cli::parse();

for doi in cli.doi {
match Client::new()
.get(Url::from(&doi))
.header(header::ACCEPT, "text/bibliography; style=bibtex")
.send()
.and_then(Response::text)
.map_err(Either::Left)
.and_then(|text| Bibtex::parse(&text).map_err(Either::Right))
{
Ok(bibtex) => {
bibtex.bibliographies().iter().for_each(|biblio| {
print(biblio);
});
}
Err(e) => {
eprintln!("Error retrieving DOI {doi}: {e}");
process::exit(1);
}
}
}
}

fn print(biblio: &Bibliography) {
println!("@{}{{{},", biblio.entry_type(), biblio.citation_key());
biblio.tags().iter().with_position().for_each(|item| {
match item {
Position::First((key, value)) | Position::Middle((key, value)) => {
println!(" {key:9} = {{{value}}},");
}
Position::Last((key, value)) | Position::Only((key, value)) => {
println!(" {key:9} = {{{value}}}");
}
}
});
println!("}}\n");
}
3 changes: 3 additions & 0 deletions src/bin/doi2text.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}
62 changes: 62 additions & 0 deletions src/bin/url2bib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use std::process;
use std::str::FromStr;

use clap::Parser;
use itertools::Itertools;
use itertools::Position;
use nom_bibtex::Bibliography;
use reqwest::blocking::Client;
use reqwest::blocking::Response;
use reqwest::Url;

/// Retrieve BibTeX data for a given URL.
#[derive(Clone, Debug, Parser)]
#[command(author, version, about, arg_required_else_help(true))]
struct Cli {
/// URL to retrieve BibTeX data for.
#[arg(value_parser(Url::from_str))]
url: Vec<Url>,
}

fn main() {
let cli = Cli::parse();

for url in cli.url {
match Client::new()
.get(url.as_str())
.send()
.and_then(Response::text)
{
Ok(html) => {
let title: String = todo!("Hello world!");
let slug: String = todo!("hello-world");
let today: String = todo!("%Y-%m-%d");
let biblio = Bibliography::new("misc".into(), slug, vec![
("title".into(), title),
("howpublished".into(), format!(r"\url{{{}}}", url)),
("note".into(), format!("Accessed: {}", today)),
]);
print(&biblio);
}
Err(e) => {
eprintln!("Error retrieving URL {url}: {e}");
process::exit(1);
}
}
}
}

fn print(biblio: &Bibliography) {
println!("@{}{{{},", biblio.entry_type(), biblio.citation_key());
biblio.tags().iter().with_position().for_each(|item| {
match item {
Position::First((key, value)) | Position::Middle((key, value)) => {
println!(" {key:9} = {{{value}}},");
}
Position::Last((key, value)) | Position::Only((key, value)) => {
println!(" {key:9} = {{{value}}}");
}
}
});
println!("}}\n");
}
21 changes: 12 additions & 9 deletions src/doi2bib
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,16 @@
#?
#? License:
#?
#? doi2bib <https://github.com/schneiderfelipe/doi2bib>
#? doi2bib <https://github.com/schneiderfelipe/doi>
#? is licensed under the MIT License.

while getopts ":hv" opt "$@"; do
case $opt in
h) # help
h) # help
grep "^#?" "$0" | cut -c 4-
exit 0
;;
v) # version
v) # version
grep "^#? doi2bib" "$0" | cut -c 4-
exit 0
;;
Expand All @@ -64,18 +64,21 @@ while getopts ":hv" opt "$@"; do
done

# recover $@
shift $((OPTIND-1))
shift $((OPTIND - 1))

# we consider everything after the command a list of DOIs.
for doi in "$@"; do
# we do some encoding as needed.
doi=${doi//+/%2B}
http_headers="Accept: text/bibliography; style=bibtex"

echo "$http_headers"
echo

# we retrieve the data from https://doi.org/
curl -s -LH "$http_headers" "https://doi.org/${doi}" | \
sed -e $'s/^ *//' \
-e $'s/}, /},\\\n /g' \
-e $'s/, /,\\\n /1' \
-e $'s/}}$/}\\\n}\\\n/'
curl -LH "$http_headers" "https://doi.org/${doi}" \
| sed -e $'s/^ *//' \
-e $'s/}, /},\\\n /g' \
-e $'s/, /,\\\n /1' \
-e $'s/}}$/}\\\n}\\\n/'
done
Loading