Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions internal/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,11 @@ func (s *Session) updateCardInFile(c *Card) {
check(err)
md := string(data)
re := regexp.MustCompile(fmt.Sprintf(`<!--\s*%s;\d;\d{4}-\d{2}-\d{2}\s*-->`, c.Id))
md = re.ReplaceAllString(md, fmt.Sprintf("<!--%s;%d;%s-->", c.Id, c.Box, c.Due.Format("2006-01-02")))
markString := ""
if c.Marked {
markString = ";fixme"
}
md = re.ReplaceAllString(md, fmt.Sprintf("<!--%s;%d;%s%s-->", c.Id, c.Box, c.Due.Format("2006-01-02"), markString))
err = os.WriteFile(s.File.Path, []byte(md), 0644)
check(err)
}
Expand Down Expand Up @@ -193,7 +197,7 @@ func (s *Session) ChooseCategory() {
}

fmt.Print("Your choice: ")
choice := ReadNumberInput(1, len(categories))
choice, _ := ReadNumberInput(1, len(categories))
s.Category = categories[choice-1]
}

Expand Down
17 changes: 11 additions & 6 deletions internal/leitner.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type Card struct {
Back string
Category string
Id string
Marked bool
// Box number starts at 0
Box uint
Due time.Time
Expand Down Expand Up @@ -69,7 +70,7 @@ func (s *Session) Start() {
// Start the study session.
for len(s.studyQueue) > 0 {
ScrollDownScreen()
card, difficulty := s.flashNextCard()
card, difficulty, marked := s.flashNextCard()

// If in test mode, don't update the metadata.
if s.TestMode {
Expand All @@ -84,7 +85,7 @@ func (s *Session) Start() {
testModeResults.Easy++
}
} else {
s.updateCard(card, difficulty)
s.updateCard(card, difficulty, marked)
}
}

Expand Down Expand Up @@ -176,7 +177,7 @@ func (s *Session) assembleStudyQueue() {

// flashNextCard Shows a card's front side. The card is picked from the study queue.
// Waits for the user to press a key to signal how difficult the card was to remember.
func (s *Session) flashNextCard() (c *Card, difficulty float32) {
func (s *Session) flashNextCard() (c *Card, difficulty float32, marked bool) {
ClearConsole()
fmt.Printf("--- Cards left for today: %d / %d", len(s.studyQueue), s.NumberCards)

Expand All @@ -198,9 +199,10 @@ func (s *Session) flashNextCard() (c *Card, difficulty float32) {
back := WrapLines(c.Back, s.WrapLines)
fmt.Printf("\n%s\n", back)

fmt.Println("--> Enter (m) to mark card with 'fixme' tag.")
fmt.Println("--> How difficult was it to remember?")
fmt.Printf("--> (1) Not remembered, (2) Hard, (3) Okay, (4) Easy: ")
d := ReadNumberInput(1, 4)
d, marked := ReadNumberInput(1, 4)
switch d {
case 1:
difficulty = NotRemembered
Expand All @@ -211,12 +213,12 @@ func (s *Session) flashNextCard() (c *Card, difficulty float32) {
case 4:
difficulty = Easy
}
return c, difficulty
return c, difficulty, marked
}

// updateCard Updates the card's metadata (box and due date) according to the user's input.
// It may also add the card back to the study queue if the answer was not remembered.
func (s *Session) updateCard(c *Card, difficulty float32) {
func (s *Session) updateCard(c *Card, difficulty float32, marked bool) {
if difficulty == NotRemembered {
// Move the card to the first box, reset the due date to today, and add it back to the study queue.
c.Box = 0
Expand All @@ -236,5 +238,8 @@ func (s *Session) updateCard(c *Card, difficulty float32) {
}
c.Due = time.Date(y, m, d, 0, 0, 0, 0, time.UTC).AddDate(0, 0, daysInFuture)
}
if marked {
c.Marked = true
}
s.updateCardInFile(c)
}
18 changes: 12 additions & 6 deletions internal/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,27 @@ func PrintJSON[T any](v T) {
fmt.Println(string(out))
}

// ReadNumberInput reads a number from standard input. The number must be within i and j. If it is not, it will retry.
func ReadNumberInput(i, j int) int {
res := i - 1
// ReadNumberInput reads a number or "m" symbol from standard input.
// The number must be within i and j. If it is not, it will retry.
func ReadNumberInput(i, j int) (int, bool) {
marked := false
scanner := bufio.NewScanner(os.Stdin)
for res < i || res > j {

for {
scanner.Scan()
in := scanner.Text()
if in == "m" {
marked = true
fmt.Print("Card marked for edit. Please enter a number: ")
continue
}
nr, err := strconv.Atoi(in)
if err != nil || nr < i || nr > j {
fmt.Print("Please enter a number: ")
continue
}
res = nr
return nr, marked
}
return res
}

// ReadEnterInput Blocks until the user enters a newline.
Expand Down
8 changes: 4 additions & 4 deletions test.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

some text that won't be parsed

## Why do broadcast algorithms differentiate between receiving and delivering? Some more text here to test the width setting and line wraps.
## Why do broadcast algorithms differentiate between receiving and delivering? Some more text here to test the width setting and line wraps. <!--H07U;0;2025-12-17-->
Because between the network and the application there lies the broadcast algorithm as a middleware. The algorithm decides, whether a message which the node received is forwarded (i.e. delivered) to the application.

The same applies to the send. An application only sees the broadcast call but the middleware then spreads it into multiple point-to-point messages.

## Which types of reliable broadcast are there?
## Which types of reliable broadcast are there? <!--Ren2;1;2025-12-18-->

- FIFO broadcast
- Causal broadcast
Expand All @@ -18,7 +18,7 @@ The same applies to the send. An application only sees the broadcast call but th

A1

## Q2 <!-- YKuO;0;2023-02-24-->
## Q2 <!--oCH3;0;2025-12-17-->

A2
## Q3 <!--0YK7;2;2023-02-26 -->
Expand All @@ -27,7 +27,7 @@ A3
# T2
some other text

## Q4 <!--fjJd;0;2023-02-24-->
## Q4 <!--fjJd;0;2025-12-17-->

A4

Expand Down