Skip to content

Commit df0c9e7

Browse files
committed
Allow exporting as Anki deck
1 parent 581c5ad commit df0c9e7

File tree

5 files changed

+127
-2
lines changed

5 files changed

+127
-2
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ This applies from version 0.5.0 onwards, as some versions before that have broke
1212
## [Unreleased]
1313

1414
### Added
15+
16+
- Allow exporting as Anki deck (text file suitable for importing).
17+
1518
### Changed
1619
### Fixed
1720
### Removed

src/Data/GlossaryTitle.elm

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,4 @@ toFilename extension glossaryTitle =
4444
else
4545
result
4646
)
47-
|> (\result -> result ++ "." ++ extension)
47+
|> (\result -> result ++ extension)

src/Export/Anki.elm

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
module Export.Anki exposing (download)
2+
3+
import Data.AboutLink as AboutLink exposing (AboutLink)
4+
import Data.GlossaryItem exposing (GlossaryItem)
5+
import Data.GlossaryItems as GlossaryItems exposing (GlossaryItems)
6+
import Data.GlossaryTitle as GlossaryTitle exposing (GlossaryTitle)
7+
import File.Download as Download
8+
import Regex
9+
10+
11+
escape : String -> String
12+
escape string =
13+
string
14+
|> String.replace "\"" "\"\""
15+
|> String.replace "\t" " "
16+
17+
18+
comment : String -> String
19+
comment =
20+
let
21+
linebreaks =
22+
"[\u{000D}\n]"
23+
|> Regex.fromString
24+
|> Maybe.withDefault Regex.never
25+
in
26+
Regex.replace linebreaks (always " ")
27+
>> (++) "# "
28+
29+
30+
crlf : String
31+
crlf =
32+
"\u{000D}\n"
33+
34+
35+
lines : List String -> String
36+
lines =
37+
String.join crlf
38+
39+
40+
paragraphs : List String -> String
41+
paragraphs =
42+
List.filter (not << String.isEmpty)
43+
>> String.join (crlf ++ crlf)
44+
45+
46+
itemToAnki : GlossaryItem -> String
47+
itemToAnki { terms, details } =
48+
let
49+
quote string =
50+
"\"" ++ string ++ "\""
51+
52+
front =
53+
terms
54+
|> List.map (.body >> escape)
55+
|> lines
56+
|> quote
57+
58+
back =
59+
details
60+
|> List.map escape
61+
|> paragraphs
62+
|> quote
63+
in
64+
front ++ "\t" ++ back
65+
66+
67+
download : GlossaryTitle -> String -> List AboutLink -> GlossaryItems -> Cmd msg
68+
download glossaryTitle aboutParagraph aboutLinks glossaryItems =
69+
let
70+
filename =
71+
GlossaryTitle.toFilename "-Anki_deck.txt" glossaryTitle
72+
73+
instructionsComment =
74+
comment "This file is meant to be imported into Anki (https://docs.ankiweb.net/importing.html#text-files)."
75+
76+
titleComment =
77+
glossaryTitle |> GlossaryTitle.toString |> comment
78+
79+
aboutLinksComment =
80+
aboutLinks
81+
|> List.map
82+
(\aboutLink ->
83+
"* " ++ AboutLink.body aboutLink ++ " - " ++ AboutLink.href aboutLink
84+
)
85+
|> List.map comment
86+
|> lines
87+
88+
itemsString =
89+
glossaryItems
90+
|> GlossaryItems.orderedAlphabetically
91+
|> List.map (Tuple.second >> itemToAnki)
92+
|> lines
93+
94+
content =
95+
[ instructionsComment
96+
, comment ""
97+
, titleComment
98+
, comment ""
99+
, comment aboutParagraph
100+
, comment ""
101+
, aboutLinksComment
102+
, itemsString
103+
]
104+
|> lines
105+
in
106+
Download.string filename "text/plain" content

src/Export/Markdown.elm

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ download : GlossaryTitle -> String -> List AboutLink -> GlossaryItems -> Cmd msg
9494
download glossaryTitle aboutParagraph aboutLinks glossaryItems =
9595
let
9696
filename =
97-
GlossaryTitle.toFilename "md" glossaryTitle
97+
GlossaryTitle.toFilename ".md" glossaryTitle
9898

9999
titleHeaderString =
100100
glossaryTitle |> GlossaryTitle.toString |> escape |> (++) "# "

src/Pages/ListAll.elm

+16
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import Data.GlossaryItems as GlossaryItems exposing (GlossaryItems)
1616
import Data.GlossaryTitle as GlossaryTitle
1717
import Dict exposing (Dict)
1818
import ElementIds
19+
import Export.Anki
1920
import Export.Markdown
2021
import Extras.Html
2122
import Extras.HtmlAttribute
@@ -81,6 +82,7 @@ type InternalMsg
8182
| JumpToTermIndexGroup Bool String
8283
| ChangeOrderItemsBy CommonModel.OrderItemsBy
8384
| DownloadMarkdown GlossaryItems
85+
| DownloadAnki GlossaryItems
8486

8587

8688
type alias Msg =
@@ -305,6 +307,17 @@ update msg model =
305307
]
306308
)
307309

310+
DownloadAnki glossaryItems ->
311+
( { model | exportDropdownMenu = Components.DropdownMenu.hidden model.exportDropdownMenu }
312+
, Cmd.batch
313+
[ Export.Anki.download
314+
model.common.title
315+
model.common.aboutParagraph
316+
model.common.aboutLinks
317+
glossaryItems
318+
]
319+
)
320+
308321

309322
patchHtmlFile : CommonModel -> GlossaryItemIndex -> GlossaryItems -> Cmd Msg
310323
patchHtmlFile common indexOfItemBeingDeleted glossaryItems =
@@ -1101,6 +1114,9 @@ viewExportButton glossaryItems exportDropdownMenu =
11011114
, text "Export"
11021115
]
11031116
[ Components.DropdownMenu.choice
1117+
[ text "Anki deck" ]
1118+
(PageMsg.Internal <| DownloadAnki glossaryItems)
1119+
, Components.DropdownMenu.choice
11041120
[ text "Markdown" ]
11051121
(PageMsg.Internal <| DownloadMarkdown glossaryItems)
11061122
]

0 commit comments

Comments
 (0)