Skip to content

Commit

Permalink
Change publisher to dictionary (typst#105)
Browse files Browse the repository at this point in the history
  • Loading branch information
DerDrodt authored and danilasar committed Dec 31, 2024
1 parent f9815b9 commit aa53ac3
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 21 deletions.
11 changes: 6 additions & 5 deletions docs/file-format.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,9 @@ Parents can also appear as standalone items and can have parents themselves. Thi
plaque:
type: Misc
title: Informational plaque about Jacoby's 1967 photos
publisher: Stiftung Reinbeckhallen
location: Berlin, Germany
publisher:
name: Stiftung Reinbeckhallen
location: Berlin, Germany
date: 2020
parent:
type: Artwork
Expand Down Expand Up @@ -231,16 +232,16 @@ This section lists all possible fields and data types for them.

| | |
|------------------|-----------------------------------------------------------|
| **Data type:** | formattable string |
| **Data type:** | publisher |
| **Description:** | publisher of the item |
| **Example:** | `publisher: Penguin Books` |
| **Example:** | `publisher: Penguin Books` or `publisher:<br> name: Penguin Books<br> location: London` |

#### `location`

| | |
|------------------|-----------------------------------------------------------|
| **Data type:** | formattable string |
| **Description:** | location at which the item was published or created |
| **Description:** | location at which an entry is physically located or took place. For the location where an item was published, see `publisher`. |
| **Example:** | `location: Lahore, Pakistan` |

#### `organization`
Expand Down
15 changes: 9 additions & 6 deletions src/csl/taxonomy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use std::cmp;
use std::str::FromStr;

use crate::types::{
ChunkedString, Date, EntryType, MaybeTyped, Numeric, Person, PersonRole, StringChunk,
ChunkedString, Date, EntryType, MaybeTyped, Numeric, Person, PersonRole, Publisher,
StringChunk,
};
use crate::{Entry, PageRanges};
use citationberg::taxonomy::{
Expand Down Expand Up @@ -309,11 +310,12 @@ impl EntryLike for Entry {
StandardVariable::OriginalPublisher => entry
.get_original()
.and_then(|e| e.publisher())
.map(|f| f.select(form))
.and_then(Publisher::name)
.map(|n| n.select(form))
.map(Cow::Borrowed),
StandardVariable::OriginalPublisherPlace => entry
.get_original()
.and_then(|e| e.publisher().and_then(|_| e.location()))
.and_then(|e| e.publisher().and_then(|p| p.location()))
.map(|f| f.select(form))
.map(Cow::Borrowed),
StandardVariable::OriginalTitle => entry
Expand All @@ -330,11 +332,12 @@ impl EntryLike for Entry {
}
StandardVariable::Publisher => entry
.map(|e| e.publisher())
.map(|f| f.select(form))
.and_then(Publisher::name)
.map(|n| n.select(form))
.map(Cow::Borrowed),
StandardVariable::PublisherPlace => entry
.map(|e| if e.publisher().is_some() { Some(e) } else { None })
.and_then(|e| e.location())
.map(|e| e.publisher())
.and_then(|p| p.location())
.map(|f| f.select(form))
.map(Cow::Borrowed),
StandardVariable::References => None,
Expand Down
16 changes: 9 additions & 7 deletions src/interop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -452,16 +452,18 @@ impl TryFrom<&tex::Entry> for Entry {
item.set_url(QualifiedUrl { value: url, visit_date: date });
}

if let Some(location) = map_res(entry.location())?.map(|d| d.into()) {
if let Some(publisher_name) =
map_res(entry.publisher())?.map(|pubs| comma_list(&pubs))
{
let location = map_res(entry.location())?.map(|d| d.into());
let publisher = Publisher::new(Some(publisher_name), location);
if let Some(parent) = book(&mut item, parent) {
parent.set_location(location);
parent.set_publisher(publisher);
} else {
item.set_location(location);
item.set_publisher(publisher);
}
}

if let Some(publisher) = map_res(entry.publisher())?.map(|pubs| comma_list(&pubs))
{
} else if let Some(location) = map_res(entry.location())?.map(|d| d.into()) {
let publisher = Publisher::new(None, Some(location));
if let Some(parent) = book(&mut item, parent) {
parent.set_publisher(publisher);
} else {
Expand Down
6 changes: 3 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -505,9 +505,9 @@ entry! {
#[serde(serialize_with = "serialize_one_or_many_opt")]
#[serde(deserialize_with = "deserialize_one_or_many_opt")]
"affiliated" => affiliated: Vec<PersonsWithRoles> | [PersonsWithRoles],
/// Publisher of the item.
"publisher" => publisher: FormatString,
/// Physical location at which the item was published or created.
/// Publisher of the item, which may have a name and a location.
"publisher" => publisher: Publisher,
/// Physical location at which an entry is physically located or took place.
"location" => location: FormatString,
/// Organization at/for which the item was created.
"organization" => organization: FormatString,
Expand Down
53 changes: 53 additions & 0 deletions src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,59 @@ impl Display for QualifiedUrl {
}
}

derive_or_from_str! {
/// A publisher, possibly with a location.
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Publisher where "FormatString string or dictionary with \"name\" and \"location\"" {
/// Publisher of the item.
name: Option<FormatString>,
/// Physical location at which the item was published or created.
location: Option<FormatString>,
}
}

impl Serialize for Publisher {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
if let Some(location) = &self.location {
let mut map = serializer.serialize_map(Some(2))?;
map.serialize_entry("name", &self.name)?;
map.serialize_entry("location", location)?;
map.end()
} else {
self.name.serialize(serializer)
}
}
}

impl Publisher {
/// Create a new publisher.
pub fn new(name: Option<FormatString>, location: Option<FormatString>) -> Self {
Self { name, location }
}

/// Publisher of the item.
pub fn name(&self) -> Option<&FormatString> {
self.name.as_ref()
}

/// Physical location at which the item was published or created.
pub fn location(&self) -> Option<&FormatString> {
self.location.as_ref()
}
}

impl FromStr for Publisher {
type Err = ChunkedStrParseError;

/// Creates a new publisher with `s` as its name and no location.
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Publisher::new(Some(FormatString::from_str(s)?), None))
}
}

/// A set of serial numbers like DOIs, ISBNs, or ISSNs.
/// Keys should be lowercase.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Hash)]
Expand Down

0 comments on commit aa53ac3

Please sign in to comment.