Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ADR for "entry(s)" #12127

Merged
merged 4 commits into from
Oct 31, 2024
Merged
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
3 changes: 2 additions & 1 deletion docs/code-howtos/localization.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,9 @@ To write a localized string in FXML file, prepend it with `%`, like in this code
## General hints

* Use the String you want to localize directly, do not use members or local variables: `Localization.lang("Translate me");` instead of `Localization.lang(someVariable)` (possibly in the form `someVariable = Localization.lang("Translate me")`
* Use `%x`-variables where appropriate: `Localization.lang("Exported %0 entries.", number)` instead of `Localization.lang("Exported ") + number + Localization.lang(" entries.");`
* Use `%x`-variables where appropriate: `Localization.lang("Exported %0 entry(s).", number)` instead of `Localization.lang("Exported ") + number + Localization.lang(" entry(s).");`
* Use a full stop/period (".") to end full sentences
* For pluralization, use a combined form. E.g., `Localization.lang("checked %0 entry(s)")`.

## Checking for correctness

Expand Down
95 changes: 95 additions & 0 deletions docs/decisions/0040-use-one-form-for-singular-and-plural.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
---
nav_order: 40
parent: Decision Records
---
<!-- we need to disable MD025, because we use the different heading "ADR Template" in the homepage (see above) than it is foreseen in the template -->
<!-- markdownlint-disable-next-line MD025 -->
# Use one language string for pluralization localization

## Context and Problem Statement

For user-facing messages, sometimes, it needs to be counted: E.g., 1 entry updated, 2 entries updated, etc.

In some languages, there is not only "one" and "more than one", but other forms:

* zero → “لم نزرع أي شجرة حتى الآن”
* one → “لقد زرعنا شجرة ١ حتى الآن”
* two → “لقد زرعنا شجرتين ٢ حتى الآن”
* few → “لقد زرعنا ٣ شجرات حتى الآن”
* many → “لقد زرعنا ١١ شجرة حتى الآن”
* other → “لقد زرعنا ١٠٠ شجرة حتى الآن”

(Example is from [Pluralization: A Guide to Localizing Plurals](https://phrase.com/blog/posts/pluralization/))

How to localize pluralization?

## Decision Drivers

* Good English language
* Good localization to other languages

## Considered Options

* Use one language string for pluralization (no explicit pluralization)
* Use singular and plural
* Handling of multiple forms

## Decision Outcome

Chosen option: "Use one form only (no explicit pluralization)", because it is the most easiest to handle in the code.

## Pros and Cons of the Options

### Use one language string for pluralization (no explicit pluralization)

Example:

- `Imported 0 entry(s)`
- `Imported 1 entry(s)`
- `Imported 12 entry(s)`

There are sub alternatives here:

* `Imported %0 entry(ies)`.
* `Number of entries imported: %0` (always use "other" plural form)

These arguments are for the general case of using a single text for all kinds of numbers:

* Good, because easy to handle in the code
* Bad, because reads strange in English UI

### Use singular and plural

Example:

- `Imported 0 entries`
- `Imported 1 entry`
- `Imported 12 entries`

* Good, because reads well in English
* Bad, because all localizations need to take an `if` check for the count
* Bad, because Arabic not localized properly

### Handling of multiple forms

Example:

- `Imported 0 entries`
- `Imported 1 entry`
- `Imported 12 entries`

Code: `Localization.lang("Imported %0 entries", "Imported %0 entry.", "Imported %0 entries.", "Imported %0 entries.", "Imported %0 entries.", "Imported %0 entries.", count)`

* Good, because reads well in English
* Bad, because sophisticated localization handling is required
* Bad, because no Java library for handling pluralization is known
* Bad, because Arabic not localized properly

## More Information

- [Language Plural Rules](https://www.unicode.org/cldr/charts/43/supplemental/language_plural_rules.html)
- [Unicode CLDR Project's Plural Rules](https://cldr.unicode.org/index/cldr-spec/plural-rules)
- [Implementation in Mozilla Firefox](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/PluralRules)
- [SX discussion on plural forms](https://english.stackexchange.com/a/90283/66058)

<!-- markdownlint-disable-file MD004 -->
6 changes: 3 additions & 3 deletions src/main/java/org/jabref/gui/LibraryTab.java
Original file line number Diff line number Diff line change
Expand Up @@ -906,7 +906,7 @@ public void insertEntries(final List<BibEntry> entries) {
public void copyEntry() {
int entriesCopied = doCopyEntry(getSelectedEntries());
if (entriesCopied >= 0) {
dialogService.notify(Localization.lang("Copied %0 entry(ies)", entriesCopied));
dialogService.notify(Localization.lang("Copied %0 entry(s)", entriesCopied));
} else {
dialogService.notify(Localization.lang("Copy failed", entriesCopied));
}
Expand Down Expand Up @@ -970,7 +970,7 @@ public void cutEntry() {
int entriesDeleted = doDeleteEntry(StandardActions.CUT, mainTable.getSelectedEntries());

if (entriesCopied == entriesDeleted) {
dialogService.notify(Localization.lang("Cut %0 entry(ies)", entriesCopied));
dialogService.notify(Localization.lang("Cut %0 entry(s)", entriesCopied));
} else {
dialogService.notify(Localization.lang("Cut failed", entriesCopied));
undoManager.undo();
Expand All @@ -983,7 +983,7 @@ public void cutEntry() {
*/
public void deleteEntry() {
int entriesDeleted = doDeleteEntry(StandardActions.DELETE_ENTRY, mainTable.getSelectedEntries());
dialogService.notify(Localization.lang("Deleted %0 entry(ies)", entriesDeleted));
dialogService.notify(Localization.lang("Deleted %0 entry(s)", entriesDeleted));
}

public void deleteEntry(BibEntry entry) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import org.slf4j.LoggerFactory;

/**
* Try to download fulltext PDF for selected entry(ies) by following URL or DOI link.
* Try to download fulltext PDF for selected entry(s) by following URL or DOI link.
*/
public class DownloadFullTextAction extends SimpleCommand {

Expand Down
6 changes: 3 additions & 3 deletions src/main/resources/l10n/JabRef_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2768,9 +2768,9 @@ Pushing\ citations\ to\ TeXShop\ is\ only\ possible\ on\ macOS\!=Pushing citatio

Single\ instance=Single instance

Copied\ %0\ entry(ies)=Copied %0 entry(ies)
Cut\ %0\ entry(ies)=Cut %0 entry(ies)
Deleted\ %0\ entry(ies)=Deleted %0 entry(ies)
Copied\ %0\ entry(s)=Copied %0 entry(s)
Cut\ %0\ entry(s)=Cut %0 entry(s)
Deleted\ %0\ entry(s)=Deleted %0 entry(s)

Enable\ Journal\ Information\ Fetching?=Enable Journal Information Fetching?
Would\ you\ like\ to\ enable\ fetching\ of\ journal\ information?\ This\ can\ be\ changed\ later\ in\ %0\ >\ %1.=Would you like to enable fetching of journal information? This can be changed later in %0 > %1.
Expand Down
Loading