csl

package
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 24, 2025 License: BSD-3-Clause Imports: 18 Imported by: 0

README

CSL: Citation Style Language

CSL is used for managing citations for the major open source citation management systems, including zotero and mendeley, and replaces the outdated bibtex system that is specific to the latex framework.

This package reads and writes JSON formatted data files containing references, which can be exported from zotero or mendeley, in this format schema. This is the replacement for the .bib file from bibtex, for example.

The result is a set of Go structs that represent the data, with csl.Item representing a given reference item.

The main feature of CSL is the ability to define new reference styles in the CSL language, which unfortunately is rather complex and requires significant infrastructure to process, and there is no extant Go native implementation.

Therefore, for the time being (ever), we are just using hand-written generators in Go that create a Reference from an Item (i.e., the text that goes in the References section) and a Citation (the text that goes in the body of a document that cites the reference). The Styles type represents available styles, and there are Ref and Cite functions that take a style and an item to generate according to the style.

The KeyList type provides an ordered list of unique citation items, using the CitationKey field, which can be used for collecting items by processing source files for references, and adding only unique entries in usage order. Some citation styles use order, and others are alpha sorted, so this provides either option.

There are two different types of CiteStyles that handle Parenthetical references (which go in parentheses) (Smith et al., 1985) versus Narrative citations: Smith et al. (1985) in APA format.

APA: American Psychological Association

The default, primary style is APA, with the RefAPA and CiteAPA methods for generating a reference or a citation. References are generated in alpha sorted order.

Documentation

Overview

Package csl provides support for citation and reference generation using the industry-standard Citation Style Language.

Index

Constants

This section is empty.

Variables

View Source
var DefaultStyle = APA

DefaultStyle is the default citation and reference formatting style.

Functions

func Cite

func Cite(s Styles, cs CiteStyles, it *Item) string

Cite generates the citation text for given item, according to the given overall style an citation style.

func CiteAPA

func CiteAPA(cs CiteStyles, it *Item) string

CiteAPA generates a APA-style citation, as Last[ & Last|et al.] Year with a , before Year in Parenthetical style, and Parens around the Year in Narrative style.

func CiteDefault

func CiteDefault(cs CiteStyles, it *Item) string

CiteDefault generates the citation text for given item, according to the DefaultStyle overall style, and given CiteStyles.

func EnsurePeriod

func EnsurePeriod(s string) string

EnsurePeriod returns a string that ends with a . if it doesn't already end in some form of punctuation.

func ExtractMarkdownCites

func ExtractMarkdownCites(files []string, src, cited *KeyList) error

ExtractMarkdownCites extracts markdown citations in the format [@Ref; @Ref] from given list of .md files, looking up in given source KeyList, adding to cited.

func NameFamilyGiven

func NameFamilyGiven(nm *Name) (family, given string)

NameFamilyGiven returns the family and given names from given name record, parsing what is available if not already parsed. todo: add suffix stuff!

func NamesCiteEtAl

func NamesCiteEtAl(nms []Name) string

NamesCiteEtAl returns a list of names formatted for a citation within a document, as Last [et al..] or Last & Last if exactly two authors.

func NamesFirstInitialLastCommaAmpersand

func NamesFirstInitialLastCommaAmpersand(nms []Name) string

NamesFirstInitialLastCommaAmpersand returns a list of names formatted as a string, in the format: A.B. Last, C.D., Last & L.M. Last

func NamesLastFirstInitialCommaAmpersand

func NamesLastFirstInitialCommaAmpersand(nms []Name) string

NamesLastFirstInitialCommaAmpersand returns a list of names formatted as a string, in the format: Last, F., Last, F., & Last., F.

func Ref

func Ref(s Styles, it *Item) rich.Text

Ref generates the reference text for given item, according to the given style.

func RefAPA

func RefAPA(it *Item) rich.Text

RefAPA generates an APA-style reference entry from the given item, with rich.Text formatting of italics around the source, volume, and spans for each separate chunk. Use Join method to get full raw text.

func RefAPAArticle

func RefAPAArticle(it *Item) rich.Text

func RefAPABook

func RefAPABook(it *Item) rich.Text

func RefAPAChapter

func RefAPAChapter(it *Item) rich.Text

func RefAPAMisc

func RefAPAMisc(it *Item) rich.Text

func RefAPAThesis

func RefAPAThesis(it *Item) rich.Text
func RefLinks(it *Item, tx *rich.Text)

func SaveItems

func SaveItems(items []Item, filename string) error

SaveItems saves items to given filename.

func SaveKeyList

func SaveKeyList(kl *KeyList, filename string) error

SaveKeyList saves items to given filename.

func WriteRefsMarkdown

func WriteRefsMarkdown(w io.Writer, kl *KeyList, sty Styles) error

WriteRefsMarkdown writes references from given KeyList to a markdown file.

Types

type CiteStyles

type CiteStyles int32 //enums:enum

CiteStyles are different types of citation styles that are supported by some formatting Styles.

const (
	// Parenthetical means that the citation is placed within parentheses.
	// This is default for most styles. In the APA style for example, it
	// adds a comma before the year, e.g., "(Smith, 1989)".
	// Note that the parentheses or other outer bracket syntax are NOT
	// generated directly, because often multiple are included together
	// in the same group.
	Parenthetical CiteStyles = iota

	// Narrative is an active, "inline" form of citation where the cited
	// content is used as the subject of a sentence. In the APA style this
	// puts the year in parentheses, e.g., "Smith (1989) invented the..."
	// In this case the parentheses are generated.
	Narrative
)
const CiteStylesN CiteStyles = 2

CiteStylesN is the highest valid value for type CiteStyles, plus one.

func CiteStylesValues

func CiteStylesValues() []CiteStyles

CiteStylesValues returns all possible values for the type CiteStyles.

func (CiteStyles) Desc

func (i CiteStyles) Desc() string

Desc returns the description of the CiteStyles value.

func (CiteStyles) Int64

func (i CiteStyles) Int64() int64

Int64 returns the CiteStyles value as an int64.

func (CiteStyles) MarshalText

func (i CiteStyles) MarshalText() ([]byte, error)

MarshalText implements the encoding.TextMarshaler interface.

func (*CiteStyles) SetInt64

func (i *CiteStyles) SetInt64(in int64)

SetInt64 sets the CiteStyles value from an int64.

func (*CiteStyles) SetString

func (i *CiteStyles) SetString(s string) error

SetString sets the CiteStyles value from its string representation, and returns an error if the string is invalid.

func (CiteStyles) String

func (i CiteStyles) String() string

String returns the string representation of this CiteStyles value.

func (*CiteStyles) UnmarshalText

func (i *CiteStyles) UnmarshalText(text []byte) error

UnmarshalText implements the encoding.TextUnmarshaler interface.

func (CiteStyles) Values

func (i CiteStyles) Values() []enums.Enum

Values returns all possible values for the type CiteStyles.

type Date

type Date struct {
	DateParts [][]any `json:"date-parts,omitempty"`
	Season    any     `json:"season,omitempty"`
	Circa     string  `json:"circa,omitempty"`
	Literal   string  `json:"literal,omitempty"`
	Raw       string  `json:"raw,omitempty"`
}

The CSL input model supports two different date representations: an EDTF string (preferred), and a more structured alternative.

func (*Date) Year

func (dt *Date) Year() string

type File

type File struct {

	// File name, full path.
	File string

	// Items from the file, as a KeyList for easy citation lookup.
	Items *KeyList

	// mod time for loaded file, to detect updates.
	Mod time.Time
}

File maintains a record for a CSL file.

func (*File) Open

func (fl *File) Open(fname string) error

Open [re]opens the given filename, looking on standard BIBINPUTS or TEXINPUTS env var paths if not found locally. If Mod >= mod timestamp on the file, and is already loaded, then nothing happens (already have it), but otherwise it parses the file and puts contents in Items.

type Files

type Files map[string]*File

Files is a map of CSL items keyed by file name.

func (*Files) Open

func (fl *Files) Open(fname string) (*File, error)

Open [re]opens the given filename, looking on standard BIBINPUTS or TEXINPUTS env var paths if not found locally. If Mod >= mod timestamp on the file, and Items is already loaded, then nothing happens (already have it), but otherwise it parses the file and puts contents in Items field.

type Item

type Item struct {
	Type                     Types          `json:"type"`
	ID                       string         `json:"id"`
	CitationKey              string         `json:"citation-key,omitempty"`
	Categories               []string       `json:"categories,omitempty"`
	Language                 string         `json:"language,omitempty"`
	JournalAbbreviation      string         `json:"journal-abbreviation,omitempty"`
	ShortTitle               string         `json:"shortTitle,omitempty"`
	Author                   []Name         `json:"author,omitempty"`
	Chair                    []Name         `json:"chair,omitempty"`
	CollectionEditor         []Name         `json:"collection-editor,omitempty"`
	Compiler                 []Name         `json:"compiler,omitempty"`
	Composer                 []Name         `json:"composer,omitempty"`
	ContainerAuthor          []Name         `json:"container-author,omitempty"`
	Contributor              []Name         `json:"contributor,omitempty"`
	Curator                  []Name         `json:"curator,omitempty"`
	Director                 []Name         `json:"director,omitempty"`
	Editor                   []Name         `json:"editor,omitempty"`
	EditorDirector           []Name         `json:"editorial-director,omitempty"`
	ExecutiveProducer        []Name         `json:"executive-producer,omitempty"`
	Guest                    []Name         `json:"guest,omitempty"`
	Host                     []Name         `json:"host,omitempty"`
	Interviewer              []Name         `json:"interviewer,omitempty"`
	Illustrator              []Name         `json:"illustrator,omitempty"`
	Narrator                 []Name         `json:"narrator,omitempty"`
	Organizer                []Name         `json:"organizer,omitempty"`
	OriginalAuthor           []Name         `json:"original-author,omitempty"`
	Performer                []Name         `json:"performer,omitempty"`
	Producer                 []Name         `json:"producer,omitempty"`
	Recipient                []Name         `json:"recipient,omitempty"`
	ReviewedAuthor           []Name         `json:"reviewed-author,omitempty"`
	ScriptWriter             []Name         `json:"script-writer,omitempty"`
	SeriesCreator            []Name         `json:"series-creator,omitempty"`
	Translator               []Name         `json:"translator,omitempty"`
	Accessed                 Date           `json:"accessed,omitempty"`
	AvailableDate            Date           `json:"available-date,omitempty"`
	EventDate                Date           `json:"event-date,omitempty"`
	Issued                   Date           `json:"issued,omitempty"`
	OriginalDate             Date           `json:"original-date,omitempty"`
	Submitted                Date           `json:"submitted,omitempty"`
	Abstract                 string         `json:"abstract,omitempty"`
	Annote                   string         `json:"annote,omitempty"`
	Archive                  string         `json:"archive,omitempty"`
	ArchiveCollection        string         `json:"archive_collection,omitempty"`
	ArchiveLocation          string         `json:"archive_location,omitempty"`
	ArchivePlace             string         `json:"archive-place,omitempty"`
	Authority                string         `json:"authority,omitempty"`
	CallNumber               string         `json:"call-number,omitempty"`
	ChapterNumber            string         `json:"chapter-number,omitempty"`
	CitationNumber           string         `json:"citation-number,omitempty"`
	CitationLabel            string         `json:"citation-label,omitempty"`
	CollectionNumber         string         `json:"collection-number,omitempty"`
	CollectionTitle          string         `json:"collection-title,omitempty"`
	ContainerTitle           string         `json:"container-title,omitempty"`
	ContainerTitleShort      string         `json:"container-title-short,omitempty"`
	Dimensions               string         `json:"dimensions,omitempty"`
	Division                 string         `json:"division,omitempty"`
	DOI                      string         `json:"DOI,omitempty"`
	Edition                  string         `json:"edition,omitempty"`
	Event                    string         `json:"event,omitempty"`
	EventTitle               string         `json:"event-title,omitempty"`
	EventPlace               string         `json:"event-place,omitempty"`
	FirstReferenceNoteNumber string         `json:"first-reference-note-number,omitempty"`
	Genre                    string         `json:"genre,omitempty"`
	ISBN                     string         `json:"ISBN,omitempty"`
	ISSN                     string         `json:"ISSN,omitempty"`
	Issue                    string         `json:"issue,omitempty"`
	Jurisdiction             string         `json:"jurisdiction,omitempty"`
	Keyword                  string         `json:"keyword,omitempty"`
	Locator                  string         `json:"locator,omitempty"`
	Medium                   string         `json:"medium,omitempty"`
	Note                     string         `json:"note,omitempty"`
	Number                   string         `json:"number,omitempty"`
	NumberOfPages            string         `json:"number-of-pages,omitempty"`
	NumberOfVolumes          string         `json:"number-of-volumes,omitempty"`
	OriginalPublisher        string         `json:"original-publisher,omitempty"`
	OriginalPublisherPlace   string         `json:"original-publisher-place,omitempty"`
	OriginalTitle            string         `json:"original-title,omitempty"`
	Page                     string         `json:"page,omitempty"`
	PageFirst                string         `json:"page-first,omitempty"`
	Part                     string         `json:"part,omitempty"`
	PartTitle                string         `json:"part-title,omitempty"`
	PMCID                    string         `json:"PMCID,omitempty"`
	PMID                     string         `json:"PMID,omitempty"`
	Printing                 string         `json:"printing,omitempty"`
	Publisher                string         `json:"publisher,omitempty"`
	PublisherPlace           string         `json:"publisher-place,omitempty"`
	References               string         `json:"references,omitempty"`
	ReviewedGenre            string         `json:"reviewed-genre,omitempty"`
	ReviewedTitle            string         `json:"reviewed-title,omitempty"`
	Scale                    string         `json:"scale,omitempty"`
	Section                  string         `json:"section,omitempty"`
	Source                   string         `json:"source,omitempty"`
	Status                   string         `json:"status,omitempty"`
	Supplement               string         `json:"supplement,omitempty"`
	Title                    string         `json:"title,omitempty"`
	TitleShort               string         `json:"title-short,omitempty"`
	URL                      string         `json:"URL,omitempty"`
	Version                  string         `json:"version,omitempty"`
	Volume                   string         `json:"volume,omitempty"`
	VolumeTitle              string         `json:"volume-title,omitempty"`
	VolumeTitleShort         string         `json:"volume-title-short,omitempty"`
	YearSuffix               string         `json:"year-suffix,omitempty"`
	Custom                   map[string]any `json:"custom,omitempty"`
}

Item represents one item of CSL data.

func Open

func Open(filename string) ([]Item, error)

Open opens CSL data items from a .json formatted CSL file.

func OpenFS

func OpenFS(fsys fs.FS, filename string) ([]Item, error)

OpenFS opens CSL data items from a .json formatted CSL file from given filesystem.

func Refs

func Refs(s Styles, kl *KeyList) ([]rich.Text, []*Item)

Refs returns a list of references and matching items according to the given Styles style.

func RefsAPA

func RefsAPA(kl *KeyList) ([]rich.Text, []*Item)

RefsAPA generates a list of APA-style reference entries and correspondingly ordered items for given keylist. APA uses alpha sort order.

func RefsDefault

func RefsDefault(kl *KeyList) ([]rich.Text, []*Item)

RefsDefault returns a list of references and matching items according to the DefaultStyle.

type KeyList

type KeyList struct {
	keylist.List[string, *Item]
}

KeyList is an ordered list of citation [Item]s, which should be used to collect items by unique citation keys.

func GenerateMarkdown

func GenerateMarkdown(dir, refFile, heading string, kl *KeyList, sty Styles) (*KeyList, error)

GenerateMarkdown extracts markdown citations in the format [@Ref; @Ref] from .md markdown files in given directory, looking up in given source KeyList, and writing the results in given style to given .md file (references.md default). Heading is written first: must include the appropriate markdown heading level (## typically). Returns the KeyList of references that were cited.

func NewKeyList

func NewKeyList(items []Item) *KeyList

NewKeyList returns a KeyList from given list of [Item]s.

func (*KeyList) AlphaKeys

func (kl *KeyList) AlphaKeys() []string

AlphaKeys returns an alphabetically sorted list of keys.

func (*KeyList) PrettyString

func (kl *KeyList) PrettyString() string

PrettyString pretty prints the items using default style.

type Name

type Name struct {
	Family              string `json:"family,omitempty"`
	Given               string `json:"given,omitempty"`
	DroppingParticle    string `json:"dropping-particle,omitempty"`
	NonDroppingParticle string `json:"non-dropping-particle,omitempty"`
	Suffix              string `json:"suffix,omitempty"`
	CommaSuffix         any    `json:"comma-suffix,omitempty"`
	StaticOrdering      any    `json:"static-ordering,omitempty"`
	Literal             string `json:"literal,omitempty"`
	ParseNames          any    `json:"parse-names,omitempty"`
}

Name represents a persons name.

type Styles

type Styles int32 //enums:enum

Styles are CSL citation and reference formatting styles.

const (
	APA Styles = iota
)
const StylesN Styles = 1

StylesN is the highest valid value for type Styles, plus one.

func StylesValues

func StylesValues() []Styles

StylesValues returns all possible values for the type Styles.

func (Styles) Desc

func (i Styles) Desc() string

Desc returns the description of the Styles value.

func (Styles) Int64

func (i Styles) Int64() int64

Int64 returns the Styles value as an int64.

func (Styles) MarshalText

func (i Styles) MarshalText() ([]byte, error)

MarshalText implements the encoding.TextMarshaler interface.

func (*Styles) SetInt64

func (i *Styles) SetInt64(in int64)

SetInt64 sets the Styles value from an int64.

func (*Styles) SetString

func (i *Styles) SetString(s string) error

SetString sets the Styles value from its string representation, and returns an error if the string is invalid.

func (Styles) String

func (i Styles) String() string

String returns the string representation of this Styles value.

func (*Styles) UnmarshalText

func (i *Styles) UnmarshalText(text []byte) error

UnmarshalText implements the encoding.TextUnmarshaler interface.

func (Styles) Values

func (i Styles) Values() []enums.Enum

Values returns all possible values for the type Styles.

type Types

type Types int32 //enums:enum -transform kebab

Types are CSL content types.

const (
	Article Types = iota
	ArticleJournal
	ArticleMagazine
	ArticleNewspaper
	Bill
	Book
	Broadcast
	Chapter
	Classic
	Collection
	Dataset
	Document
	Entry
	EntryDictionary
	EntryEncyclopedia
	Event
	Figure
	Graphic
	Hearing
	Interview
	LegalCase
	Legislation
	Manuscript
	Map
	MotionPicture
	MusicalScore
	Pamphlet
	PaperConference
	Patent
	Performance
	Periodical
	PersonalCommunication
	Post
	PostWeblog
	Regulation
	Report
	Review
	ReviewBook
	Software
	Song
	Speech
	Standard
	Thesis
	Treaty
	Webpage
)
const TypesN Types = 45

TypesN is the highest valid value for type Types, plus one.

func TypesValues

func TypesValues() []Types

TypesValues returns all possible values for the type Types.

func (Types) Desc

func (i Types) Desc() string

Desc returns the description of the Types value.

func (Types) Int64

func (i Types) Int64() int64

Int64 returns the Types value as an int64.

func (Types) MarshalText

func (i Types) MarshalText() ([]byte, error)

MarshalText implements the encoding.TextMarshaler interface.

func (*Types) SetInt64

func (i *Types) SetInt64(in int64)

SetInt64 sets the Types value from an int64.

func (*Types) SetString

func (i *Types) SetString(s string) error

SetString sets the Types value from its string representation, and returns an error if the string is invalid.

func (Types) String

func (i Types) String() string

String returns the string representation of this Types value.

func (*Types) UnmarshalText

func (i *Types) UnmarshalText(text []byte) error

UnmarshalText implements the encoding.TextUnmarshaler interface.

func (Types) Values

func (i Types) Values() []enums.Enum

Values returns all possible values for the type Types.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL