├── .gitignore ├── LICENSE ├── README.md ├── Satyristes ├── bibyfi-IEEETran.satyh ├── bibyfi.satyh ├── example-bib.satyh ├── example ├── Makefile ├── cite-as-number.saty └── cite-with-name.saty ├── satysfi-bibyfi-doc.opam ├── satysfi-bibyfi.opam └── screenshot.png /.gitignore: -------------------------------------------------------------------------------- 1 | *.satysfi-aux 2 | *.pdf 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BiByFi 2 | *This project has been under developing. The API may be broken dramatically and suddenly* 3 | 4 | A bibliography framework for [SATySFi](https://github.com/gfngfn/SATySFi) 5 | 6 | This project is inspired by [cs-thesis](https://github.com/gfngfn/cs-thesis) and borrowing many codes from [it](https://github.com/gfngfn/cs-thesis). 7 | 8 | # Usage 9 | See [examples](https://github.com/namachan10777/master/example). 10 | 11 | # Install 12 | ```sh 13 | opam install satysfi-bibyfi 14 | ``` 15 | 16 | ![screenshot](https://raw.githubusercontent.com/namachan10777/bibyfi/master/screenshot.png) 17 | -------------------------------------------------------------------------------- /Satyristes: -------------------------------------------------------------------------------- 1 | (version "0.0.2") 2 | (library 3 | (name "bibyfi") 4 | (version "0.0.1") 5 | (sources 6 | ( 7 | (package "bibyfi.satyh" "./bibyfi.satyh") 8 | (package "bibyfi-IEEETran.satyh" "./bibyfi-IEEETran.satyh") 9 | ) 10 | ) 11 | (opam "satysfi-bibyfi.opam")) 12 | (libraryDoc 13 | (name "bibyfi-doc") 14 | (version "0.0.1") ; 15 | (workingDirectory "example") 16 | (build 17 | ((make "-f" "Makefile"))) 18 | (sources 19 | ((doc "LICENSE" "LICENSE") 20 | (doc "README.md" "README.md") 21 | (doc "example-bib.satyh" "example-bib.satyh") 22 | (doc "examples/cite-as-number.saty" "example/cite-as-number.saty") 23 | (doc "examples/cite-as-number.pdf" "example/cite-as-number.pdf") 24 | (doc "examples/cite-with-name.saty" "example/cite-with-name.saty") 25 | (doc "examples/cite-with-name.pdf" "example/cite-with-name.pdf"))) 26 | (opam "satysfi-bibyfi-doc.opam") 27 | (dependencies ((bibyfi ())))) 28 | -------------------------------------------------------------------------------- /bibyfi-IEEETran.satyh: -------------------------------------------------------------------------------- 1 | @import: bibyfi 2 | 3 | type bibyfi-ieee-tran-cfg = (| 4 | name-shrink: bool; 5 | et-al: bool; 6 | journal-abbr : (string * string) list; 7 | |) 8 | 9 | module BiByFiIEEETran : sig 10 | val theme : bibyfi-ieee-tran-cfg -> context -> int -> bibyfi-item -> block-boxes 11 | end = struct 12 | 13 | let font-ratio-latin = 1. 14 | let book-title-font = (`Junicode-it`, font-ratio-latin, 0.) 15 | 16 | let mk-index ctx index = 17 | let s = `[` ^ arabic index ^ `] `# in 18 | read-inline ctx (embed-string s) 19 | 20 | let-inline ctx \book-title it = 21 | let ctx = ctx 22 | |> set-font Latin book-title-font 23 | in 24 | read-inline ctx it 25 | 26 | let mk-pages (s, e) = 27 | let it-s = embed-string s in 28 | let it-e = embed-string e in 29 | {pp. #it-s;–#it-e;} 30 | 31 | let mk-year-month year month = 32 | let it-year = embed-string year in 33 | match month with 34 | | None -> {#it-year;} 35 | | Some(month) -> ( 36 | let it-month = embed-string month in 37 | {#it-month;\ #it-year;} 38 | ) 39 | 40 | let-inline ctx \space l = 41 | inline-skip l 42 | 43 | let endmarkers-en = 44 | List.map string-explode [`.`; `?`; `!`] 45 | 46 | let-rec head-match xs ys = match (xs, ys) with 47 | | ([], []) -> true 48 | | (x :: xs, y :: ys) -> x == y && head-match xs ys 49 | | _ -> true 50 | 51 | let tail-match xs ys = 52 | head-match (List.reverse xs) (List.reverse ys) 53 | 54 | let mk-title title sep = 55 | let it-title = embed-string title in 56 | let title = string-explode title in 57 | let title-has-endmark = 58 | endmarkers-en 59 | |> List.map (fun pattern -> tail-match pattern title) 60 | |> List.fold-left ( || ) false 61 | in 62 | if title-has-endmark 63 | then {“#it-title;”} 64 | else {“#it-title;#sep;”} 65 | 66 | let mk-publisher addr publisher = match addr with 67 | | Some(addr) -> ( 68 | let it-addr = embed-string addr in 69 | let it-publisher = embed-string publisher in 70 | {#it-addr;:\ #it-publisher;}) 71 | | None -> ( 72 | let it-publisher = embed-string publisher in 73 | {#it-publisher;}) 74 | 75 | let mk-title-elem title = 76 | Some(| 77 | not-tail = fun sep -> mk-title title sep ; 78 | tail = fun periodo -> mk-title title periodo; 79 | |) 80 | 81 | let mk-authors et-al shrinked authors = 82 | let authors = 83 | if shrinked 84 | then authors |> List.map BiByFi.shrink-name 85 | else authors 86 | in 87 | let authors = 88 | if et-al 89 | then (match authors with 90 | | [] -> [] 91 | | [n] -> [n] 92 | | [n1;n2] -> [n1;n2] 93 | | n1 :: _ -> [n1 ^ #` et al.`]) 94 | else 95 | authors 96 | in 97 | BiByFi.join-authors {\ and\ } {,\ } {and\ } (List.map embed-string authors) 98 | 99 | let mk-journal abbrs journal = 100 | let-rec search abbrs = match abbrs with 101 | | [] -> journal 102 | | (full, abbr) :: last -> if string-same full journal 103 | then abbr 104 | else search last 105 | in 106 | let it-journal = embed-string (search abbrs) in 107 | {\book-title{#it-journal;}} 108 | 109 | let mk-article cfg r = 110 | let it-note = Option.map embed-string r#note in 111 | let it-key = Option.map embed-string r#key in 112 | BiByFi.join-elements {,} {.} {\ } [ 113 | BiByFi.lift-elem (mk-authors cfg#et-al cfg#name-shrink r#author); 114 | mk-title-elem r#title; 115 | BiByFi.lift-elem (mk-journal cfg#journal-abbr r#journal); 116 | BiByFi.lift-elem (mk-pages r#pages); 117 | BiByFi.map-elem (Option.map 118 | (fun v -> ( 119 | let it-v = embed-string v 120 | in {vol. #it-v;})) r#volume); 121 | BiByFi.map-elem (Option.map 122 | (fun n -> ( 123 | let it-n = embed-string n in 124 | {no. #it-n;})) r#number); 125 | BiByFi.lift-elem (mk-year-month r#year r#month); 126 | BiByFi.map-elem it-note; 127 | BiByFi.map-elem it-key; 128 | ] 129 | 130 | let mk-inproceedings cfg r = 131 | let it-authors = mk-authors cfg#et-al cfg#name-shrink r#author in 132 | let it-booktitle = mk-journal cfg#journal-abbr r#booktitle in 133 | let it-editors = r#editor 134 | |> Option.map (fun editors -> mk-authors cfg#et-al cfg#name-shrink editors) 135 | |> Option.map (fun it-editor -> {#it-editor;,\ Eds.}) in 136 | let it-note = Option.map embed-string r#note in 137 | let it-key = Option.map embed-string r#key in 138 | let it-organization = Option.map embed-string r#organization in 139 | let it-publisher = Option.map (mk-publisher r#address) r#publisher in 140 | BiByFi.join-elements {,} {.} {\ } [ 141 | BiByFi.lift-elem it-authors; 142 | mk-title-elem r#title; 143 | BiByFi.lift-elem {in\ #it-booktitle;}; 144 | BiByFi.map-elem it-editors; 145 | BiByFi.custom-sep {.} {.} (BiByFi.map-elem it-organization); 146 | BiByFi.map-elem it-publisher; 147 | BiByFi.lift-elem (mk-year-month r#year r#month); 148 | BiByFi.map-elem (Option.map mk-pages r#pages); 149 | BiByFi.map-elem it-note; 150 | BiByFi.map-elem it-key; 151 | ] 152 | 153 | let mk-book cfg r = 154 | let it-authors = mk-authors cfg#et-al cfg#name-shrink r#author in 155 | let it-edition = r#edition 156 | |> Option.map embed-string 157 | |> Option.map (fun it-edition -> {#it-edition;\ ed.}) 158 | in 159 | let it-series = r#series 160 | |> Option.map embed-string 161 | |> Option.map (fun it-series -> {ser.\ #it-series;}) 162 | in 163 | let it-publisher = mk-publisher r#address r#publisher in 164 | let it-year-month = mk-year-month r#year r#month in 165 | let it-volume = r#volume 166 | |> Option.map embed-string 167 | |> Option.map (fun it-volume -> {vol.\ #it-volume;}) 168 | in 169 | let it-note = Option.map embed-string r#note in 170 | BiByFi.join-elements {,} {.} {\ } [ 171 | BiByFi.lift-elem it-authors; 172 | mk-title-elem r#title; 173 | BiByFi.map-elem it-edition; 174 | BiByFi.custom-sep {.} {.} (BiByFi.map-elem it-series); 175 | BiByFi.lift-elem it-publisher; 176 | BiByFi.lift-elem it-year-month; 177 | BiByFi.map-elem it-volume; 178 | BiByFi.map-elem it-note; 179 | ] 180 | 181 | let theme cfg ctx index bib-item = 182 | match bib-item with 183 | | Article(r) -> 184 | BiByFi.make-entry ctx (mk-index ctx index) (read-inline ctx (mk-article cfg r)) 185 | | InProceedings(r) -> 186 | BiByFi.make-entry ctx (mk-index ctx index) (read-inline ctx (mk-inproceedings cfg r)) 187 | | Book(r) -> 188 | BiByFi.make-entry ctx (mk-index ctx index) (read-inline ctx (mk-book cfg r)) 189 | | WildCard(it) -> 190 | BiByFi.make-entry ctx (mk-index ctx index) (read-inline ctx it) 191 | | _ -> 192 | BiByFi.make-entry ctx (mk-index ctx index) (read-inline ctx {yet implemented}) 193 | end 194 | -------------------------------------------------------------------------------- /bibyfi.satyh: -------------------------------------------------------------------------------- 1 | % vim: foldmethod=marker 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % Original author: T. Suwa (github: gfngfn) % 4 | % Original repository: https://github.com/gfngfn/cs-thesis % 5 | % % 6 | % Author: Nakano Masaki % 7 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8 | 9 | @require: vdecoset 10 | @require: option 11 | 12 | % global types {{{ 13 | 14 | type bibyfi-article = 15 | (| 16 | author : string list; 17 | title : string; 18 | journal : string; 19 | year : string; 20 | pages : (string * string); 21 | % option 22 | volume : string option; 23 | number : string option; 24 | month : string option; 25 | note : string option; 26 | key : string option; 27 | |) 28 | 29 | type bibyfi-book = 30 | (| 31 | author : string list; 32 | title : string; 33 | publisher : string; 34 | year : string; 35 | % option 36 | volume : string option; 37 | series : string option; 38 | address : string option; 39 | edition : string option; 40 | month : string option; 41 | note : string option; 42 | key : string option; 43 | |) 44 | 45 | type bibyfi-booklet = 46 | (| 47 | title : string; 48 | % option 49 | author : (string list) option; 50 | howpublished : string option; 51 | address : string option; 52 | year : string option; 53 | month : string option; 54 | note : string option; 55 | key : string option; 56 | |) 57 | 58 | type bibyfi-incollection = 59 | (| 60 | author : string list; 61 | title : string; 62 | booktitle : string; 63 | year : string; 64 | % option 65 | editor : (string list) option; 66 | pages : (string * string); 67 | organization : string option; 68 | publisher : string option; 69 | address : string option; 70 | month : string option; 71 | note : string option; 72 | key : string option; 73 | |) 74 | 75 | type bibyfi-inproceedings = 76 | (| 77 | author : string list; 78 | title : string; 79 | booktitle : string; 80 | year : string; 81 | % option 82 | editor : (string list) option; 83 | pages : (string * string) option; 84 | organization : string option; 85 | publisher : string option; 86 | address : string option; 87 | month : string option; 88 | note : string option; 89 | key : string option; 90 | |) 91 | 92 | type bibyfi-proceedings = 93 | (| 94 | title : string; 95 | year : string; 96 | % option 97 | editor : (string list) option; 98 | publisher : string option; 99 | organization : string option; 100 | address : string option; 101 | month : string option; 102 | note : string option; 103 | key : string option; 104 | |) 105 | 106 | type bibyfi-manual = 107 | (| 108 | title : string; 109 | % option 110 | author : (string list) option; 111 | organization : string option; 112 | address : string option; 113 | edition : string option; 114 | month : string option; 115 | year : string option; 116 | note : string option; 117 | key : string option; 118 | |) 119 | 120 | type bibyfi-masterthesis = 121 | (| 122 | author : string list; 123 | title : string; 124 | school : string; 125 | year : string; 126 | % option 127 | address : string option; 128 | month : string option; 129 | note : string option; 130 | key : string option; 131 | |) 132 | 133 | type bibyfi-phdthesis = 134 | (| 135 | author : string list; 136 | title : string; 137 | school : string; 138 | year : string; 139 | % option 140 | address : string option; 141 | month : string option; 142 | note : string option; 143 | key : string option; 144 | |) 145 | 146 | type bibyfi-techreport = 147 | (| 148 | author : string list; 149 | title : string; 150 | institution : string; 151 | year : string; 152 | % option 153 | typeof : string option; 154 | number : string option; 155 | address : string option; 156 | month : string option; 157 | note : string option; 158 | key : string option; 159 | |) 160 | 161 | type bibyfi-misc = 162 | (| 163 | % option 164 | author : (string list) option; 165 | title : string option; 166 | howpublished : string option; 167 | month : string option; 168 | year : string option; 169 | note : string option; 170 | key : string option; 171 | |) 172 | 173 | type bibyfi-unpublished = 174 | (| 175 | % option 176 | author : string list; 177 | title : string; 178 | note : string; 179 | %option 180 | month : string option; 181 | year : string option; 182 | key : string option; 183 | |) 184 | 185 | % }}} 186 | 187 | type bibyfi-item = 188 | | Article of bibyfi-article 189 | | Book of bibyfi-book 190 | | Booklet of bibyfi-booklet 191 | | InCollection of bibyfi-incollection 192 | | InProceedings of bibyfi-inproceedings 193 | | Manual of bibyfi-manual 194 | | MasterThesis of bibyfi-masterthesis 195 | | PhDThesis of bibyfi-phdthesis 196 | | Misc of bibyfi-misc 197 | | Proceedings of bibyfi-proceedings 198 | | TechReport of bibyfi-techreport 199 | | Unpublished of bibyfi-unpublished 200 | | WildCard of inline-text 201 | 202 | type bibyfi-entry-element = 203 | (| 204 | not-tail : inline-text -> inline-text; 205 | tail : inline-text -> inline-text; 206 | |) 207 | 208 | type bibyfi-citestyle = 209 | | CiteAsNumber 210 | | CiteAsAuthors 211 | | CiteAsAuthorsEtAl 212 | | CiteAsAuthorsPlus 213 | 214 | type bib-config = (| 215 | sort-references: bool; 216 | citestyle: bibyfi-citestyle; 217 | name-shrink: bool; 218 | |) 219 | 220 | module BiByFi: sig 221 | direct \cite : [string list] inline-cmd 222 | direct +makebibliography : [bib-config?; context -> int -> bibyfi-item -> block-boxes; (string * bibyfi-item) list] block-cmd 223 | direct \BiByFi : [] inline-cmd 224 | 225 | val shrink-name : string -> string 226 | 227 | val join-authors : inline-text -> inline-text -> inline-text -> inline-text list -> inline-text 228 | val make-entry : context -> inline-boxes -> inline-boxes -> block-boxes 229 | val join-elements : inline-text -> inline-text -> inline-text -> (bibyfi-entry-element option) list -> inline-text 230 | val lift-elem : inline-text -> bibyfi-entry-element option 231 | val map-elem : inline-text option -> bibyfi-entry-element option 232 | val custom-sep : inline-text -> inline-text -> bibyfi-entry-element option -> bibyfi-entry-element option 233 | end = struct 234 | let bib-left-padding = 20pt 235 | 236 | % internal functions {{{ 237 | 238 | let-rec merge xs ys = match (xs, ys) with 239 | | (x :: xs, y :: ys) -> 240 | if x < y 241 | then x :: y :: merge xs ys 242 | else y :: x :: merge xs ys 243 | | (_ :: _, []) -> xs 244 | | ([], _ :: _) -> ys 245 | | ([], []) -> [] 246 | 247 | let-rec split l = match l with 248 | | x :: y :: l -> ( 249 | let (xs, ys) = split l in 250 | (x :: xs, y :: ys)) 251 | | x :: [] -> 252 | ([x], []) 253 | | [] -> 254 | ([], []) 255 | 256 | let-rec sort l = 257 | match l with 258 | | [] -> [] 259 | | [x] -> [x] 260 | | [x;y] -> if x < y then [x;y] else [y;x] 261 | | _ -> 262 | let (xs, ys) = split l in 263 | let xs = sort xs in 264 | let ys = sort ys in 265 | merge xs ys 266 | 267 | let int-of-string s = 268 | let digit-of-string s = match s with 269 | | `0` -> Some(0) 270 | | `1` -> Some(1) 271 | | `2` -> Some(2) 272 | | `3` -> Some(3) 273 | | `4` -> Some(4) 274 | | `5` -> Some(5) 275 | | `6` -> Some(6) 276 | | `7` -> Some(7) 277 | | `8` -> Some(8) 278 | | `9` -> Some(9) 279 | | _ -> None 280 | in 281 | let-rec f exp s = 282 | let l = string-length s in 283 | match l with 284 | | 0 -> None 285 | | 1 -> 286 | (Option.map (fun d -> exp * d) (digit-of-string (string-sub s (l - 1) 1))) 287 | | _ -> 288 | Option.bind 289 | (f (exp * 10) (string-sub s 0 (l - 1))) 290 | (fun n -> Option.map (fun d -> n + exp * d) (digit-of-string (string-sub s (l - 1) 1))) 291 | in 292 | f 1 s 293 | 294 | % }}} 295 | 296 | let shrinkable codepoint = 297 | (codepoint >= 97 && codepoint <= 122) 298 | || (codepoint >= 65 && codepoint <= 90) 299 | 300 | % helpers for style file {{{ 301 | let-rec shrink-name name = 302 | let splitter = regexp-of-string `[ ]+` in 303 | let splited = split-on-regexp splitter name in 304 | let shrink n = 305 | let exploded = string-explode n in 306 | let initial = (match exploded with 307 | | i :: _ -> (if shrinkable i 308 | then Some(string-unexplode [i]) 309 | else None) 310 | | _ -> None) 311 | in 312 | match initial with 313 | | Some(initial) -> initial ^ `. `# 314 | | None -> n ^ #` `# 315 | in 316 | let-rec f name = match name with 317 | | [] -> ` ` 318 | | [(_, n)] -> n 319 | | (_, n) :: last -> (shrink n) ^ f last 320 | in 321 | f splited 322 | 323 | 324 | let join-authors sep-for-double sep sep-last authors = 325 | match List.reverse authors with 326 | | [] -> {} 327 | | it :: [] -> it 328 | | it2 :: it1 :: [] -> {#it1;#sep-for-double;#it2;} 329 | | it-last :: it-rest -> 330 | let its = it-rest 331 | |> List.reverse 332 | |> List.fold-left (fun acc it -> {#acc;#it;#sep;}) {} 333 | in 334 | {#its;#sep-last;#it-last;} 335 | 336 | let make-entry ctx ib-num ib-main = 337 | let ib = 338 | inline-skip (0pt -' get-natural-width ib-num) 339 | ++ ib-num ++ ib-main ++ inline-fil 340 | in 341 | let pads = (20pt, 0pt, 0pt, 0pt) in 342 | block-frame-breakable ctx pads VDecoSet.empty (fun ctx -> line-break true true ctx ib) 343 | 344 | let lift-elem e = Some 345 | (| 346 | not-tail = fun sep -> {#e;#sep;}; 347 | tail = fun periodo -> {#e;#periodo;}; 348 | |) 349 | 350 | let map-elem e = Option.map (fun e -> 351 | (| 352 | not-tail = fun sep -> {#e;#sep;}; 353 | tail = fun periodo -> {#e;#periodo;}; 354 | |)) e 355 | 356 | let custom-sep sep periodo e = Option.map (fun e -> 357 | (| 358 | not-tail = fun _ -> e#not-tail sep; 359 | tail = fun _ -> e#tail periodo; 360 | |)) e 361 | 362 | let-rec shrink l = match l with 363 | | [] -> [] 364 | | (None) :: tail -> shrink tail 365 | | (Some(x)) :: tail -> x :: shrink tail 366 | 367 | let join-elements sep periodo space elements = 368 | match elements |> shrink |> List.reverse with 369 | | [] -> {} 370 | | [elem] -> 371 | elem#tail periodo 372 | | elem-last :: elements -> 373 | let it-body = List.fold-left (fun acc elem -> ( 374 | let it-elem = elem#not-tail sep in 375 | {#it-elem;#space;#acc;})) {} elements 376 | in 377 | let tail = elem-last#tail periodo in 378 | {#it-body;#tail;} 379 | % }}} 380 | 381 | % implementations {{{ 382 | let-mutable cite-logs <- [] 383 | 384 | let-inline ctx \BiByFi = 385 | let size = get-font-size ctx in 386 | let f = read-inline ctx in 387 | let fd = ctx |> set-manual-rising (0pt -' (size *' 0.25)) |> read-inline in 388 | let ib = 389 | f {BiB} ++ kern (size *' 0.05) ++ fd{Y} ++ f{F} ++ kern(size *' 0.05) ++ fd{I} 390 | in 391 | script-guard Latin (no-break ib) 392 | 393 | let join-references-smartly = 394 | List.fold-left-adjacent (fun acc ref-n ref-n-prev ref-n-next -> ( 395 | match (ref-n-prev, ref-n-next) with 396 | | (_, None) -> acc ^ arabic ref-n 397 | | (None, Some(n-next)) -> 398 | if n-next == ref-n + 1 399 | then (arabic ref-n) ^ `–` 400 | else (arabic ref-n) ^ `, `# 401 | | (Some(n-prev), Some(n-next)) -> 402 | if n-next == ref-n + 1 && n-prev + 1 == ref-n 403 | % nothing to do because `–` was printed 404 | then acc 405 | else ( 406 | if n-next == ref-n + 1 407 | % 1, 3-4 408 | then acc ^ (arabic ref-n) ^ `–` 409 | % 1, 3 410 | else acc ^ (arabic ref-n) ^ `, `# 411 | ) 412 | )) ` ` 413 | 414 | let-inline ctx \cite labels = 415 | let sacc = 416 | labels 417 | |> List.fold-left (fun (numbers, fullcites) label -> ( 418 | let () = cite-logs <- ( 419 | if List.fold-left (fun acc cited -> (string-same cited label) || acc) false !cite-logs 420 | then !cite-logs 421 | else label :: !cite-logs 422 | ) 423 | in 424 | match get-cross-reference (`__bibyfi:` ^ label) with 425 | | None -> (numbers, `unresolved` :: fullcites) 426 | | Some(l) -> (match (int-of-string l) with 427 | | Some(i) -> (i :: numbers, fullcites) 428 | | None -> (numbers, l :: fullcites)) 429 | )) 430 | ([], []) 431 | |> (fun (numbers, fullcites) -> ( 432 | let numebers-str = 433 | match numbers with 434 | | [] -> ` ` 435 | | _ -> (numbers |> sort |> join-references-smartly) 436 | in 437 | let fullcites-str = 438 | let-rec join cites = match cites with 439 | | [] -> ` ` 440 | | c :: [] -> c 441 | | c :: last -> c ^ `, `# ^ join last 442 | in 443 | join fullcites 444 | in 445 | numebers-str ^ fullcites-str)) 446 | in 447 | inline-skip 2pt ++ read-inline ctx (embed-string (`[` ^ sacc ^ `]`)) 448 | 449 | let-rec sort-same f src refs = 450 | let pick label lst = lst |> List.filter (fun l -> f l label) |> List.nth 0 in 451 | match refs with 452 | | [] -> [] 453 | | label1 :: tl -> (match pick label1 src with 454 | | Some (l) -> l :: sort-same f src tl 455 | | None -> sort-same f src tl) 456 | 457 | let default-config = (| 458 | sort-references = true; 459 | citestyle = CiteAsNumber; 460 | name-shrink = true; 461 | |) 462 | 463 | let authors-of-item i style name-shrink item = 464 | let f author year = match (author, year) with 465 | | (Some author, Some year) -> Some (author, year) 466 | | _ -> None 467 | in 468 | let authors = match item with 469 | | Article(r) -> f (Some r#author) (Some r#year) 470 | | Book(r) -> f (Some r#author) (Some r#year) 471 | | Booklet(r) -> f r#author r#year 472 | | InCollection(r) -> f (Some r#author) (Some r#year) 473 | | InProceedings(r) -> f (Some r#author) (Some r#year) 474 | | Manual(r) -> f r#author r#year 475 | | MasterThesis(r) -> f (Some r#author) (Some r#year) 476 | | PhDThesis(r) -> f (Some r#author) (Some r#year) 477 | | Misc(r) -> f r#author r#year 478 | | Proceedings(r) -> None 479 | | TechReport(r) -> f (Some r#author) (Some r#year) 480 | | Unpublished(r) -> f (Some r#author) r#year 481 | | WildCard(r) -> None 482 | in 483 | (match style with 484 | | CiteAsNumber -> None 485 | | _ -> ( 486 | authors 487 | |> Option.map (fun (authors, year) -> ( 488 | let authors = List.map shrink-name authors |> List.reverse in 489 | match authors with 490 | | [] -> ` ` 491 | | n1 :: [] -> n1 492 | | n1 :: n2 :: [] -> ( 493 | match style with 494 | | CiteAsAuthorsPlus -> n1 ^ `+` 495 | | _ -> n1 ^ #` and `# ^ n2) 496 | | n1 :: ns -> ( 497 | match style with 498 | | CiteAsAuthors -> ( 499 | match List.reverse authors with 500 | | nlast :: ns -> 501 | (List.fold-left (^) `, `# ns) ^ #` and `# ^ nlast 502 | | _ -> ` `) 503 | | CiteAsAuthorsEtAl -> 504 | n1 ^ #` et al.` 505 | | CiteAsAuthorsPlus -> 506 | n1 ^ `+` 507 | | CiteAsNumber -> ` ` 508 | )) ^ #` `# ^ year))) 509 | |> Option.from (arabic (i + 1)) 510 | 511 | let-block ctx +makebibliography ?:cfg theme bibs = 512 | let cfg = Option.from default-config cfg in 513 | let bibs = 514 | let sorted = 515 | sort-same (fun (cited, _) label -> string-same label cited) bibs !cite-logs 516 | |> List.reverse 517 | in 518 | if cfg#sort-references then sorted else bibs 519 | in 520 | let () = 521 | bibs |> List.iteri (fun i (label, item) -> ( 522 | register-cross-reference (`__bibyfi:` ^ label) (authors-of-item i cfg#citestyle cfg#name-shrink item) 523 | )) 524 | in 525 | bibs |> List.fold-lefti (fun i bbacc (_, bibitem) -> ( 526 | bbacc +++ theme ctx (i + 1) bibitem 527 | )) block-nil 528 | % }}} 529 | end 530 | -------------------------------------------------------------------------------- /example-bib.satyh: -------------------------------------------------------------------------------- 1 | @import: bibyfi 2 | 3 | let bibs = [ 4 | (`comon1994independent`, Article(| 5 | author = [`Pierre Comon`]; 6 | title = `Independent component analysis, a new concept?`; 7 | journal = `Signal Processing`; 8 | year = `1994`; 9 | volume = Some(`36`); 10 | number = Some(`3`); 11 | pages = (`287`,`314`); 12 | month = None; 13 | key = None; 14 | note = None; 15 | |)); 16 | (`sawada2013multichannel`, Article(| 17 | author= [`Hiroshi Sawada`;`Hirokazu Kameoka`;`Shoko Araki`;`Naonori Ueda`]; 18 | title = `Multichannel Extensions of Non-Negative Matrix Factorization With Complex-Valued Data`; 19 | journal = `IEEE Transactions on Audio, Speech, and Language Processing`; 20 | year = `2013`; 21 | volume = Some(`21`); 22 | number = Some(`5`); 23 | pages = (`971`,`982`); 24 | month = None; 25 | key = None; 26 | note = None; 27 | |)); 28 | (`kitamura2017experimental`, InProceedings(| 29 | author = [`Daichi Kitamura`; `Nobutaka Ono`; `Hiroshi Saruwatari`]; 30 | title = `Experimental analysis of optimal window length for independent low-rank matrix analysis`; 31 | booktitle = `European Association for Signal Processing`; 32 | pages = Some((`1170`, `1174`)); 33 | year = `2017`; 34 | editor = None; 35 | organization = None; 36 | publisher = None; 37 | address = None; 38 | month = None; 39 | note = None; 40 | key = None; 41 | |)); 42 | (`asano2011`, Book(| 43 | author = [`浅野 太`]; 44 | title = `音のアレイ信号処理`; 45 | publisher = `コロナ社`; 46 | year = `2011`; 47 | volume = None; 48 | series = None; 49 | address = None; 50 | edition = None; 51 | month = None; 52 | note = None; 53 | key = None; 54 | |)); 55 | (`wildcard`, WildCard({This is a joker for you that don't have enough time!})) 56 | ] 57 | -------------------------------------------------------------------------------- /example/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES=$(wildcard *.saty) 2 | TARGETS=$(patsubst %.saty,%.pdf,$(SOURCES)) 3 | 4 | SATYSFI_OPTS+=-b 5 | 6 | ifdef SATYSFI_RUNTIME 7 | SATYSFI_OPTS+=-C "$(SATYSFI_RUNTIME)" 8 | endif 9 | 10 | .PHONY: all 11 | 12 | all: $(TARGETS) 13 | 14 | %.pdf: %.saty 15 | satysfi $(SATYSFI_OPTS) $< -o $@ 16 | 17 | .PHONY: clean 18 | 19 | clean: 20 | rm *.pdf 21 | rm *.satysfi-aux 22 | -------------------------------------------------------------------------------- /example/cite-as-number.saty: -------------------------------------------------------------------------------- 1 | @require: stdjareport 2 | @require: bibyfi/bibyfi 3 | @require: bibyfi/bibyfi-IEEETran 4 | @import: ../example-bib 5 | 6 | let bibyfi-theme = BiByFiIEEETran.theme (| 7 | name-shrink = true; 8 | et-al = true; 9 | journal-abbr = [(`European Association for Signal Processing`, `EUSIPCO`)]; 10 | |) 11 | in 12 | document(| 13 | title = {Example of \BiByFi;}; 14 | author = {Nakano Masaki}; 15 | |) '< 16 | +p{ 17 | テスト\cite[`comon1994independent`; `sawada2013multichannel`; `kitamura2017experimental`; `asano2011`; `wildcard`]; 18 | テスト2\cite[`comon1994independent`]; 19 | テスト2\cite[`comon1994independent`; `kitamura2017experimental`;`asano2011`]; 20 | } 21 | +makebibliography ?:(|sort-references=true; citestyle=CiteAsNumber; name-shrink=true;|) (bibyfi-theme)(bibs); 22 | > 23 | -------------------------------------------------------------------------------- /example/cite-with-name.saty: -------------------------------------------------------------------------------- 1 | @require: stdjareport 2 | @require: bibyfi/bibyfi 3 | @require: bibyfi/bibyfi-IEEETran 4 | @import: ../example-bib 5 | 6 | let bibyfi-theme = BiByFiIEEETran.theme (| 7 | name-shrink = true; 8 | et-al = true; 9 | journal-abbr = [(`European Association for Signal Processing`, `EUSIPCO`)]; 10 | |) 11 | in 12 | document(| 13 | title = {Example of \BiByFi;}; 14 | author = {Nakano Masaki}; 15 | |) '< 16 | +p{ 17 | テスト\cite[`comon1994independent`; `sawada2013multichannel`; `kitamura2017experimental`; `asano2011`; `wildcard`]; 18 | テスト2\cite[`comon1994independent`]; 19 | テスト2\cite[`comon1994independent`; `kitamura2017experimental`;`asano2011`]; 20 | } 21 | +makebibliography ?:(|sort-references=true; citestyle=CiteAsAuthorsEtAl; name-shrink=true;|) (bibyfi-theme)(bibs); 22 | > 23 | -------------------------------------------------------------------------------- /satysfi-bibyfi-doc.opam: -------------------------------------------------------------------------------- 1 | opam-version: "2.0" 2 | name: "satysfi-bibyfi-doc" 3 | version: "0.0.1" 4 | synopsis: "Document: A bibliography framework for SATySFi" 5 | maintainer: "Nakano Masaki" 6 | authors: [ 7 | "Nakano Masaki" 8 | "T. Suwa" 9 | ] 10 | homepage: "https://github.com/namachan10777/BiByFi" 11 | bug-reports: "https://github.com/namachan10777/BiByFi/issues" 12 | dev-repo: "git+https://github.com/namachan10777/BiByFi.git" 13 | depends: [ 14 | "satysfi" {>= "0.0.3" & < "0.0.5"} 15 | "satyrographos" {>= "0.0.2.3" & < "0.0.3"} 16 | "satysfi-dist" 17 | 18 | # You may want to include the corresponding library 19 | "satysfi-bibyfi" {= "%{version}%"} 20 | ] 21 | build: [ 22 | ["satyrographos" "opam" "build" 23 | "-name" "bibyfi-doc" 24 | "-prefix" "%{prefix}%" 25 | "-script" "%{build}%/Satyristes"] 26 | ] 27 | install: [ 28 | ["satyrographos" "opam" "install" 29 | "-name" "bibyfi-doc" 30 | "-prefix" "%{prefix}%" 31 | "-script" "%{build}%/Satyristes"] 32 | ] 33 | -------------------------------------------------------------------------------- /satysfi-bibyfi.opam: -------------------------------------------------------------------------------- 1 | opam-version: "2.0" 2 | name: "satysfi-bibyfi" 3 | version: "0.0.1" 4 | synopsis: "A bibliography framework for SATySFi" 5 | description: """ 6 | This project has been under developing. The API may be broken dramatically and suddenly 7 | 8 | A bibliography framework for SATySFi 9 | 10 | This project is inspired by cs-thesis and borrowing many codes from it. 11 | """ 12 | maintainer: "Nakano Masaki" 13 | authors: [ 14 | "Nakano Masaki" 15 | "T. Suwa" 16 | ] 17 | license: "Unlicense" 18 | homepage: "https://github.com/namachan10777/BiByFi" 19 | bug-reports: "https://github.com/namachan10777/BiByFi/issues" 20 | dev-repo: "git+https://github.com/namachan10777/BiByFi.git" 21 | depends: [ 22 | "satysfi" {>= "0.0.3" & < "0.0.5"} 23 | "satyrographos" {>= "0.0.2.3" & < "0.0.3"} 24 | ] 25 | build: [ ] 26 | install: [ 27 | ["satyrographos" "opam" "install" 28 | "-name" "bibyfi" 29 | "-prefix" "%{prefix}%" 30 | "-script" "%{build}%/Satyristes"] 31 | ] 32 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/namachan10777/BiByFi/5747245d2ed9f3f1101b2a70258a3c7f69090647/screenshot.png --------------------------------------------------------------------------------