Skip to content
main
Switch branches/tags
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Build Status Go Report Card Coverage Status

Turning notes into flashcards, or should I say concards! This is my ongoing attempt to make flashcards more simple and convenient. Concards provides much of the functionality of other mainstream flashcard applications, but with a unique focus on parsing cards embedded within text files.

Features

  • Spaced repetition similar to SM2!
  • UTF-8 as a first-class citizen!
  • Configure with your favorite editor!
  • Undo & Redo support!
  • Read from directories or files!
  • Reversible cards!
  • Cloze cards!

Install

Download the latest release from the release page. At the moment, only Linux and Mac are supported.

You can also build a snapshot from source with the go command.

$ go install github.com/alanxoc3/concards

Once installed, you may want to try running concards on this readme!

$ concards README.md

You may also want to review the help command's output.

$ concards --help

Basic Syntax

You can learn the full flashcard embedding syntax in just a few minutes! Let's get started.

Creating a flashcard

To make a flashcard, you must put the flashcard text within a concards block. A concards block looks like this #: :#, where text would be placed between the two colons. Ex:

#: This is a one sided flashcard. :#

The text above will produce a one sided flashcard! But flashcards are normally 2 sided, so let's create a new flashcard that separates a question and answer with the pipe symbol:

#: What is a great way to decrease the effects of the forgetting curve?
 | Spending time every day to review previously learned information. :#

Any number of sides are supported, so creating a 3 sided flashcard is a piece of cake:

#: What are Newton's 3 laws of motion?
 | 1. An object at rest stays at rest unless acted upon.
 | 2. Force is equal to mass times acceleration.
 | 3. For every action, there is an equal and opposite reaction. :#

You can either create new blocks for each card, or you can keep them in the same block. This creates 2 cards:

#: Who published the first flashcards? | Favell Lee Mortimer
#: When were the first flashcards published? | 1834 :#

Reversible Cards

When learning a language, you might find yourself writing a flashcard that transitions a phrase from language #1 to language #2 and writing another flashcard that transitions the same phrase from language #2 to language #1. Concards makes this easier with the :: operator

#: saluton al la mundo :: hello world :#

Generates these cards:

#: saluton al la mundo | hello world
#: hello world | saluton al la mundo :#

If you are learning two languages, you can expand this with an extra :::

#: spagetoj :: spaghetti :: 意面 :#

Generates these cards:

#: spagetoj | spaghetti | 意面
#: spaghetti | spagetoj | 意面
#: 意面 | spagetoj | spaghetti :#

Translating a word from one language to another often results in multiple definitions. Concards can represent these scenarios more efficiently when combining the | and ::.

#: apricot | almond :: 杏仁 :#

Generates these cards:

#: apricot | 杏仁
#: almond | 杏仁
#: 杏仁 | apricot | almond :#

The double colon operator always takes precedence before the pipe operator.

Cloze Cards

Cloze cards are handy when working with phrases or related facts. In concards, a cloze is created by putting text within a set of curly braces. Concards will generate cards from the text in the curly braces and replace the text with an empty set of curly braces.

#: {Hermann Ebbinghaus} published his findings on the forgetting curve in {1885}. :#

Generates these cards:

#: {} published his findings on the forgetting curve in 1885. | Hermann Ebbinghaus
#: Hermann Ebbinghaus published his findings on the forgetting curve in {}. | 1885 :#

Cloze nesting is supported:

#: {Education is the {kindling of a flame}}, {not the {filling of a vessel}}. :#

Generates these cards:

#: {}, not the filling of a vessel. | Education is the kindling of a flame
#: Education is the {}, not the filling of a vessel. | kindling of a flame
#: Education is the kindling of a flame, {}. | not the filling of a vessel
#: Education is the kindling of a flame, not the {}. | filling of a vessel :#

You can replace consecutive curly braces with the colon operator. This especially makes separation within a single word look nicer.

#: {Pneumono:ultra:microscopic:silico:volcano:coniosis} :#

Is the same as:

#: {Pneumono}{ultra}{microscopic}{silico}{volcano}{coniosis} :#

And generates these cards:

#: {}ultramicroscopicsilicovolcanoconiosis | Pneumono
#: Pneumono{}microscopicsilicovolcanoconiosis | ultra
#: Pneumonoultra{}silicovolcanoconiosis | microscopic
#: Pneumonoultramicroscopic{}volcanoconiosis | silico
#: Pneumonoultramicroscopicsilico{}coniosis | volcano
#: Pneumonoultramicroscopicsilicovolcano{} | coniosis :#

To group multiple clozes together, use the hash symbol before a set of curly braces.

#: #{Sebastian Leitner} published about the Leitner System in #{1972}. :#

Generates this card:

#: {} published about the Leitner System in {}. | Sebastian Leitner | 1972 :#

Cloze groups are different based on the number of hash symbols before the curly brace. Here is an example with 3 cloze groups:

#: ###{Spaced repetition} is an #{evidence-based} learning technique which
   ##{incorporates} increasing time intervals between each ##{review} of a
   flashcard in order to exploit the ###{psychological} #{spacing effect}. :#

Generates these cards:

#: Spaced repetition is an {} learning technique which incorporates increasing
   time intervals between each review of a flashcard in order to exploit the
   psychological {}.
 | evidence-based
 | spacing effect

#: Spaced repetition is an evidence-based learning technique which {}
   increasing time intervals between each {} of a flashcard in order to exploit
   the psychological spacing effect.
 | incorporates
 | review

#: {} is an evidence-based learning technique which incorporates increasing
   time intervals between each review of a flashcard in order to exploit the {}
   spacing effect.
 | Spaced repetition
 | psychological :#

Finally, you can combine the cloze syntax with :: and |:

#: {新型:冠状:病毒} :: Coronavirus | COVID-19 :#

Generates these cards:

#: {}冠状病毒 | 新型
#: 新型{}病毒 | 冠状
#: 新型冠状{} | 病毒
#: 新型冠状病毒 | Coronavirus | COVID-19
#: Coronavirus | 新型冠状病毒
#: COVID-19 | 新型冠状病毒 :#

Whitespace & Escaping

Concards ignores consecutive whitespace. The following flashcards are equivalent:

#: {Piotr A. Woźniak} created the SM-2 spaced repetition algorithm in {1987}.
#: { Piotr A. Woźniak } created the SM-2 spaced repetition algorithm in { 1987}.
#:{Piotr A. Woźniak }created the SM-2 spaced repetition algorithm in{ 1987}. :#

Generates these cards:

#: {} created the SM-2 spaced repetition algorithm in 1987. | Piotr A. Woźniak
#: Piotr A. Woźniak created the SM-2 spaced repetition algorithm in {}. | 1987 :#

Backslash any reserved character or whitespace to include it in the card text:

#: Which characters are special in concards?
 | \# \: \| \{ \}

#: Leave my door open just a crack\
Cause I feel like such an insomniac\
Why do I tire of counting sheep?\
When I'm far too tired to fall asleep
 | Fireflies, by Owl City :#

File Structure

Concards follows the XDG standard for config/data file placement.

Config Directory

The config directory is calculated by following this order of steps until one succeeds:

  1. concards --config-dir <directory>
  2. $CONCARDS_CONFIG_DIR
  3. $XDG_CONFIG_HOME/concards
  4. $HOME/.config/concards
  5. ./

Hooks

Hooks are currently an experimental feature. Concards hooks works similar to git hooks. You must place an executable file with a specific name in <config-dir>/hooks/. Hooks that begin with event- are meant to be run in parallel with concards and perform tasks that don't affect concards directly. Hooks that begin with hook- are similar to plugins in that they are meant to change program behavior.

Here are all the currently supported hooks:

  • hooks/event-review - executed right after passing off a card with a pass or fail
  • hooks/event-startup - executed once if/when concards starts the GUI up successfully

Data Directory

The data directory is calculated by following this order of steps until one succeeds:

  1. concards --data-dir <directory>
  2. $CONCARDS_DATA_DIR
  3. $XDG_DATA_HOME/concards
  4. $HOME/.local/share/concards
  5. ./

Concards has a very simple file structure. This section explains the content of the meta data files concards writes to after a review session.

The Predict File

The predict file is located at <data-dir>/predict. This file contains information needed to make a prediction when you should review a card next.

Here is an example predict file:

002141b9b9448a257b05da1f2eb78972 2020-08-08T18:00:17Z 2020-08-02T18:00:17Z 2 1 1 sm2
3dda75cb44ed447186834541475f32e2 2020-08-08T18:00:17Z 2020-08-02T18:00:17Z 1 3 -2 sm2

Here is that same file, but annotated:

sha256sum cut in half            | next timestamp       | previous timestamp   | total yes count | total no count | current streak | spaced repetition algorithm used
---------------------------------+----------------------+----------------------+---+---+----+----
002141b9b9448a257b05da1f2eb78972 | 2020-08-08T18:00:17Z | 2020-08-02T18:00:17Z | 2 | 1 |  1 | sm2
3dda75cb44ed447186834541475f32e2 | 2020-08-08T18:00:17Z | 2020-08-02T18:00:17Z | 1 | 3 | -2 | sm2

The Outcome File

The outcome file is located at <data-dir>/outcome. This file contains the historical outcomes of every time a card has been passed off or failed. It differs only slightly from the predict file. Here is the corresponding outcome file for the predict file example above:

002141b9b9448a257b05da1f2eb78972 2020-08-08T18:00:17Z 2020-08-02T18:00:17Z 0 0 0 0
002141b9b9448a257b05da1f2eb78972 2020-08-08T18:00:17Z 2020-08-02T18:00:17Z 0 1 -1 1
002141b9b9448a257b05da1f2eb78972 2020-08-08T18:00:17Z 2020-08-02T18:00:17Z 1 1 0 1
3dda75cb44ed447186834541475f32e2 2020-08-08T18:00:17Z 2020-08-02T18:00:17Z 0 0 0 1
3dda75cb44ed447186834541475f32e2 2020-08-08T18:00:17Z 2020-08-02T18:00:17Z 1 0 1 0
3dda75cb44ed447186834541475f32e2 2020-08-08T18:00:17Z 2020-08-02T18:00:17Z 1 1 0 0
3dda75cb44ed447186834541475f32e2 2020-08-08T18:00:17Z 2020-08-02T18:00:17Z 1 2 -1 0

You can notice that there are two main differences from the predict file:

  • There are usually multiple lines with the same hash.
  • The last column is a boolean "pass or fail" instead of an algorithm name.

Dependencies

Concards currently depends on these libraries:

Concards wouldn't be where it is today without those repositories & their contributors, so please check them out too!

Future Work

The next big things to focus on:

  • Improved CLI UI.
  • Local Web Server UI.
  • Support Unix Piping.
  • Customizable Algorithm Plugin System.