varri-js 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CITATION.bib +13 -0
- package/CITATION.cff +33 -0
- package/README.md +64 -10
- package/citation.html +316 -0
- package/doc/example-page-screenshot.png +0 -0
- package/doc/vaRRI-UI-example.png +0 -0
- package/doc/vaRRI_example_output.png +0 -0
- package/doc/vaRRI_example_output.svg +8 -0
- package/docu.free-trailing-ends.md +247 -0
- package/example-data.js +226 -0
- package/index.html +616 -0
- package/index.js +2844 -0
- package/logo/vaRRI.logo.200x200.png +0 -0
- package/logo/vaRRI.logo.40x40.png +0 -0
- package/logo/vaRRI.logo.svg +144 -0
- package/logo/vaRRI.media.png +0 -0
- package/package.json +20 -2
- package/style.css +1183 -0
package/CITATION.bib
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
@misc{raden_varrii_js_2026,
|
|
2
|
+
title = {vaRRI-js - Visual annotation of RNA-RNA interactions},
|
|
3
|
+
author = {Raden, Martin and Ganter, Fabian},
|
|
4
|
+
year = {2026},
|
|
5
|
+
url = {https://backofenlab.github.io/vaRRI-js/},
|
|
6
|
+
note = {Web application and JavaScript library},
|
|
7
|
+
abstract = {vaRRI-js is a browser-based JavaScript library for visualizing RNA-RNA interactions (RRIs) as 2D diagrams with annotations such as base-pair highlights, probability profiles, subsequence highlights, and point mutation annotations.},
|
|
8
|
+
keywords = {RNA, RNA-RNA interaction, visualization, JavaScript, bioinformatics},
|
|
9
|
+
version = {1.0.0},
|
|
10
|
+
license = {MIT},
|
|
11
|
+
organization = {University of Freiburg, Department of Computer Science, Bioinformatics Lab},
|
|
12
|
+
organization_url = {https://www.bioinformatics.uni-freiburg.de/}
|
|
13
|
+
}
|
package/CITATION.cff
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
title: vaRRI-js - Visual annotation of RNA-RNA interactions
|
|
3
|
+
message: >-
|
|
4
|
+
If you use this software in a publication, please cite it using the metadata
|
|
5
|
+
in this file.
|
|
6
|
+
type: software
|
|
7
|
+
authors:
|
|
8
|
+
- given-names: Martin
|
|
9
|
+
family-names: Raden
|
|
10
|
+
affiliation: University of Freiburg, Germany
|
|
11
|
+
orcid: 'https://orcid.org/0000-0002-7926-5911'
|
|
12
|
+
- given-names: Fabian
|
|
13
|
+
family-names: Ganter
|
|
14
|
+
affiliation: University of Freiburg, Germany
|
|
15
|
+
- name: Bioinformatics Lab, University of Freiburg
|
|
16
|
+
affiliation: Department of Computer Science, University of Freiburg
|
|
17
|
+
website: 'https://www.bioinformatics.uni-freiburg.de/'
|
|
18
|
+
version: 1.0.0
|
|
19
|
+
date-released: '2026-07-31'
|
|
20
|
+
repository-code: 'https://github.com/BackofenLab/vaRRI-js'
|
|
21
|
+
url: 'https://backofenlab.github.io/vaRRI-js/'
|
|
22
|
+
abstract: >-
|
|
23
|
+
vaRRI-js is a browser-based JavaScript library for visualizing RNA-RNA
|
|
24
|
+
interactions (RRIs) as 2D diagrams with annotations such as base-pair
|
|
25
|
+
highlights, probability profiles, subsequence highlights, and point mutation
|
|
26
|
+
annotations.
|
|
27
|
+
keywords:
|
|
28
|
+
- RNA
|
|
29
|
+
- RNA-RNA interaction
|
|
30
|
+
- visualization
|
|
31
|
+
- JavaScript
|
|
32
|
+
- bioinformatics
|
|
33
|
+
license: MIT
|
package/README.md
CHANGED
|
@@ -132,6 +132,50 @@ Install vaRRI-js in an application with:
|
|
|
132
132
|
npm install varri-js
|
|
133
133
|
```
|
|
134
134
|
|
|
135
|
+
Starting with version 1.0.1, the package includes the complete viewer as well as the library.
|
|
136
|
+
|
|
137
|
+
### Open `index.html` in Browser
|
|
138
|
+
|
|
139
|
+
After installation via npm, you find the vaRRI-js user interface `index.html` in the following subfolder
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
node_modules/varri-js/index.html
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
You can open it with any recent browser and start working
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
### Local Webserver (optional)
|
|
149
|
+
|
|
150
|
+
Alternatively, serving the installed viewer locally using a local webserver requires e.g. Python 3:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
python3 -m http.server 8080 --bind 127.0.0.1 --directory node_modules/varri-js
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Open `http://localhost:8080/index.html`. Applications can serve or copy the whole package
|
|
157
|
+
directory using their own static-file server, retaining the relative directory layout.
|
|
158
|
+
The viewer includes example inputs, SVG/PNG export controls, help, citation data and local logos.
|
|
159
|
+
Use HTTP rather than `file://` so the help and citation pages can load their packaged data.
|
|
160
|
+
|
|
161
|
+
The JavaScript `main` and root export intentionally remain `src/vaRRI.js`: `require('varri-js')`
|
|
162
|
+
and ESM default imports return the library API. The viewer has a separate public entry:
|
|
163
|
+
|
|
164
|
+
```javascript
|
|
165
|
+
const viewerPath = require.resolve('varri-js/index.html');
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Resolving this path does not start a server; serve its containing directory to make the viewer
|
|
169
|
+
and its assets available. HTML is a browser document, not a JavaScript module.
|
|
170
|
+
|
|
171
|
+
**Network requirements:** the existing viewer uses jsDelivr for `marked` and external
|
|
172
|
+
university logos from `www.bioinf.uni-freiburg.de`. The help page also uses cdnjs for its
|
|
173
|
+
Markdown stylesheet, and the citation page loads Citation.js from jsDelivr. These URLs
|
|
174
|
+
are retained, so this is not a fully offline distribution. Deployments with restricted
|
|
175
|
+
network access must provide those assets locally and update the HTML references/CSP.
|
|
176
|
+
Opening the help or citation page through `file://` can additionally fetch fallback content
|
|
177
|
+
from `raw.githubusercontent.com`; serving the package over HTTP uses the local files.
|
|
178
|
+
|
|
135
179
|
The package exports the CommonJS-compatible API as `varri-js` and ships the browser assets under
|
|
136
180
|
`varri-js/fornac/` and `varri-js/dist/`. For a static page served from an npm-based application,
|
|
137
181
|
load the browser files in this order:
|
|
@@ -573,16 +617,26 @@ The `src` directory provides a [detailed vaRRI-js Library API documentation](src
|
|
|
573
617
|
|
|
574
618
|
## Release Process
|
|
575
619
|
|
|
576
|
-
Publishing is automated by [`.github/workflows/publish-npm.yml`](.github/workflows/publish-npm.yml).
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
with
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
620
|
+
Publishing is automated by [`.github/workflows/publish-npm.yml`](https://github.com/BackofenLab/vaRRI-js/blob/main/.github/workflows/publish-npm.yml).
|
|
621
|
+
The initial `varri-js@1.0.0` publication was manual. Before automated releases, an npm package
|
|
622
|
+
owner must configure a **GitHub Actions trusted publisher** in the package's npm settings:
|
|
623
|
+
organization `BackofenLab`, repository `vaRRI-js`, workflow filename `publish-npm.yml`, no
|
|
624
|
+
environment name, with direct `npm publish` allowed. This one-time account action may request
|
|
625
|
+
2FA. The workflow uses OIDC and does not require an `NPM_TOKEN` secret or interactive 2FA for
|
|
626
|
+
each release. See [npm trusted publishing](https://docs.npmjs.com/trusted-publishers/).
|
|
627
|
+
|
|
628
|
+
Merge the workflow changes before creating a release tag on a commit containing them.
|
|
629
|
+
Every published GitHub release runs the tests, derives the npm version from the release tag,
|
|
630
|
+
builds and installs a temporary package to verify its contents, and publishes with provenance.
|
|
631
|
+
Stable releases use the `latest` npm tag; semantic prerelease versions or GitHub releases
|
|
632
|
+
marked as prereleases use `next`. Use `npm install varri-js@next` to try a prerelease.
|
|
633
|
+
Use a new, increasing stable version for each stable release: npm versions are immutable,
|
|
634
|
+
and re-running an already successful publish cannot overwrite that version. Publishing a
|
|
635
|
+
GitHub release is the trigger; pushing a Git tag alone does not publish the npm package.
|
|
636
|
+
|
|
637
|
+
Run `npm run test:ci` and `npm run test:package` locally before proposing a release. The
|
|
638
|
+
package check installs the actual tarball in a temporary consumer and checks module exports,
|
|
639
|
+
viewer asset references, documentation images, and citation data. It also runs in PR CI.
|
|
586
640
|
|
|
587
641
|
Release tags must be valid semantic versions with an optional leading `v`, for example `v1.2.3`
|
|
588
642
|
or `1.2.3`. The workflow changes `package.json` and `package-lock.json` only inside the temporary
|
package/citation.html
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="de">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<title>Citation — vaRRI-js</title>
|
|
7
|
+
<link rel="icon" type="image/png" href="logo/vaRRI.logo.40x40.png">
|
|
8
|
+
|
|
9
|
+
<!-- External Stylesheets (matching index.html) -->
|
|
10
|
+
<link rel="stylesheet" href="fornac/fornac.css" />
|
|
11
|
+
<link rel="stylesheet" href="style.css" />
|
|
12
|
+
|
|
13
|
+
<style>
|
|
14
|
+
/* Tab Buttons & Layout overrides */
|
|
15
|
+
.tab-header {
|
|
16
|
+
display: flex;
|
|
17
|
+
gap: 0.25rem;
|
|
18
|
+
border-bottom: 2px solid #e9ecef;
|
|
19
|
+
margin-bottom: 1rem;
|
|
20
|
+
overflow-x: auto;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.tab-btn {
|
|
24
|
+
padding: 0.6rem 1.2rem;
|
|
25
|
+
background: none;
|
|
26
|
+
border: none;
|
|
27
|
+
border-bottom: 3px solid transparent;
|
|
28
|
+
font-weight: 600;
|
|
29
|
+
color: #6c757d;
|
|
30
|
+
cursor: pointer;
|
|
31
|
+
transition: all 0.2s;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.tab-btn:hover {
|
|
35
|
+
color: #1d7fa4;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.tab-btn.active {
|
|
39
|
+
color: #1d7fa4;
|
|
40
|
+
border-bottom-color: #1d7fa4;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* Content Area */
|
|
44
|
+
.tab-content {
|
|
45
|
+
display: none;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.tab-content.active {
|
|
49
|
+
display: block;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.action-bar {
|
|
53
|
+
display: flex;
|
|
54
|
+
justify-content: flex-end;
|
|
55
|
+
margin-bottom: 0.5rem;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
pre.citation-pre {
|
|
59
|
+
background: #f8f9fa;
|
|
60
|
+
padding: 1.25rem;
|
|
61
|
+
border-radius: 6px;
|
|
62
|
+
border: 1px solid #e9ecef;
|
|
63
|
+
overflow-x: auto;
|
|
64
|
+
white-space: pre-wrap;
|
|
65
|
+
word-wrap: break-word;
|
|
66
|
+
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
|
|
67
|
+
font-size: 0.9rem;
|
|
68
|
+
line-height: 1.45;
|
|
69
|
+
color: #212529;
|
|
70
|
+
}
|
|
71
|
+
</style>
|
|
72
|
+
|
|
73
|
+
<!-- Citation.js Library -->
|
|
74
|
+
<script src="https://cdn.jsdelivr.net/npm/citation-js@0.7.14/build/citation.min.js"></script>
|
|
75
|
+
</head>
|
|
76
|
+
<body>
|
|
77
|
+
|
|
78
|
+
<header>
|
|
79
|
+
<a class="group-logo-link" href="https://www.bioinf.uni-freiburg.de" target="_blank" rel="noopener noreferrer" aria-label="Visit the Bioinformatics Group Freiburg website">
|
|
80
|
+
<img class="group-logo" src="https://www.bioinf.uni-freiburg.de/assets/images/bioinf-fr-logo-blau.png" alt="Bioinformatics Group Freiburg logo" />
|
|
81
|
+
</a>
|
|
82
|
+
<img class="varri-logo" src="logo/vaRRI.logo.200x200.png" alt="vaRRI-js logo">
|
|
83
|
+
<div class="header-title">
|
|
84
|
+
<h1>vaRRI-js</h1>
|
|
85
|
+
<p>Visual Annotation of RNA–RNA Interactions</p>
|
|
86
|
+
</div>
|
|
87
|
+
<div class="uni-logo-wrap">
|
|
88
|
+
<a class="uni-logo-link" href="https://www.bioinf.uni-freiburg.de" target="_blank" rel="noopener noreferrer" aria-label="Open the University Freiburg Bioinformatics website in a new tab">
|
|
89
|
+
<span class="uni-logo-text">Bioinformatics -</span>
|
|
90
|
+
<img src="https://www.bioinf.uni-freiburg.de/assets/images/logo-uni-freiburg.png" alt="University Freiburg logo" class="img-fluid uni-logo" />
|
|
91
|
+
</a>
|
|
92
|
+
</div>
|
|
93
|
+
</header>
|
|
94
|
+
|
|
95
|
+
<main>
|
|
96
|
+
<div class="controls-column" style="grid-column: 1 / -1; max-width: 1000px; margin: 0 auto; width: 100%;">
|
|
97
|
+
|
|
98
|
+
<aside class="panel control-panel">
|
|
99
|
+
<details class="control-group" open>
|
|
100
|
+
<summary>Citation & Export</summary>
|
|
101
|
+
<div class="control-group-body">
|
|
102
|
+
<p style="margin-top:0; color:#6c757d;">
|
|
103
|
+
Choose a format to copy or download the citation data.</p>
|
|
104
|
+
|
|
105
|
+
<!-- Tab Navigationsleiste -->
|
|
106
|
+
<div class="tab-header" id="tab-header">
|
|
107
|
+
<button class="tab-btn active" onclick="switchTab('bibtex')">BibTeX</button>
|
|
108
|
+
<button class="tab-btn" onclick="switchTab('cff')">CFF</button>
|
|
109
|
+
<button class="tab-btn" onclick="switchTab('apa')">APA</button>
|
|
110
|
+
<button class="tab-btn" onclick="switchTab('ieee')">IEEE</button>
|
|
111
|
+
<button class="tab-btn" onclick="switchTab('ris')">RIS (EndNote/Zotero)</button>
|
|
112
|
+
</div>
|
|
113
|
+
|
|
114
|
+
<!-- Inhaltsbereich -->
|
|
115
|
+
<div id="tab-contents"></div>
|
|
116
|
+
</div>
|
|
117
|
+
</details>
|
|
118
|
+
</aside>
|
|
119
|
+
|
|
120
|
+
<!-- Link zurück zur Hauptanwendung -->
|
|
121
|
+
<aside class="panel control-panel">
|
|
122
|
+
<details class="control-group">
|
|
123
|
+
<summary>
|
|
124
|
+
<a href="index.html">
|
|
125
|
+
← Back to Visualization
|
|
126
|
+
</a>
|
|
127
|
+
</summary>
|
|
128
|
+
</details>
|
|
129
|
+
</aside>
|
|
130
|
+
|
|
131
|
+
</div>
|
|
132
|
+
</main>
|
|
133
|
+
|
|
134
|
+
<footer class="site-footer" aria-label="Service information">
|
|
135
|
+
<div class="footer-content">
|
|
136
|
+
<p>
|
|
137
|
+
Disclaimer: This service is provided "as is" without any warranties or guarantees.
|
|
138
|
+
</p>
|
|
139
|
+
<p>
|
|
140
|
+
For comments or feedback, please contact
|
|
141
|
+
<a href="https://www.bioinf.uni-freiburg.de/" target="_blank" rel="noopener noreferrer">Freiburg Bioinformatics Group of the University of Freiburg</a>.
|
|
142
|
+
</p>
|
|
143
|
+
<p>
|
|
144
|
+
The source code for this service is freely available on
|
|
145
|
+
<a href="https://github.com/BackofenLab/vaRRI-js" target="_blank" rel="noopener noreferrer">GitHub</a>.
|
|
146
|
+
</p>
|
|
147
|
+
</div>
|
|
148
|
+
</footer>
|
|
149
|
+
|
|
150
|
+
<!-- JavaScript Logik -->
|
|
151
|
+
<script>
|
|
152
|
+
const GITHUB_RAW_BASE = 'https://raw.githubusercontent.com/BackofenLab/vaRRI-js/main/';
|
|
153
|
+
|
|
154
|
+
const TABS_CONFIG = {
|
|
155
|
+
bibtex: { label: 'BibTeX', filename: 'CITATION.bib', mime: 'text/plain', source: 'CITATION.bib', type: 'raw' },
|
|
156
|
+
cff: { label: 'CFF', filename: 'CITATION.cff', mime: 'text/yaml', source: 'CITATION.cff', type: 'raw' },
|
|
157
|
+
apa: { label: 'APA', filename: 'citation.txt', mime: 'text/plain', source: 'CITATION.bib', type: 'parsed', style: 'apa' },
|
|
158
|
+
ieee: { label: 'IEEE', filename: 'citation.txt', mime: 'text/plain', source: 'CITATION.bib', type: 'parsed', style: 'ieee' },
|
|
159
|
+
ris: { label: 'RIS', filename: 'citation.ris', mime: 'application/x-research-info-systems', source: 'CITATION.bib', type: 'parsed', style: 'ris' }
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
const dataStore = {};
|
|
163
|
+
let currentTab = 'bibtex';
|
|
164
|
+
|
|
165
|
+
document.addEventListener('DOMContentLoaded', async () => {
|
|
166
|
+
buildTabStructure();
|
|
167
|
+
await Promise.all([
|
|
168
|
+
loadFileWithFallback('CITATION.bib'),
|
|
169
|
+
loadFileWithFallback('CITATION.cff')
|
|
170
|
+
]);
|
|
171
|
+
renderTabContent(currentTab);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
async function loadFileWithFallback(filename) {
|
|
175
|
+
try {
|
|
176
|
+
const response = await fetch(filename);
|
|
177
|
+
if (!response.ok) throw new Error(`Status ${response.status}`);
|
|
178
|
+
dataStore[filename] = await response.text();
|
|
179
|
+
return;
|
|
180
|
+
} catch (localErr) {
|
|
181
|
+
console.warn(`Lokaler Aufruf für "${filename}" fehlgeschlagen. Versuche Fallback...`);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
try {
|
|
185
|
+
const response = await fetch(GITHUB_RAW_BASE + filename);
|
|
186
|
+
if (!response.ok) throw new Error(`GitHub Status ${response.status}`);
|
|
187
|
+
dataStore[filename] = await response.text();
|
|
188
|
+
} catch (githubErr) {
|
|
189
|
+
dataStore[filename] = `[Fehler: Datei "${filename}" konnte nicht geladen werden.]`;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function buildTabStructure() {
|
|
194
|
+
const container = document.getElementById('tab-contents');
|
|
195
|
+
container.innerHTML = '';
|
|
196
|
+
Object.keys(TABS_CONFIG).forEach(key => {
|
|
197
|
+
const conf = TABS_CONFIG[key];
|
|
198
|
+
const tabDiv = document.createElement('div');
|
|
199
|
+
tabDiv.id = `content-${key}`;
|
|
200
|
+
tabDiv.className = `tab-content ${key === currentTab ? 'active' : ''}`;
|
|
201
|
+
tabDiv.innerHTML = `
|
|
202
|
+
<div class="action-bar">
|
|
203
|
+
<button class="btn btn-sm" onclick="downloadTabContent('${key}')" style="background:#1d7fa4; color:#fff;">
|
|
204
|
+
💾 ${conf.label} herunterladen
|
|
205
|
+
</button>
|
|
206
|
+
</div>
|
|
207
|
+
<pre id="pre-${key}" class="citation-pre">Wird geladen...</pre>
|
|
208
|
+
`;
|
|
209
|
+
container.appendChild(tabDiv);
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function parseBibTeX(bibText) {
|
|
214
|
+
const fields = {};
|
|
215
|
+
const matches = bibText.matchAll(/(\w+)\s*=\s*[{"]([^}"]+)[}"]/g);
|
|
216
|
+
for (const match of matches) {
|
|
217
|
+
fields[match[1].toLowerCase()] = match[2].trim();
|
|
218
|
+
}
|
|
219
|
+
return fields;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function formatCitation(bibText, style) {
|
|
223
|
+
const b = parseBibTeX(bibText);
|
|
224
|
+
const authors = b.author || 'Unknown Author';
|
|
225
|
+
const title = b.title || 'Untitled';
|
|
226
|
+
const year = b.year || 'n.d.';
|
|
227
|
+
const journal = b.journal || b.booktitle || '';
|
|
228
|
+
const volume = b.volume ? `, ${b.volume}` : '';
|
|
229
|
+
const number = b.number ? `(${b.number})` : '';
|
|
230
|
+
const pages = b.pages ? `, ${b.pages}` : '';
|
|
231
|
+
const doi = b.doi ? ` https://doi.org/${b.doi}` : '';
|
|
232
|
+
const url = b.url ? ` ${b.url}` : '';
|
|
233
|
+
const link = doi || url;
|
|
234
|
+
const note = b.note ? ` (${b.note})` : '';
|
|
235
|
+
const RIS_type = journal == '' ? 'COMP' : 'JOUR';
|
|
236
|
+
|
|
237
|
+
if (style === 'apa') {
|
|
238
|
+
return `${authors} (${year}). ${title}. ${journal}${volume}${number}${pages}.${note}${link}`;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (style === 'ieee') {
|
|
242
|
+
return `${authors}, "${title}," ${journal}${volume}${number}${pages}, ${year}.${note}${link}`;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (style === 'ris') {
|
|
246
|
+
const risLines = [
|
|
247
|
+
`TY - ${RIS_type}`,
|
|
248
|
+
`AU - ${authors}`,
|
|
249
|
+
`TI - ${title}`,
|
|
250
|
+
`JO - ${journal}`,
|
|
251
|
+
`PY - ${year}`,
|
|
252
|
+
`VL - ${b.volume || ''}`,
|
|
253
|
+
`IS - ${b.number || ''}`,
|
|
254
|
+
`SP - ${b.pages || ''}`,
|
|
255
|
+
`DO - ${b.doi || ''}`,
|
|
256
|
+
`UR - ${b.url || ''}`,
|
|
257
|
+
`AB - ${b.abstract || ''}`,
|
|
258
|
+
`N1 - ${b.note || ''}`
|
|
259
|
+
];
|
|
260
|
+
|
|
261
|
+
if (b.keywords) {
|
|
262
|
+
b.keywords.split(/[,;]/).forEach(kw => {
|
|
263
|
+
if (kw.trim()) risLines.push(`KW - ${kw.trim()}`);
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
risLines.push('ER -');
|
|
268
|
+
return risLines.filter(line => !line.endsWith(' - ')).join('\n');
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return bibText;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
async function renderTabContent(tabKey) {
|
|
275
|
+
const conf = TABS_CONFIG[tabKey];
|
|
276
|
+
const preElem = document.getElementById(`pre-${tabKey}`);
|
|
277
|
+
|
|
278
|
+
if (conf.type === 'raw') {
|
|
279
|
+
preElem.textContent = dataStore[conf.source] || 'Kein Inhalt verfügbar.';
|
|
280
|
+
} else if (conf.type === 'parsed') {
|
|
281
|
+
const rawBib = dataStore[conf.source];
|
|
282
|
+
if (!rawBib || rawBib.startsWith('[Fehler')) {
|
|
283
|
+
preElem.textContent = 'Zitationsdaten konnten nicht geladen werden.';
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
preElem.textContent = formatCitation(rawBib, conf.style);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
function switchTab(tabKey) {
|
|
291
|
+
currentTab = tabKey;
|
|
292
|
+
document.querySelectorAll('.tab-btn').forEach(btn => {
|
|
293
|
+
btn.classList.toggle('active', btn.getAttribute('onclick').includes(`'${tabKey}'`));
|
|
294
|
+
});
|
|
295
|
+
document.querySelectorAll('.tab-content').forEach(content => {
|
|
296
|
+
content.classList.toggle('active', content.id === `content-${tabKey}`);
|
|
297
|
+
});
|
|
298
|
+
renderTabContent(tabKey);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function downloadTabContent(tabKey) {
|
|
302
|
+
const conf = TABS_CONFIG[tabKey];
|
|
303
|
+
const text = document.getElementById(`pre-${tabKey}`).textContent;
|
|
304
|
+
const blob = new Blob([text], { type: `${conf.mime};charset=utf-8` });
|
|
305
|
+
const url = URL.createObjectURL(blob);
|
|
306
|
+
const a = document.createElement('a');
|
|
307
|
+
a.href = url;
|
|
308
|
+
a.download = conf.filename;
|
|
309
|
+
document.body.appendChild(a);
|
|
310
|
+
a.click();
|
|
311
|
+
document.body.removeChild(a);
|
|
312
|
+
URL.revokeObjectURL(url);
|
|
313
|
+
}
|
|
314
|
+
</script>
|
|
315
|
+
</body>
|
|
316
|
+
</html>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|