initial version of better aligned bibliography
This commit is contained in:
+209
-23
@@ -1,27 +1,213 @@
|
||||
#import "@preview/alexandria:0.2.2": *
|
||||
#import "@preview/alexandria:0.2.2": alexandria, get-bibliography, load-bibliography
|
||||
|
||||
= Spis literatury
|
||||
// Global state
|
||||
#let used-refs = state("used-refs", ())
|
||||
|
||||
== Książki
|
||||
#bibliographyx(
|
||||
"Bibliography/Books.bib",
|
||||
prefix: "book-",
|
||||
title: none,
|
||||
style: "ieee",
|
||||
)
|
||||
// 1. Analizes and sets up the document
|
||||
#let bib-setup(body) = {
|
||||
show: alexandria(prefix: "cite:", read: path => read(path))
|
||||
|
||||
== Artykuły
|
||||
#bibliographyx(
|
||||
"Bibliography/Articles.bib",
|
||||
prefix: "article-",
|
||||
title: none,
|
||||
style: "ieee",
|
||||
)
|
||||
// Searching for references in document
|
||||
show ref: it => {
|
||||
let target = str(it.target)
|
||||
if target.starts-with("cite:") {
|
||||
let key = target.slice(5)
|
||||
used-refs.update(arr => if key not in arr { arr + (key,) } else { arr })
|
||||
context {
|
||||
let cites = used-refs.final()
|
||||
let bib = get-bibliography("cite:")
|
||||
let get-type(k) = {
|
||||
let e = bib.references.find(x => x.key == k)
|
||||
if e != none { lower(e.details.at("type", default: "")) } else { "" }
|
||||
}
|
||||
let is-book(t) = t == "book"
|
||||
let is-article(t) = t == "article" or t == "paper-conference" or t == "inproceedings"
|
||||
let is-other(t) = not is-book(t) and not is-article(t)
|
||||
|
||||
== Źródła internetowe i inne
|
||||
#bibliographyx(
|
||||
"Bibliography/Others.bib",
|
||||
prefix: "other-",
|
||||
title: none,
|
||||
style: "ieee",
|
||||
)
|
||||
let books = cites.filter(k => is-book(get-type(k)))
|
||||
let articles = cites.filter(k => is-article(get-type(k)))
|
||||
let others = cites.filter(k => is-other(get-type(k)))
|
||||
|
||||
let sorted = books + articles + others
|
||||
let idx = sorted.position(k => k == key)
|
||||
|
||||
if idx != none { link(it.target, [\[#(idx + 1)\]]) } else { [\[?\]] }
|
||||
}
|
||||
} else { it }
|
||||
}
|
||||
|
||||
body
|
||||
}
|
||||
|
||||
// 2. Bibliography rendering
|
||||
#let render-bib() = {
|
||||
load-bibliography("Bibliography.bib", prefix: "cite:", full: true, style: "ieee")
|
||||
|
||||
heading(level: 1)[Spis literatury]
|
||||
v(1em)
|
||||
|
||||
context {
|
||||
let cites = used-refs.final()
|
||||
if cites.len() > 0 {
|
||||
let bib = get-bibliography("cite:")
|
||||
let get-entry(k) = bib.references.find(e => e.key == k)
|
||||
|
||||
// custom implementation adapting the ZUT's formatting
|
||||
let format-custom(entry) = {
|
||||
let d = entry.details
|
||||
let entry-type = lower(d.at("type", default: ""))
|
||||
|
||||
let format-author(a) = {
|
||||
if type(a) == dictionary {
|
||||
let parts = ()
|
||||
if "given" in a { parts.push(str(a.given)) }
|
||||
if "family" in a { parts.push(str(a.family)) }
|
||||
if parts.len() > 0 { return parts.join(" ") }
|
||||
if "name" in a { return str(a.name) }
|
||||
return ""
|
||||
} else {
|
||||
let s = str(a)
|
||||
let parts = s.split(",")
|
||||
if parts.len() == 2 { return parts.at(1).trim() + " " + parts.at(0).trim() }
|
||||
return s
|
||||
}
|
||||
}
|
||||
|
||||
let raw-auth = d.at("author", default: ())
|
||||
let author-list = if type(raw-auth) == array {
|
||||
raw-auth.map(format-author)
|
||||
} else if raw-auth != none and raw-auth != "" {
|
||||
(format-author(raw-auth),)
|
||||
} else { () }
|
||||
|
||||
let authors = if author-list.len() > 1 {
|
||||
author-list.slice(0, -1).join(", ") + " i " + author-list.last()
|
||||
} else if author-list.len() == 1 { author-list.first() } else { "" }
|
||||
|
||||
let get-val(..keys) = {
|
||||
let extract(obj, k) = {
|
||||
if type(obj) != dictionary { return none }
|
||||
let v = obj.at(k, default: none)
|
||||
if v == none { return none }
|
||||
if type(v) == str { return v }
|
||||
if type(v) in (int, float) { return str(v) }
|
||||
if type(v) == array { return v.filter(x => type(x) in (str, int, float)).map(x => str(x)).join(", ") }
|
||||
if type(v) == dictionary {
|
||||
if "isbn" in v { return str(v.isbn) }
|
||||
if "value" in v { return str(v.value) }
|
||||
if "name" in v { return str(v.name) }
|
||||
if "text" in v { return str(v.text) }
|
||||
return ""
|
||||
}
|
||||
return ""
|
||||
}
|
||||
for k in keys.pos() {
|
||||
let res = extract(d, k)
|
||||
if res == none and "parent" in d { res = extract(d.parent, k) }
|
||||
if res != none and res != "" { return res }
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
let y = ""
|
||||
let m = ""
|
||||
let date-val = d.at("date", default: none)
|
||||
if type(date-val) == dictionary {
|
||||
y = str(date-val.at("year", default: ""))
|
||||
m = str(date-val.at("month", default: ""))
|
||||
} else if date-val != none { y = str(date-val) }
|
||||
if y == "" { y = get-val("year") }
|
||||
if m == "" { m = get-val("month") }
|
||||
|
||||
if m != "" {
|
||||
if m.match(regex("^\d+$")) != none {
|
||||
let idx = int(m)
|
||||
let months = (
|
||||
"",
|
||||
"sty.",
|
||||
"lut.",
|
||||
"mar.",
|
||||
"kwi.",
|
||||
"maj",
|
||||
"cze.",
|
||||
"lip.",
|
||||
"sie.",
|
||||
"wrz.",
|
||||
"paź.",
|
||||
"lis.",
|
||||
"gru.",
|
||||
)
|
||||
if idx >= 1 and idx <= 12 { m = months.at(idx) }
|
||||
}
|
||||
}
|
||||
let year = if m != "" { m + y } else { y }
|
||||
let title-txt = get-val("title")
|
||||
let series = get-val("collection-title", "series")
|
||||
let pub-place = get-val("location", "address", "publisher-place")
|
||||
let pub = get-val("publisher")
|
||||
let edition = get-val("edition")
|
||||
let volume = get-val("volume")
|
||||
let pages = get-val("page-range", "pages").replace("--", "–").replace("-", "–")
|
||||
let isbn = get-val("isbn", "ISBN", "serial-number", "number")
|
||||
let issue = get-val("issue", "number")
|
||||
let url = get-val("url")
|
||||
|
||||
if entry-type == "book" [
|
||||
#authors. #emph(title-txt).
|
||||
#if edition != "" { if edition.match(regex("^\d+$")) != none [#edition wyd. ] else [#edition. ] }
|
||||
#if volume != "" [T. #volume. ]
|
||||
#if series != "" [#series. ]
|
||||
#if pub-place != "" [#pub-place: ]
|
||||
#if pub != "" [#pub, ]
|
||||
#year#if pages != "" [, s. #pages].
|
||||
#if isbn != "" [ isbn: #isbn.]
|
||||
] else if entry-type == "article" or entry-type == "paper-conference" [
|
||||
#authors. „#title-txt”. W:#if volume != "" or issue != "" [ #volume#if issue != "" [.#issue]] (#year)#if pages != "" [, s. #pages].
|
||||
] else [
|
||||
#authors. #emph(title-txt).
|
||||
#if url != "" [ URL: #link(url)[#raw(url)].]
|
||||
]
|
||||
}
|
||||
|
||||
let get-type(k) = {
|
||||
let e = get-entry(k)
|
||||
if e != none { lower(e.details.at("type", default: "")) } else { "" }
|
||||
}
|
||||
|
||||
let is-book(t) = t == "book"
|
||||
let is-article(t) = t == "article" or t == "paper-conference" or t == "inproceedings"
|
||||
let is-other(t) = not is-book(t) and not is-article(t)
|
||||
|
||||
let render-group(title, keys, start-idx) = {
|
||||
if keys.len() > 0 [
|
||||
== #title
|
||||
#grid(
|
||||
columns: (auto, 1fr),
|
||||
column-gutter: 0.65em,
|
||||
row-gutter: 1em,
|
||||
..keys
|
||||
.enumerate()
|
||||
.map(((i, k)) => {
|
||||
let entry = get-entry(k)
|
||||
if entry == none { return () }
|
||||
let num = start-idx + i + 1
|
||||
// Pamiętaj: musisz użyć format-custom, który wkleiłeś wyżej!
|
||||
([\[#num\]], [#format-custom(entry)#label("cite:" + k)])
|
||||
})
|
||||
.flatten()
|
||||
)
|
||||
#v(1em)
|
||||
]
|
||||
}
|
||||
|
||||
let books = cites.filter(k => is-book(get-type(k)))
|
||||
let articles = cites.filter(k => is-article(get-type(k)))
|
||||
let others = cites.filter(k => is-other(get-type(k)))
|
||||
|
||||
// last parameter is start idx
|
||||
render-group("Książki", books, 0)
|
||||
render-group("Artykuły", articles, books.len())
|
||||
render-group("Źródła internetowe i inne", others, books.len() + articles.len())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user