1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
# SRS Anywhere
SRS Anywhere is a free, browser-based flash card application using the [Free Spaced Repetition Scheduler (FSRS)](https://github.com/open-spaced-repetition/free-spaced-repetition-scheduler) algorithm.
It is similar to [Anki](https://en.wikipedia.org/wiki/Anki_(software)), except that it is entirely contained within static files and can therefore be used anywhere a web browser is available.
No server is necessary.
SRS Anywhere is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
SRS Anywhere is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with SRS Anywhere. If not, see <https://www.gnu.org/licenses/.>.
## Building
Just run `make`.
The build process is very simple, it just tangles the CSS and JavaScript code into an HTML template using `sed`.
## Usage
Open `srs-anywhere.html` in a web browser and press the "Browse..." button in the top right-hand corner to load a deck of cards.
The "?" button will display the available keyboard shortcuts.
When the review is complete, you will be prompted to download a JSON file.
This contains the deck of cards updated with new scheduling parameters for your next review.
SRS Anywhere comes with a simple editor for adding, editing, and removing cards from a deck.
Open `deck-editor.html` and press the "Browse..." button in the top right-hand corner to load a deck of cards.
The page will populate with one or more tables, each corresponding to a specific type of card, and input fields for part of the card.
The button labeled with a plus sign (+) will add a card of that type to the deck, with an automatically-generated ID.
Press the "Download JSON" button in the top right-hand corner to download the modified deck.
### Format for Cards
The `cards.json` file is an array of objects containing at least the keys `id`, `front`, and `back`.
The only requirement for `id` is that it's unique across the deck: it could be a UUID, but it could also be something more descriptive.
`front` and `back` are HTML fragments that are injected into the page when the card is shown.
Additional keys are permissible.
Keys generated and modified by SRS Anywhere are prefixed by the `_` character.
#### Example
```json
[
{
"id": "cca013c4-450a-41a1-abed-28abdc73413a",
"front": "What is the capital of Virginia?",
"back": "Richmond."
},
{
"id": "a8fc5101-2d22-4b20-b475-1db00f120654",
"front": "What is accomplished by Article II of the United States Constitution?",
"back": "Article II of the United States Constitution establishes the executive branch of the federal government, which carries out and enforces federal laws."
}
]
```
### Custom Cards
Custom card types can be defined in a `srs-anywhere-custom-card-types.js` file.
To register a new card type, add it as a new entry to the `CARD_TYPES` object, where the key is the the name of the card type.
A card type should be an object containing at least the following keys: `validate`, `front`, and `back`.
`validate` takes the card and throws an `Error` if it is malformed.
`front` returns the desired HTML code for the front of the card.
`back` returns the desired HTML code for the back of the card.
Optionally, `showFront` and `showBack` are functions that are evaluted when the front or back of the card are shown, respectively.
For example, to define a card type for a [cloze deletion test](https://en.wikipedia.org/wiki/Cloze_test):
```javascript
const CLOZE_REGEX = /\[.*?\]/ig;
CARD_TYPES["clozeAll"] = {
"validate": function (card) {
if (typeof card.back !== "string") {
throw new Error(`malformed card ${card.id}: invalid back (should be string)`)
}
if (!CLOZE_REGEX.test(card.back)) {
throw new Error(`malformed card ${card.id}: contains no cloze;
please enclose deletion in brackets (e.g., [...])`)
}
},
"front": (card) => card.back.replaceAll(CLOZE_REGEX, '[...]'),
"back": (card) => card.back
};
```
The `type` key in the cards JSON file associates an entry with the custom card type.
```javascript
{
"id": "cca013c4-450a-41a1-abed-28abdc73413a",
"type": "clozeAll",
"back": "This is a card containing a [cloze deletion]!"
}
```
|