From 52617511b0ec2ee3c3615c1da6901ab5e2860b22 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Sun, 22 Nov 2020 15:30:59 +1000 Subject: [PATCH] automatically format/check ftl files --- ftl/BUILD.bazel | 20 +++++++++ ftl/core/card-stats.ftl | 1 - ftl/core/card-template-rendering.ftl | 28 ++++--------- ftl/core/decks.ftl | 9 ++-- ftl/core/empty-cards.ftl | 12 +++--- ftl/core/exporting.ftl | 27 ++++++------ ftl/core/findreplace.ftl | 9 ++-- ftl/core/media-check.ftl | 1 - ftl/core/network.ftl | 3 +- ftl/core/notetypes.ftl | 1 - ftl/core/scheduling.ftl | 9 ++-- ftl/core/search.ftl | 1 + ftl/core/studying.ftl | 27 ++++++------ ftl/core/sync.ftl | 1 + ftl/format.py | 62 ++++++++++++++++++++++++++++ ftl/format_check.py | 10 +++++ ftl/qt/preferences.ftl | 5 +-- ftl/qt/profiles.ftl | 3 +- ftl/qt/qt-misc.ftl | 9 ++-- 19 files changed, 162 insertions(+), 76 deletions(-) create mode 100644 ftl/format.py create mode 100644 ftl/format_check.py diff --git a/ftl/BUILD.bazel b/ftl/BUILD.bazel index 5356aa65d..e9d227a19 100644 --- a/ftl/BUILD.bazel +++ b/ftl/BUILD.bazel @@ -1,3 +1,5 @@ +load("@py_deps//:requirements.bzl", "requirement") + filegroup( name = "ftl", srcs = [ @@ -7,6 +9,24 @@ filegroup( visibility = ["//rslib:__subpackages__"], ) +py_binary( + name = "format", + srcs = ["format.py"], + deps = [requirement("fluent-syntax")], +) + +py_test( + name = "format_check", + srcs = [ + "format.py", + "format_check.py", + ], + # so we can locate data files + args = ["$(location BUILD.bazel)"], + data = glob(["**/*.ftl"]) + ["BUILD.bazel"], + deps = [requirement("fluent-syntax")], +) + # export this file as a way of locating the top level folder in $(location ...) exports_files( ["BUILD.bazel"], diff --git a/ftl/core/card-stats.ftl b/ftl/core/card-stats.ftl index ddaf797d9..af08defcd 100644 --- a/ftl/core/card-stats.ftl +++ b/ftl/core/card-stats.ftl @@ -22,4 +22,3 @@ card-stats-review-log-type-review = Review card-stats-review-log-type-relearn = Relearn card-stats-review-log-type-filtered = Filtered card-stats-review-log-type-manual = Manual - diff --git a/ftl/core/card-template-rendering.ftl b/ftl/core/card-template-rendering.ftl index 42e1b66b1..bff3327a0 100644 --- a/ftl/core/card-template-rendering.ftl +++ b/ftl/core/card-template-rendering.ftl @@ -4,39 +4,27 @@ # Label of link users can click on card-template-rendering-more-info = More information - card-template-rendering-front-side-problem = Front template has a problem: card-template-rendering-back-side-problem = Back template has a problem: - # when the user forgot to close a field reference, # eg, Missing '}}' in '{{Field' -card-template-rendering-no-closing-brackets = - Missing '{$missing}' in '{$tag}' - +card-template-rendering-no-closing-brackets = Missing '{ $missing }' in '{ $tag }' # when the user opened a conditional, but forgot to close it # eg, Missing '{{/Conditional}}' -card-template-rendering-conditional-not-closed = - Missing '{$missing}' - +card-template-rendering-conditional-not-closed = Missing '{ $missing }' # when the user closed the wrong conditional # eg, Found '{{/Something}}', but expected '{{/SomethingElse}}' -card-template-rendering-wrong-conditional-closed = - Found '{$found}', but expected '{$expected}' - +card-template-rendering-wrong-conditional-closed = Found '{ $found }', but expected '{ $expected }' # when the user closed a conditional that wasn't open # eg, Found '{{/Something}}', but missing '{{#Something}}' or '{{^Something}}' -card-template-rendering-conditional-not-open = - Found '{$found}', but missing '{$missing1}' or '{$missing2}' - +card-template-rendering-conditional-not-open = Found '{ $found }', but missing '{ $missing1 }' or '{ $missing2 }' # when the user referenced a field that doesn't exist # eg, Found '{{Field}}', but there is not field called 'Field' -card-template-rendering-no-such-field = - Found '{$found}', but there is no field called '{$field}' - +card-template-rendering-no-such-field = Found '{ $found }', but there is no field called '{ $field }' # This message is shown when the front side of the card is blank, # either due to a badly-designed template, or because required fields # are missing. card-template-rendering-empty-front = The front of this card is blank. - -card-template-rendering-missing-cloze = No cloze { $number } found on card. - Please either add a cloze deletion, or use the Empty Cards tool. +card-template-rendering-missing-cloze = + No cloze { $number } found on card. + Please either add a cloze deletion, or use the Empty Cards tool. diff --git a/ftl/core/decks.ftl b/ftl/core/decks.ftl index 4eecee62a..222a993c2 100644 --- a/ftl/core/decks.ftl +++ b/ftl/core/decks.ftl @@ -31,7 +31,8 @@ decks-reschedule-cards-based-on-my-answers = Reschedule cards based on my answer decks-study = Study decks-study-deck = Study Deck decks-the-provided-search-did-not-match = The provided search did not match any cards. Would you like to revise it? -decks-it-has-card = { $count -> - [one] It has { $count } card. - *[other] It has { $count } cards. - } +decks-it-has-card = + { $count -> + [one] It has { $count } card. + *[other] It has { $count } cards. + } diff --git a/ftl/core/empty-cards.ftl b/ftl/core/empty-cards.ftl index e03144fcb..cbc9f91a9 100644 --- a/ftl/core/empty-cards.ftl +++ b/ftl/core/empty-cards.ftl @@ -1,14 +1,14 @@ empty-cards-for-note-type = Empty cards for { $notetype }: -empty-cards-count-line = - { $empty_count } of { $existing_count } cards empty ({ $template_names }). +empty-cards-count-line = { $empty_count } of { $existing_count } cards empty ({ $template_names }). empty-cards-window-title = Empty Cards empty-cards-preserve-notes-checkbox = Keep notes with no valid cards empty-cards-delete-button = Delete empty-cards-not-found = No empty cards. -empty-cards-deleted-count = Deleted { $cards -> - [one] { $cards } card. - *[other] { $cards } cards. - } +empty-cards-deleted-count = + Deleted { $cards -> + [one] { $cards } card. + *[other] { $cards } cards. + } empty-cards-delete-empty-cards = Delete Empty Cards empty-cards-delete-empty-notes = Delete Empty Notes empty-cards-deleting = Deleting... diff --git a/ftl/core/exporting.ftl b/ftl/core/exporting.ftl index 7d66820c5..c373b63ed 100644 --- a/ftl/core/exporting.ftl +++ b/ftl/core/exporting.ftl @@ -15,15 +15,18 @@ exporting-include-scheduling-information = Include scheduling information exporting-include-tags = Include tags exporting-notes-in-plain-text = Notes in Plain Text exporting-selected-notes = Selected Notes -exporting-card-exported = { $count -> - [one] { $count } card exported. - *[other] { $count } cards exported. - } -exporting-exported-media-file = { $count -> - [one] Exported { $count } media file - *[other] Exported { $count } media files - } -exporting-note-exported = { $count -> - [one] { $count } note exported. - *[other] { $count } notes exported. - } +exporting-card-exported = + { $count -> + [one] { $count } card exported. + *[other] { $count } cards exported. + } +exporting-exported-media-file = + { $count -> + [one] Exported { $count } media file + *[other] Exported { $count } media files + } +exporting-note-exported = + { $count -> + [one] { $count } note exported. + *[other] { $count } notes exported. + } diff --git a/ftl/core/findreplace.ftl b/ftl/core/findreplace.ftl index ad08c7a2b..85e7ed905 100644 --- a/ftl/core/findreplace.ftl +++ b/ftl/core/findreplace.ftl @@ -1,4 +1,5 @@ -findreplace-notes-updated = { $total -> - [one] {$changed} of {$total} note updated - *[other] {$changed} of {$total} notes updated - } +findreplace-notes-updated = + { $total -> + [one] { $changed } of { $total } note updated + *[other] { $changed } of { $total } notes updated + } diff --git a/ftl/core/media-check.ftl b/ftl/core/media-check.ftl index 02b52e23b..af6f9458d 100644 --- a/ftl/core/media-check.ftl +++ b/ftl/core/media-check.ftl @@ -1,7 +1,6 @@ ## Shown at the top of the media check screen media-check-window-title = Check Media - # the number of files, and the total space used by files # that have been moved to the trash folder. eg, # "Trash folder: 3 files, 3.47MB" diff --git a/ftl/core/network.ftl b/ftl/core/network.ftl index 9fff6a92b..660e410fd 100644 --- a/ftl/core/network.ftl +++ b/ftl/core/network.ftl @@ -2,5 +2,4 @@ network-offline = Please check your internet connection. network-timeout = Connection timed out. Please try again. If you see frequent timeouts, please try a different network connection. network-proxy-auth = Your proxy requires authentication. network-other = A network error occurred. - -network-details = Error details: {$details} +network-details = Error details: { $details } diff --git a/ftl/core/notetypes.ftl b/ftl/core/notetypes.ftl index d20d7fff9..5e993c0c2 100644 --- a/ftl/core/notetypes.ftl +++ b/ftl/core/notetypes.ftl @@ -18,7 +18,6 @@ notetypes-cloze-name = Cloze notetypes-card-1-name = Card 1 notetypes-card-2-name = Card 2 - notetypes-add = Add: { $val } notetypes-add-note-type = Add Note Type notetypes-cards = Cards... diff --git a/ftl/core/scheduling.ftl b/ftl/core/scheduling.ftl index be774a8d0..861c365e8 100644 --- a/ftl/core/scheduling.ftl +++ b/ftl/core/scheduling.ftl @@ -138,7 +138,8 @@ scheduling-steps-must-be-numbers = Steps must be numbers. scheduling-tag-only = Tag Only scheduling-the-default-configuration-cant-be-removed = The default configuration can't be removed. scheduling-your-changes-will-affect-multiple-decks = Your changes will affect multiple decks. If you wish to change only the current deck, please add a new options group first. -scheduling-deck-updated = { $count -> - [one] { $count } deck updated. - *[other] { $count } decks updated. - } +scheduling-deck-updated = + { $count -> + [one] { $count } deck updated. + *[other] { $count } decks updated. + } diff --git a/ftl/core/search.ftl b/ftl/core/search.ftl index 4f4de7f60..8bb63dbe7 100644 --- a/ftl/core/search.ftl +++ b/ftl/core/search.ftl @@ -6,3 +6,4 @@ search-note-modified = Note Modified search-card-modified = Card Modified ## + diff --git a/ftl/core/studying.ftl b/ftl/core/studying.ftl index 8f8b6180e..3cc23ffef 100644 --- a/ftl/core/studying.ftl +++ b/ftl/core/studying.ftl @@ -42,15 +42,18 @@ studying-type-answer-unknown-field = Type answer: unknown field { $val } studying-unbury = Unbury studying-what-would-you-like-to-unbury = What would you like to unbury? studying-you-havent-recorded-your-voice-yet = You haven't recorded your voice yet. -studying-card-studied-in = { $count -> - [one] { $count } card studied in - *[other] { $count } cards studied in - } -studying-minute = { $count -> - [one] { $count } minute. - *[other] { $count } minutes. - } -studying-note-and-its-card-deleted = { $count -> - [one] Note and its { $count } card deleted. - *[other] Note and its { $count } cards deleted. - } +studying-card-studied-in = + { $count -> + [one] { $count } card studied in + *[other] { $count } cards studied in + } +studying-minute = + { $count -> + [one] { $count } minute. + *[other] { $count } minutes. + } +studying-note-and-its-card-deleted = + { $count -> + [one] Note and its { $count } card deleted. + *[other] Note and its { $count } cards deleted. + } diff --git a/ftl/core/sync.ftl b/ftl/core/sync.ftl index 73ace090c..0b2f99d4b 100644 --- a/ftl/core/sync.ftl +++ b/ftl/core/sync.ftl @@ -1,5 +1,6 @@ ### Messages shown when synchronizing with AnkiWeb. + ## Media synchronization sync-media-added-count = Added: { $up }↑ { $down }↓ diff --git a/ftl/format.py b/ftl/format.py new file mode 100644 index 000000000..402ed92f1 --- /dev/null +++ b/ftl/format.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +# -*- coding: UTF-8 -*- + +""" +Parse and re-serialize ftl files to get them in a consistent form. +""" + +import os +import json +import glob +import sys +from typing import List +from fluent.syntax import parse, serialize +from fluent.syntax.ast import Junk + + +def check_file(path: str, fix: bool) -> bool: + "True if file is ok." + orig_text = open(path).read() + obj = parse(orig_text, with_spans=False) + # make sure there's no junk + for ent in obj.body: + if isinstance(ent, Junk): + raise Exception(f"file had junk! {path} {ent}") + # serialize + new_text = serialize(obj) + # make sure serializing did not introduce new junk + obj = parse(new_text, with_spans=False) + for ent in obj.body: + if isinstance(ent, Junk): + raise Exception(f"file introduced junk! {path} {ent}") + + if new_text == orig_text: + return True + + if fix: + print(f"Fixing {path}") + open(path, "w", newline="\n", encoding="utf8").write(new_text) + return True + else: + print(f"Bad formatting in {path}") + return False + + +def check_files(files: List[str], fix: bool) -> bool: + "True if files ok." + + found_bad = False + for path in files: + ok = check_file(path, fix) + if not ok: + found_bad = True + return True + + +if __name__ == "__main__": + template_root = os.environ["BUILD_WORKSPACE_DIRECTORY"] + template_files = glob.glob( + os.path.join(template_root, "ftl", "*", "*.ftl"), recursive=True + ) + + check_files(template_files, fix=True) diff --git a/ftl/format_check.py b/ftl/format_check.py new file mode 100644 index 000000000..9df5ed058 --- /dev/null +++ b/ftl/format_check.py @@ -0,0 +1,10 @@ +import os +import format +import sys +import glob + +template_root = os.path.dirname(sys.argv[1]) +template_files = glob.glob(os.path.join(template_root, "*", "*.ftl"), recursive=True) + +if not format.check_files(template_files, fix=False): + sys.exit(1) diff --git a/ftl/qt/preferences.ftl b/ftl/qt/preferences.ftl index 7e4249e16..7d64939a0 100644 --- a/ftl/qt/preferences.ftl +++ b/ftl/qt/preferences.ftl @@ -1,7 +1,6 @@ # shown instead of the 'night mode' option when night mode is forced on because # macOS is in dark mode preferences-dark-mode-active = macOS is in dark mode - preferences-dark-mode-disable = - To show Anki in light mode while macOS is in dark mode, please - see the Night Mode section of the manual. + To show Anki in light mode while macOS is in dark mode, please + see the Night Mode section of the manual. diff --git a/ftl/qt/profiles.ftl b/ftl/qt/profiles.ftl index 261b10397..924f126fc 100644 --- a/ftl/qt/profiles.ftl +++ b/ftl/qt/profiles.ftl @@ -3,7 +3,6 @@ profiles-folder-readme = to make backups easy. To tell Anki to use a different location, please see: - {$link} - + { $link } # will appear as 'Downgrade & Quit' profiles-downgrade-and-quit = Downgrade && Quit diff --git a/ftl/qt/qt-misc.ftl b/ftl/qt/qt-misc.ftl index bac7bc46c..f7bf66c60 100644 --- a/ftl/qt/qt-misc.ftl +++ b/ftl/qt/qt-misc.ftl @@ -61,7 +61,8 @@ qt-misc-would-you-like-to-download-it = Would you like to download it now? qt-misc-your-collection-file-appears-to-be = Your collection file appears to be corrupt. This can happen when the file is copied or moved while Anki is open, or when the collection is stored on a network or cloud drive. If problems persist after restarting your computer, please open an automatic backup from the profile screen. qt-misc-your-computers-storage-may-be-full = Your computer's storage may be full. Please delete some unneeded files, then try again. qt-misc-your-firewall-or-antivirus-program-is = Your firewall or antivirus program is preventing Anki from creating a connection to itself. Please add an exception for Anki. -qt-misc-second = { $count -> - [one] { $count } second - *[other] { $count } seconds - } +qt-misc-second = + { $count -> + [one] { $count } second + *[other] { $count } seconds + }