mirror of
https://github.com/NullHypothesis/censorbib.git
synced 2025-07-23 06:31:22 -04:00
Add new build tool.
bibliogra.py requires Python 2, which is a pain to deal with. This commit adds a Go tool that compiles CensorBib from BibTeX to HTML. The tool does the bare minimum and is quite strict in the BibTeX format it expects.
This commit is contained in:
parent
d432134ed4
commit
4be5f7bfb2
21 changed files with 2381 additions and 0 deletions
113
src/main.go
Normal file
113
src/main.go
Normal file
|
@ -0,0 +1,113 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/nickng/bibtex"
|
||||
)
|
||||
|
||||
// Matches e.g.: @inproceedings{Doe2024a,
|
||||
var re = regexp.MustCompile(`@[a-z]*\{([A-Za-z\-]*[0-9]{4}[a-z]),`)
|
||||
|
||||
// Map a cite name (e.g., Doe2024a) to its line number in the .bib file. All
|
||||
// cite names are unique.
|
||||
type entryToLineFunc func(string) int
|
||||
|
||||
// Augment bibtex.BibEntry with the entry's line number in the .bib file.
|
||||
type bibEntry struct {
|
||||
bibtex.BibEntry
|
||||
lineNum int
|
||||
}
|
||||
|
||||
func toStr(b bibtex.BibString) string {
|
||||
if b == nil {
|
||||
return ""
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func parseBibFile(path string) []bibEntry {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
bib, err := bibtex.Parse(file)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Augment our BibTeX entries with their respective line numbers in the .bib
|
||||
// file. This is necessary to create the "Download BibTeX" links.
|
||||
lineOf := buildEntryToLineFunc(path)
|
||||
bibEntries := []bibEntry{}
|
||||
for _, entry := range bib.Entries {
|
||||
bibEntries = append(bibEntries, bibEntry{
|
||||
BibEntry: *entry,
|
||||
lineNum: lineOf(entry.CiteName),
|
||||
})
|
||||
}
|
||||
|
||||
return bibEntries
|
||||
}
|
||||
|
||||
func buildEntryToLineFunc(path string) entryToLineFunc {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
sc := bufio.NewScanner(file)
|
||||
entryToLine := make(map[string]int)
|
||||
line := 0
|
||||
for sc.Scan() {
|
||||
line++
|
||||
s := sc.Text()
|
||||
if !strings.HasPrefix(s, "@") {
|
||||
continue
|
||||
}
|
||||
entry := parseCiteName(s) // E.g., Doe2024a
|
||||
entryToLine[entry] = line
|
||||
}
|
||||
if err := sc.Err(); err != nil {
|
||||
log.Fatalf("scan file error: %v", err)
|
||||
}
|
||||
|
||||
return func(entry string) int {
|
||||
if line, ok := entryToLine[entry]; ok {
|
||||
return line
|
||||
}
|
||||
log.Fatalf("could not find line number for cite name: %s", entry)
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
func parseCiteName(line string) string {
|
||||
matches := re.FindStringSubmatch(line)
|
||||
if len(matches) != 2 {
|
||||
log.Fatalf("failed to extract cite name of: %s", line)
|
||||
}
|
||||
return matches[1]
|
||||
}
|
||||
|
||||
func run(w io.Writer, bibEntries []bibEntry) {
|
||||
fmt.Fprint(w, header())
|
||||
makeBib(w, bibEntries)
|
||||
fmt.Fprint(w, footer())
|
||||
}
|
||||
|
||||
func main() {
|
||||
path := flag.String("path", "", "Path to .bib file.")
|
||||
flag.Parse()
|
||||
if *path == "" {
|
||||
log.Fatal("No path to .bib file provided.")
|
||||
}
|
||||
run(os.Stdout, parseBibFile(*path))
|
||||
log.Println("Successfully created bibliography.")
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue