yuchenlin commited on
Commit
3ca5e42
·
1 Parent(s): e3931d3

Refresh demo to Rebiber 1.3.0

Browse files

Install Rebiber from GitHub main, pin Gradio 5.49.1, copy the latest
abbr.tsv, and fix Gradio 4/5 button updates. Keep matching local-only
(no live DBLP lookup) with an optional skip-author-check toggle.

Files changed (4) hide show
  1. README.md +8 -2
  2. abbr.tsv +23 -3
  3. app.py +95 -50
  4. requirements.txt +2 -1
README.md CHANGED
@@ -4,9 +4,15 @@ emoji: 📚
4
  colorFrom: blue
5
  colorTo: blue
6
  sdk: gradio
7
- sdk_version: 5.29.1
8
  app_file: app.py
9
  pinned: true
10
  ---
11
 
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
4
  colorFrom: blue
5
  colorTo: blue
6
  sdk: gradio
7
+ sdk_version: 5.49.1
8
  app_file: app.py
9
  pinned: true
10
  ---
11
 
12
+ # Rebiber 1.3.0 demo
13
+
14
+ Normalize BibTeX with official DBLP / ACL Anthology records.
15
+
16
+ This Space installs [Rebiber](https://github.com/yuchenlin/rebiber) from GitHub `main` (latest dumps) and runs **local-only** matching — no live DBLP lookup.
17
+
18
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
abbr.tsv CHANGED
@@ -3,9 +3,10 @@ Proc. of NAACL-HLT | Proceedings of the .* Conference of the North {A}merican Ch
3
  Proc. of EMNLP | Proceedings of the .* Conference on Empirical Methods in Natural Language Processing
4
  Proc. of ACL | Proceedings of the .* Annual Meeting of the Association for Computational Linguistics
5
  Proc. of WWW | {WWW} '.*: The Web Conference .*
6
- Proc. of ICLR | .* International Conference on Learning Representations,
7
- Proc. of ICML | Proceedings of the .* International Conference on Machine Learning.*
8
  Proc. of ICML | Machine Learning, Proceedings of the .* International Conference
 
9
  Proc. of AAAI | Proceedings of the .*AAAI.* Conference on Artificial Intelligence
10
  Proc. of KDD | The .* {ACM} {SIGKDD} International Conference on Knowledge Discovery
11
  Proc. of CVPR | .*IEEE Computer Society Conference on Computer Vision and Pattern Recognition.*
@@ -13,4 +14,23 @@ Proc. of CVPR | .*IEEE/CVF Conference on Computer Vision and Pattern Recognition
13
  Proc. of ICDE | .*International Conference on Data Engineering.*
14
  Proc. of SIGIR | .*International {ACM} {SIGIR}.*
15
  Proc. of INTERSPEECH | Interspeech .*Annual Conference of the International Speech.*
16
- TKDE | IEEE Transactions on Knowledge and Data Engineering
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  Proc. of EMNLP | Proceedings of the .* Conference on Empirical Methods in Natural Language Processing
4
  Proc. of ACL | Proceedings of the .* Annual Meeting of the Association for Computational Linguistics
5
  Proc. of WWW | {WWW} '.*: The Web Conference .*
6
+ Proc. of ICLR | .*International Conference on Learning Representations
7
+ Proc. of ICML | .*International Conference on Machine Learning
8
  Proc. of ICML | Machine Learning, Proceedings of the .* International Conference
9
+ Proc. of NeurIPS | .*Neural Information Processing Systems
10
  Proc. of AAAI | Proceedings of the .*AAAI.* Conference on Artificial Intelligence
11
  Proc. of KDD | The .* {ACM} {SIGKDD} International Conference on Knowledge Discovery
12
  Proc. of CVPR | .*IEEE Computer Society Conference on Computer Vision and Pattern Recognition.*
 
14
  Proc. of ICDE | .*International Conference on Data Engineering.*
15
  Proc. of SIGIR | .*International {ACM} {SIGIR}.*
16
  Proc. of INTERSPEECH | Interspeech .*Annual Conference of the International Speech.*
17
+ TKDE | IEEE Transactions on Knowledge and Data Engineering
18
+ Proc. of COLM | .*Conference on Language Modeling
19
+ Proc. of WACV | .*Winter Conference on Applications of Computer Vision
20
+ Proc. of ECCV | .*European Conference on Computer Vision
21
+ Proc. of ICCV | .*International Conference on Computer Vision
22
+ Proc. of NAACL | Proceedings of the .* Conference of the Nations of the Americas Chapter of the Association for Computational Linguistics
23
+ Proc. of Findings | Findings of the Association for Computational Linguistics
24
+ TACL | Transactions of the Association for Computational Linguistics
25
+ JMLR | Journal of Machine Learning Research
26
+ TMLR | Trans. Mach. Learn. Res.
27
+ TMLR | Transactions on Machine Learning Research
28
+ JMLR | J. Mach. Learn. Res.
29
+ Proc. of MICCAI | .*Medical Image Computing and Computer.?Assisted Intervention
30
+ Proc. of MLSys | .*Conference on Machine Learning and Systems
31
+ Proc. of LoG | .*Learning on Graphs Conference
32
+ Proc. of AutoML | .*International Conference on Automated Machine Learning
33
+ Proc. of ICRA | .*International Conference on Robotics and Automation
34
+ Proc. of IROS | .*International Conference on Intelligent Robots and Systems
35
+ Proc. of RSS | .*Robotics: Science and Systems
36
+ Proc. of CoRL | .*Conference on Robot Learning
app.py CHANGED
@@ -1,32 +1,44 @@
1
  import os
 
2
  import uuid
 
3
  import gradio as gr
4
  import rebiber
 
 
 
 
 
5
 
6
- # ---------- preload DB ---------- #
7
- PACKAGE_ROOT = os.path.abspath(rebiber.__file__).replace("__init__.py", "")
8
  bib_db = rebiber.construct_bib_db(
9
  os.path.join(PACKAGE_ROOT, "bib_list.txt"), start_dir=PACKAGE_ROOT
10
  )
11
- abbr_dict = rebiber.normalize.load_abbr_tsv("abbr.tsv")
 
 
 
 
 
12
 
13
  # ---------- helper functions ---------- #
14
- def process(input_bib: str,
15
- shorten: bool,
16
- remove_keys: list[str],
17
- deduplicate: bool,
18
- sort_ids: bool):
 
 
 
19
  """Normalize a BibTeX string and write it to disk."""
20
- if "@" not in input_bib:
21
- # Nothing that looks like BibTeX
22
- return "N/A", "", gr.Button.update(visible=False)
23
 
24
  run_id = uuid.uuid4().hex
25
- in_file = f"input_{run_id}.bib"
26
- out_file = f"output_{run_id}.bib"
 
27
 
28
- # Write raw input
29
- with open(in_file, "w") as f:
30
  f.write(input_bib.replace("\t", " "))
31
 
32
  entries = rebiber.load_bib_file(in_file)
@@ -34,24 +46,35 @@ def process(input_bib: str,
34
  bib_db,
35
  entries,
36
  out_file,
37
- abbr_dict = abbr_dict if shorten else [],
38
- deduplicate = deduplicate,
39
- sort = sort_ids,
40
- removed_value_names = remove_keys,
 
 
41
  )
42
 
43
- with open(out_file) as f:
44
  output_bib = f.read().replace("\n ", "\n ")
45
 
46
- # Show output + enable “Download” button
47
- return output_bib, run_id, gr.update(visible=True)
48
 
49
 
50
- def download_file(run_id: str):
51
  """Expose the normalized .bib for download."""
52
- file_path = f"output_{run_id}.bib"
53
-
54
- return file_path, gr.update(visible=True)
 
 
 
 
 
 
 
 
 
 
55
 
56
 
57
  # ---------- demo UI ---------- #
@@ -67,19 +90,21 @@ EXAMPLE = """
67
  with gr.Blocks(title="Rebiber", theme=gr.themes.Soft()) as demo:
68
  gr.Markdown(
69
  """
70
- # **Rebiber** – normalise those BibTeX entries!
71
 
72
  🐼 [Project page](https://yuchenlin.xyz/)   |  
73
  :octocat: [GitHub](https://github.com/yuchenlin/rebiber)   |  
74
- 🐤 [Tweet](https://twitter.com/billyuchenlin/status/1353850378438070272)
75
 
76
- Rebiber replaces arXiv citations with their official venue versions (DBLP / ACL
77
- Anthology), deduplicates, sorts, and can abbreviate conference names.
 
 
 
78
  """
79
  )
80
 
81
  with gr.Row():
82
- # ---------- left column ---------- #
83
  with gr.Column(scale=3):
84
  input_bib = gr.Textbox(
85
  label="Input BibTeX",
@@ -88,41 +113,61 @@ Anthology), deduplicates, sorts, and can abbreviate conference names.
88
  interactive=True,
89
  )
90
  removekeys = gr.CheckboxGroup(
91
- ["url", "biburl", "address", "publisher",
92
- "pages", "doi", "volume", "bibsource"],
 
 
 
 
 
 
 
 
93
  label="Remove fields",
94
- info="Select the keys youd like to strip",
 
 
 
 
 
 
 
 
95
  )
96
- shorten = gr.Checkbox(label="Abbreviate venue names")
97
- dedup = gr.Checkbox(label="Deduplicate entries")
98
- sort = gr.Checkbox(label="Sort IDs alphabetically")
99
 
100
  with gr.Row():
101
- clear_btn = gr.Button("Clear")
102
- submit_btn = gr.Button("Submit")
103
 
104
- run_uuid = gr.Textbox(visible=False)
105
 
106
- # ---------- right column ---------- #
107
  with gr.Column(scale=3):
108
  output_box = gr.Textbox(
109
  label="Normalised BibTeX",
110
  interactive=False,
111
- show_copy_button=True, # :contentReference[oaicite:2]{index=2}
 
112
  )
113
- download_btn = gr.Button("Generate . bib file", visible=False)
114
- download_file_component = gr.File(visible=False)
115
 
116
- # ---------- wiring ---------- #
117
  submit_btn.click(
118
  process,
119
- inputs=[input_bib, shorten, removekeys, dedup, sort],
120
- outputs=[output_box, run_uuid, download_btn],
121
  api_name="process",
122
  )
123
- download_btn.click(download_file, run_uuid, [download_file_component, download_file_component])
124
- clear_btn.click(lambda: "", None, input_bib)
 
 
 
 
 
 
 
 
125
 
126
 
127
  if __name__ == "__main__":
128
- demo.launch()
 
1
  import os
2
+ import tempfile
3
  import uuid
4
+
5
  import gradio as gr
6
  import rebiber
7
+ from rebiber.normalize import load_abbr_tsv
8
+
9
+ # ---------- preload DB (local dumps only; no live DBLP) ---------- #
10
+ PACKAGE_ROOT = os.path.dirname(os.path.abspath(rebiber.__file__))
11
+ SPACE_ROOT = os.path.dirname(os.path.abspath(__file__))
12
 
 
 
13
  bib_db = rebiber.construct_bib_db(
14
  os.path.join(PACKAGE_ROOT, "bib_list.txt"), start_dir=PACKAGE_ROOT
15
  )
16
+
17
+ abbr_path = os.path.join(SPACE_ROOT, "abbr.tsv")
18
+ if not os.path.isfile(abbr_path):
19
+ abbr_path = os.path.join(PACKAGE_ROOT, "abbr.tsv")
20
+ abbr_dict = load_abbr_tsv(abbr_path)
21
+
22
 
23
  # ---------- helper functions ---------- #
24
+ def process(
25
+ input_bib: str,
26
+ shorten: bool,
27
+ remove_keys,
28
+ deduplicate: bool,
29
+ sort_ids: bool,
30
+ skip_author_check: bool,
31
+ ):
32
  """Normalize a BibTeX string and write it to disk."""
33
+ if not input_bib or "@" not in input_bib:
34
+ return "N/A", "", gr.update(visible=False), gr.update(visible=False, value=None)
 
35
 
36
  run_id = uuid.uuid4().hex
37
+ tmpdir = tempfile.gettempdir()
38
+ in_file = os.path.join(tmpdir, f"rebiber_input_{run_id}.bib")
39
+ out_file = os.path.join(tmpdir, f"rebiber_output_{run_id}.bib")
40
 
41
+ with open(in_file, "w", encoding="utf8") as f:
 
42
  f.write(input_bib.replace("\t", " "))
43
 
44
  entries = rebiber.load_bib_file(in_file)
 
46
  bib_db,
47
  entries,
48
  out_file,
49
+ abbr_dict=abbr_dict if shorten else [],
50
+ deduplicate=bool(deduplicate),
51
+ sort=bool(sort_ids),
52
+ removed_value_names=list(remove_keys or []),
53
+ check_authors=not bool(skip_author_check),
54
+ live_lookup=False,
55
  )
56
 
57
+ with open(out_file, encoding="utf8") as f:
58
  output_bib = f.read().replace("\n ", "\n ")
59
 
60
+ return output_bib, out_file, gr.update(visible=True), gr.update(visible=False, value=None)
 
61
 
62
 
63
+ def download_file(out_path: str):
64
  """Expose the normalized .bib for download."""
65
+ if not out_path or not os.path.isfile(out_path):
66
+ return gr.update(visible=False, value=None)
67
+ return gr.update(value=out_path, visible=True)
68
+
69
+
70
+ def clear_all():
71
+ return (
72
+ "",
73
+ "",
74
+ "",
75
+ gr.update(visible=False),
76
+ gr.update(visible=False, value=None),
77
+ )
78
 
79
 
80
  # ---------- demo UI ---------- #
 
90
  with gr.Blocks(title="Rebiber", theme=gr.themes.Soft()) as demo:
91
  gr.Markdown(
92
  """
93
+ # **Rebiber 1.3.0** – normalise those BibTeX entries!
94
 
95
  🐼 [Project page](https://yuchenlin.xyz/)   |  
96
  :octocat: [GitHub](https://github.com/yuchenlin/rebiber)   |  
97
+ 🐤 [Tweet](https://twitter.com/billyuchenlin/status/1353850378438070272)
98
 
99
+ Rebiber **1.3.0** replaces arXiv citations with official venue versions (DBLP / ACL Anthology),
100
+ deduplicates, sorts, and can abbreviate conference names. Matching is **local-only** (no live DBLP lookup).
101
+
102
+ **What's new in 1.3.0:** author-overlap guard (a shared title like "Deep Learning" is not replaced by an unrelated paper),
103
+ official arXiv fields (`eprint`, `archivePrefix`, `primaryClass`), and the latest conference dumps.
104
  """
105
  )
106
 
107
  with gr.Row():
 
108
  with gr.Column(scale=3):
109
  input_bib = gr.Textbox(
110
  label="Input BibTeX",
 
113
  interactive=True,
114
  )
115
  removekeys = gr.CheckboxGroup(
116
+ [
117
+ "url",
118
+ "biburl",
119
+ "address",
120
+ "publisher",
121
+ "pages",
122
+ "doi",
123
+ "volume",
124
+ "bibsource",
125
+ ],
126
  label="Remove fields",
127
+ info="Select the keys you'd like to strip",
128
+ )
129
+ shorten = gr.Checkbox(label="Abbreviate venue names", value=False)
130
+ dedup = gr.Checkbox(label="Deduplicate entries", value=False)
131
+ sort = gr.Checkbox(label="Sort IDs alphabetically", value=False)
132
+ skip_author_check = gr.Checkbox(
133
+ label="Skip author check",
134
+ value=False,
135
+ info="Disable the 1.3 author-overlap guard (check_authors=False). Leave unchecked unless you know you need it.",
136
  )
 
 
 
137
 
138
  with gr.Row():
139
+ clear_btn = gr.Button("Clear")
140
+ submit_btn = gr.Button("Submit", variant="primary")
141
 
142
+ run_path = gr.Textbox(visible=False)
143
 
 
144
  with gr.Column(scale=3):
145
  output_box = gr.Textbox(
146
  label="Normalised BibTeX",
147
  interactive=False,
148
+ show_copy_button=True,
149
+ lines=15,
150
  )
151
+ download_btn = gr.Button("Download .bib", visible=False)
152
+ download_file_component = gr.File(label="Normalized BibTeX file", visible=False)
153
 
 
154
  submit_btn.click(
155
  process,
156
+ inputs=[input_bib, shorten, removekeys, dedup, sort, skip_author_check],
157
+ outputs=[output_box, run_path, download_btn, download_file_component],
158
  api_name="process",
159
  )
160
+ download_btn.click(
161
+ download_file,
162
+ inputs=run_path,
163
+ outputs=download_file_component,
164
+ )
165
+ clear_btn.click(
166
+ clear_all,
167
+ inputs=None,
168
+ outputs=[input_bib, output_box, run_path, download_btn, download_file_component],
169
+ )
170
 
171
 
172
  if __name__ == "__main__":
173
+ demo.launch()
requirements.txt CHANGED
@@ -1 +1,2 @@
1
- git+https://github.com/yuchenlin/rebiber.git@main
 
 
1
+ git+https://github.com/yuchenlin/rebiber.git@main
2
+ gradio==5.49.1