Skip to content

Commit

Permalink
Allow also citations with @
Browse files Browse the repository at this point in the history
  • Loading branch information
francisco-perez-sorrosal committed Aug 18, 2021
1 parent 496392c commit 91e181c
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 11 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ A [mdBook](https://github.com/rust-lang/mdBook) plugin for creating a bibliograp
[![Crate](https://img.shields.io/crates/v/mdbook-bib.svg)](https://crates.io/crates/mdbook-bib)
![Crates.io](https://img.shields.io/crates/d/mdbook-bib?style=social&link=https://crates.io/crates/mdbook-bib)

## Features

- Add citations from your BibLaText files
- Automatically download your public bibliography from Zotero and cite it
- Allows defining a template for the citations shown in the references page

## Basic Install

If you have [mdbook](https://github.com/rust-lang/mdBook) installed just do:
Expand Down Expand Up @@ -39,6 +45,11 @@ Now you can add references/citations to the citation-keys appearing in the `.bib
```handlebars
{{#cite my-citation-key}}
```
or simply with:

```handlebars
@@my-citation-key
```

See other configuration options in the [Config section of the manual](https://francisco-perez-sorrosal.github.io/mdbook-bib/config.html).

Expand Down
9 changes: 9 additions & 0 deletions manual/src/bibliography.bib
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,12 @@ @book{mdBook
langid = {english},
abstract = {mdBook is a command line tool and Rust crate to create books using Markdown (as by the CommonMark specification) files. It's very similar to Gitbook but written in Rust.}
}

@book{Klabnik2018,
author = {Klabnik, Steve and Nichols, Carol},
title = {The Rust Programming Language},
year = {2018},
isbn = {1593278284},
publisher = {No Starch Press},
url = {https://doc.rust-lang.org/book/}
}
8 changes: 3 additions & 5 deletions manual/src/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,10 @@ Zotero account.

## Add References/Citations to the Bibliography

In your markdown files, create references/citations to the citation-keys included in the `.bib` file with the
following syntax:
In your markdown files, create references/citations to the citation-keys included in the `.bib` file with any of these two options:

```handlebars
{{#cite my-citation-key}}
```
1. Surround the citation key with the `{{#cite` and `}}` delimiters
2. Prepend the citation key with two `@` characters

## Configure your own Style for Bibliography Entries

Expand Down
2 changes: 1 addition & 1 deletion manual/src/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[![Test status](https://github.com/francisco-perez-sorrosal/mdbook-bib/actions/workflows/test.yml/badge.svg)](https://github.com/francisco-perez-sorrosal/mdbook-bib/actions/workflows/test.yml)
[![MPL-2.0 License](https://img.shields.io/github/license/francisco-perez-sorrosal/mdbook-bib)](https://github.com/francisco-perez-sorrosal/mdbook-bib/blob/master/LICENSE)

**mdbook-bib** is a {{#cite mdBook}} plugin for creating a bibliography & reference its citations in your books.
**mdbook-bib** is a {{#cite mdBook}} plugin for creating a bibliography & reference its citations in your books. mdBook is written in the Rust language @@Klabnik2018.

### GitHub project

Expand Down
33 changes: 30 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ impl Bibiography {
if let BookItem::Chapter(ref mut ch) = *section {
if let Some(ref chapter_path) = ch.path {
info!(
"Replacing placeholders({{#cite ..}}) in {}",
"Replacing placeholders: {{#cite ...}} and @@citation in {}",
chapter_path.as_path().display()
);
let new_content = replace_all_placeholders(
Expand Down Expand Up @@ -412,7 +412,20 @@ fn replace_all_placeholders<'a>(
previous_end_index = placeholder.end_index;

match placeholder.placeholder_type {
PlaceholderType::Cite(ref cite) => {
PlaceholderType::Cite(ref cite) | PlaceholderType::AtCite(ref cite) => {
cited.insert(cite.to_owned());
}
}
}
// TODO Maybe look how to combine two iterators to avoid the duplicated code below
for placeholder in find_at_placeholders(s) {
replaced.push_str(&s[previous_end_index..placeholder.start_index]);
replaced
.push_str(&placeholder.render_with_path(bib_as_html_filepath.to_owned(), bibliography));
previous_end_index = placeholder.end_index;

match placeholder.placeholder_type {
PlaceholderType::Cite(ref cite) | PlaceholderType::AtCite(ref cite) => {
cited.insert(cite.to_owned());
}
}
Expand All @@ -426,9 +439,14 @@ fn parse_cite(cite: &str) -> PlaceholderType {
PlaceholderType::Cite(cite.to_owned())
}

fn parse_at_cite(cite: &str) -> PlaceholderType {
PlaceholderType::AtCite(cite.to_owned())
}

#[derive(PartialEq, Debug, Clone)]
enum PlaceholderType {
Cite(String),
AtCite(String),
}

#[derive(PartialEq, Debug, Clone)]
Expand All @@ -448,6 +466,7 @@ impl<'a> Placeholder<'a> {

match (typ.as_str(), file_arg) {
("cite", Some(cite)) => Some(parse_cite(cite)),
("@@", Some(cite)) => Some(parse_at_cite(cite)),
_ => None,
}
}
Expand All @@ -470,7 +489,7 @@ impl<'a> Placeholder<'a> {
bibliography: &HashMap<String, BibItem>,
) -> String {
match self.placeholder_type {
PlaceholderType::Cite(ref cite) => {
PlaceholderType::Cite(ref cite) | PlaceholderType::AtCite(ref cite) => {
if bibliography.contains_key(cite) {
format!(
"\\[[{}]({}#{})\\]",
Expand Down Expand Up @@ -520,5 +539,13 @@ fn find_placeholders(contents: &str) -> PlaceholderIter<'_> {
PlaceholderIter(RE.captures_iter(contents))
}

const AT_REF_PATTERN: &str = r##"(@@)([^\[\]\s\.,;"#'()={}%]+)"##;
fn find_at_placeholders(contents: &str) -> PlaceholderIter<'_> {
lazy_static! {
static ref REF_REGEX: Regex = Regex::new(AT_REF_PATTERN).unwrap();
}
PlaceholderIter(REF_REGEX.captures_iter(contents))
}

#[cfg(test)]
mod tests;
25 changes: 23 additions & 2 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ use std::{
// use std::{println as info, println as warn};
use tempfile::Builder as TempFileBuilder;

use crate::PlaceholderType::Cite;
use crate::PlaceholderType::{AtCite, Cite};
use crate::{
build_bibliography, extract_date, find_placeholders, load_bibliography,
build_bibliography, extract_date, find_at_placeholders, find_placeholders, load_bibliography,
replace_all_placeholders, BibItem, Config,
};
use toml::value::Table;
Expand Down Expand Up @@ -52,6 +52,10 @@ const DUMMY_TEXT_WITH_A_VALID_AND_AN_INVALID_CITE_PLACEHOLDERS: &str = r#"
this is a dumb text that includes valid and invalid citations like {{ #cite fps }} and {{ #cite im_not_there }}
"#;

const DUMMY_TEXT_WITH_A_VALID_AT_CITE_PLACEHOLDER: &str = r#"
this is a dumb text that includes a valid citation with double @, as in @@fps.
"#;

const DUMMY_TEXT_WITH_2_UNKNOWN_PLACEHOLDERS: &str = r#"
this is a dumb text that includes invalid placeholders like {{ #zoto uhmmmm }} and {{ #peto ahhhhmmm }}
"#;
Expand Down Expand Up @@ -183,6 +187,7 @@ fn find_only_citation_placeholders() {
for plh in plhs {
match plh.placeholder_type {
Cite(_) => items += 1,
AtCite(_) => items += 1,
};
}
assert_eq!(items, 2);
Expand All @@ -195,6 +200,22 @@ fn find_only_citation_placeholders() {
}
assert_eq!(items, 0);
}

#[test]
fn find_only_at_citation_placeholders() {
// As long as placeholders are related to cites, they are found, independently of whether they
// are valid or not
let plhs = find_at_placeholders(DUMMY_TEXT_WITH_A_VALID_AT_CITE_PLACEHOLDER);
let mut items = 0;
for plh in plhs {
match plh.placeholder_type {
Cite(_) => items += 1,
AtCite(_) => items += 1,
};
}
assert_eq!(items, 1);
}

use std::env;
#[test]
fn check_config_attributes() {
Expand Down

0 comments on commit 91e181c

Please sign in to comment.