Skip to content

Commit

Permalink
Refine .lang file spec
Browse files Browse the repository at this point in the history
Closing key tags are no longer needed, single line key/value sets are no longer allowed
  • Loading branch information
zajrik committed Jul 17, 2017
1 parent 7a6d9ce commit 0bcaf84
Show file tree
Hide file tree
Showing 19 changed files with 28 additions and 95 deletions.
26 changes: 11 additions & 15 deletions examples/LocalizationGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ potentially a lot of translating to be done if you wish to provide localizations

## .lang files
The first thing to cover is the file format. `.lang` is a simple data file format created specifically for
the purpose of providing strings for localization throughout the framework. It's slightly reminiscent of XML
but far simpler in that it only serves to hold key/value pairs where the value is a string. Here are a couple
the purpose of providing strings for localization throughout the framework. Here are a couple
simple examples:
```
[EXAMPLE_FOO] This is a single line string [/EXAMPLE_FOO]
[EXAMPLE_FOO]
Simple single-line string
[EXAMPLE_BAR]
This is a multi-line string.
Expand All @@ -19,13 +19,11 @@ This is a multi-line string.
Newlines are preserved as well, though you can \nadd newlines mid-line
as seen in the line above this, here -----------^
[/EXAMPLE_BAR]
```
The identifying string within the opening and closing tag is the key that will be used when retrieving
the string via `Lang.res()` or a ResourceLoader from `Lang.createResourceLoader()`.

>Note: The closing tag key must match the opening tag key. Nested tags are not supported and, if attempted, will be
parsed as part of the raw string value of the outer-most surrounding tag
There should not be anything directly above the key (the text in braces) or it will cause the following
key/value set to be parsed as part of the previous set. The text present in the braces for key/value
set is the key that will be used when retrieving the string via `Lang.res()` or a ResourceLoader from
`Lang.createResourceLoader()`.

Single-line and inline comments are also allowed, using the syntax `##`:
```
Expand All @@ -34,10 +32,9 @@ Single-line and inline comments are also allowed, using the syntax `##`:
## Here's another
foo bar baz ## And here's an inline comment
[/EXAMPLE_BAZ]
```
Comments are removed when parsing. Any text not enclosed within key-tags is inherently treated as a comment
and is ignored when parsing.
Comments are removed when parsing. Comments between key/value sets that do not end up captured as a part of
of a key/value set will not be captured at all.

## Templating
Unrelated to the `.lang` file format, but arguably the most important part of the localization system as a whole,
Expand All @@ -47,8 +44,8 @@ via matching keys within a {@link TemplateData} object passed to `Lang.res()` or
```
[TEMPLATE_EXAMPLE]
foo {{ barTemplate }} baz
[/TEMPLATE_EXAMPLE]
// When in use:
Lang.res('en_us', 'TEMPLATE_EXAMPLE', { barTemplate: 'bar' }) // Produces: 'foo bar baz'
```
Templates with a question mark (`{{ foo ?}}`) are "maybe templates". If a value is not given for that template it will
Expand All @@ -59,8 +56,8 @@ removed and a blank line will not be left behind:
foo{{ barTemplate ?}}baz
{{ emptyTemplate ?}}
boo
[/MAYBE_TEMPLATE_EXAMPLE]
// When in use:
Lang.res('en_us', 'MAYBE_TEMPLATE_EXAMPLE') // Produces: 'foobaz\nboo'
```
>Note: Passing empty strings for maybe templates results in them being removed in the same manner as if no value was given
Expand All @@ -79,7 +76,6 @@ the strings for the default help Command:
[CMD_HELP_ALIASES]
## 'Aliases: foo, bar' | 'Alias: foo'
{{! args.aliases.split(',').length > 1 ? 'Aliases' : 'Alias' !}}: {{ aliases }}
[/CMD_HELP_ALIASES]
```
>Note: A template script itself is just interpreted Javascript that must return a value. A template script that does not return a
value will simply have the template removed from the output string in the same manner as maybe templates. Implicit returns are
Expand Down
9 changes: 7 additions & 2 deletions src/localization/Lang.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,13 @@ export class Lang
for (const langFile of langs[langName])
{
if (!langNameRegex.test(langFile)) continue;
const loadedLangFile: string = fs.readFileSync(langFile).toString();
const parsedLanguageFile: Language = LangFileParser.parseFile(langName, loadedLangFile);
const loadedLangFile: string = fs
.readFileSync(langFile)
.toString()
.replace(/\r\n/g, '\n');

const parsedLanguageFile: Language =
LangFileParser.parseFile(langName, loadedLangFile);

if (typeof Lang._instance.langs[langName] !== 'undefined')
Lang._instance.langs[langName].concat(parsedLanguageFile);
Expand Down
9 changes: 4 additions & 5 deletions src/localization/LangFileParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Language } from './Language';
*/
export class LangFileParser
{
private static parseBlock: RegExp = /(\[([a-zA-Z0-9_]+)\]([^]+)\[\/\2\])/;
private static parseBlock: RegExp = /(\[(\w+)\]\n([\s\S]*?))(?=\n\n+?(?:## *.*\n)*\[\w+\]\n.+|\n*?$)/;
private static parseBlocks: RegExp = new RegExp(LangFileParser.parseBlock, 'g');
private static stripComments: RegExp = /^(?!$)\s*##.*\n|##.*$/gm;
private static trimNewlines: RegExp = /^\n|\n$/g;
Expand All @@ -15,17 +15,16 @@ export class LangFileParser
* Parse a given language file string and return a Language
* object containing all the parsed values
*/
public static parseFile(langName: string, langFile: string): Language
public static parseFile(langName: string, fileContents: string): Language
{
const lang: Language = new Language(langName);
const blocks: string[] = langFile.match(LangFileParser.parseBlocks);
const blocks: string[] = fileContents.match(LangFileParser.parseBlocks);
for (const block of blocks)
{
const match: RegExpMatchArray = block.match(LangFileParser.parseBlock);
const raw: string = match[1].replace(/\r\n/g, '\n');
const raw: string = match[1];
const key: string = match[2];
const value: string = match[3]
.replace(/\r\n/g, '\n')
.replace(LangFileParser.stripComments, '')
.replace(LangFileParser.trimNewlines, '')
.trim();
Expand Down
8 changes: 0 additions & 8 deletions src/localization/en_us/cmd/en_us.cmd.blacklist.lang
Original file line number Diff line number Diff line change
@@ -1,31 +1,23 @@
[CMD_BLACKLIST_ERR_NOSELF]
You can not blacklist your own account.
[/CMD_BLACKLIST_ERR_NOSELF]

[CMD_BLACKLIST_ERR_NOBOT]
Bots cannot call commands and thus do not need to be blacklisted.
[/CMD_BLACKLIST_ERR_NOBOT]

[CMD_BLACKLIST_ERR_OWNERONLY]
Only bot owners may blacklist globally.
[/CMD_BLACKLIST_ERR_OWNERONLY]

[CMD_BLACKLIST_ERR_ALREADYGLOBAL]
That user is already globally blacklisted.
[/CMD_BLACKLIST_ERR_ALREADYGLOBAL]

[CMD_BLACKLIST_ERR_BADTARGET]
You may not use this command on that person.
[/CMD_BLACKLIST_ERR_BADTARGET]

[CMD_BLACKLIST_ERR_ALREADYBLACKLISTED]
That user is already blacklisted in this server.
[/CMD_BLACKLIST_ERR_ALREADYBLACKLISTED]

[CMD_BLACKLIST_GLOBALSUCCESS]
Added {{ user }} to the global blacklist.
[/CMD_BLACKLIST_GLOBALSUCCESS]

[CMD_BLACKLIST_SUCCESS]
Added {{ user }} to the blacklist for this server.
[/CMD_BLACKLIST_SUCCESS]
2 changes: 0 additions & 2 deletions src/localization/en_us/cmd/en_us.cmd.clearlimit.lang
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
[CMD_CLEARLIMIT_UNKNOWN_COMMAND]
Failed to find a command with the name `{{ commandName }}`
[/CMD_CLEARLIMIT_UNKNOWN_COMMAND]

[CMD_CLEARLIMIT_SUCCESS]
Successfully cleared role limits for command: `{{ commandName }}`
[/CMD_CLEARLIMIT_SUCCESS]
5 changes: 1 addition & 4 deletions src/localization/en_us/cmd/en_us.cmd.disablegroup.lang
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
[CMD_DISABLEGROUP_ERR_NOEXIST]
Command group "{{ group }}" does not exist.
[/CMD_DISABLEGROUP_ERR_NOEXIST]

[CMD_DISABLEGROUP_ERR_DISABLED]
Command group "{{ group }}" is already disabled or is not allowed to be disabled.
[/CMD_DISABLEGROUP_ERR_DISABLED]

[CMD_DISABLEGROUP_SUCCESS]
**Disabled command group "{{ group }}"**
[/CMD_DISABLEGROUP_SUCCESS]
**Disabled command group "{{ group }}"**
3 changes: 0 additions & 3 deletions src/localization/en_us/cmd/en_us.cmd.enablegroup.lang
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
[CMD_ENABLEGROUP_ERR_NOEXIST]
Command group "{{ group }}" does not exist.
[/CMD_ENABLEGROUP_ERR_NOEXIST]

[CMD_ENABLEGROUP_ERR_ENABLED]
Command group "{{ group }}" is already enabled.
[/CMD_ENABLEGROUP_ERR_ENABLED]

[CMD_ENABLEGROUP_SUCCESS]
**Enabled command group "{{ group }}"**
[/CMD_ENABLEGROUP_SUCCESS]
3 changes: 0 additions & 3 deletions src/localization/en_us/cmd/en_us.cmd.eval.lang
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
```xl
No code provided to evaluate.
```
[/CMD_EVAL_ERR_NOCODE]

[CMD_EVAL_RESULT]
**INPUT:**
Expand All @@ -14,7 +13,6 @@ No code provided to evaluate.
```xl
{{ result }}
```
[/CMD_EVAL_RESULT]

[CMD_EVAL_ERROR]
**INPUT:**
Expand All @@ -25,4 +23,3 @@ No code provided to evaluate.
```xl
{{ error }}
```
[/CMD_EVAL_ERROR]
15 changes: 5 additions & 10 deletions src/localization/en_us/cmd/en_us.cmd.help.lang
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

[CMD_HELP_COMMAND_LIST]
Available commands: (Commands marked with `*` are server-only)
```ldif
Expand All @@ -7,20 +6,20 @@ Available commands: (Commands marked with `*` are server-only)
## weird spacing between it and the last line.
## I don't recommend using one
```Use `{{ usage }}` or `{{ mentionUsage }}` for more info
[/CMD_HELP_COMMAND_LIST]

[CMD_HELP_UNKNOWN_COMMAND]
A command by that name could not be found or you do
not have permission to view it.
[/CMD_HELP_UNKNOWN_COMMAND]

[CMD_HELP_SERVERONLY] [Server Only] [/CMD_HELP_SERVERONLY]
[CMD_HELP_OWNERONLY] [Owner Only] [/CMD_HELP_OWNERONLY]
[CMD_HELP_SERVERONLY]
[Server Only]

[CMD_HELP_OWNERONLY]
[Owner Only]

[CMD_HELP_ALIASES]
## 'Aliases: foo, bar' | 'Alias: foo'
{{! args.aliases.split(',').length > 1 ? 'Aliases' : 'Alias' !}}: {{ aliases }}
[/CMD_HELP_ALIASES]

[CMD_HELP_CODEBLOCK]
## I feel ldif is the best codeblock language for
Expand All @@ -35,16 +34,12 @@ Description: {{ desc }}
Usage: {{ usage }}
{{ info ?}}
```
[/CMD_HELP_CODEBLOCK]

[CMD_HELP_REPLY_CMD]
Sent you a DM with command help information.
[/CMD_HELP_REPLY_CMD]

[CMD_HELP_REPLY_ALL]
Sent you a DM with a list of commands.
[/CMD_HELP_REPLY_ALL]

[CMD_HELP_REPLY_FAIL]
Failed to DM help information. Do you have DMs blocked?
[/CMD_HELP_REPLY_FAIL]
6 changes: 0 additions & 6 deletions src/localization/en_us/cmd/en_us.cmd.limit.lang
Original file line number Diff line number Diff line change
@@ -1,27 +1,21 @@
[CMD_LIMIT_ERR_UNKNOWN_COMMAND]
Failed to find a command with the name `{{ commandName }}`
[/CMD_LIMIT_ERR_UNKNOWN_COMMAND]

[CMD_LIMIT_ERR_INVALID_GROUP]
Cannot limit base commands.
[/CMD_LIMIT_ERR_INVALID_GROUP]

[CMD_LIMIT_ERR_ALREADY_LIMITER]
Role `{{ roleName }}` is already a limiter for command: `{{ commandName }}`
[/CMD_LIMIT_ERR_ALREADY_LIMITER]

[CMD_LIMIT_ERR_INVALID_ROLE]
Failed to find {{!
args.invalidRoles.split(',').length > 1 ? 'roles' : 'role'
!}}: {{ invalidRoles }}
[/CMD_LIMIT_ERR_INVALID_ROLE]

[CMD_LIMIT_ERR_NO_ROLES]
Failed to add any roles to the command.
[/CMD_LIMIT_ERR_NO_ROLES]

[CMD_LIMIT_SUCCESS]
Successfully added {{!
args.roles.split(',').length > 1 ? 'roles' : 'role'
!}}: {{ roles }} to the limiter for command: `{{ commandName }}`
[/CMD_LIMIT_SUCCESS]
1 change: 0 additions & 1 deletion src/localization/en_us/cmd/en_us.cmd.listgroups.lang
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,3 @@ Command groups:
.map(g => `${args.disabledGroups.split(', ').includes(g) ? '*' : ' '}${g}`)
.join('\n')
!}}
[/CMD_LISTGROUPS_GROUPS]
2 changes: 0 additions & 2 deletions src/localization/en_us/cmd/en_us.cmd.reload.lang
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
[CMD_RELOAD_ERR_UNKNOWN_COMMAND]
Command "{{ commandName }}" could not be found.
[/CMD_RELOAD_ERR_UNKNOWN_COMMAND]

[CMD_RELOAD_SUCCESS]
{{!
args.commandName ?
`Command "${args.commandName}"` :
'Commands'
!}} reloaded. ({{ time }} ms)
[/CMD_RELOAD_SUCCESS]
3 changes: 0 additions & 3 deletions src/localization/en_us/cmd/en_us.cmd.setlang.lang
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,9 @@ Available languages: (Language marked with `*` is the current language)
## Be sure to preserve the `{{ prefix }}setlang #` part
```Use `{{ prefix }}setlang #`, where `#` is the number of the language to set the
language to use for this server
[/CMD_SETLANG_LIST]

[CMD_SETLANG_ERR_INVALID]
That is not a valid language choice!
[/CMD_SETLANG_ERR_INVALID]

[CMD_SETLANG_SUCCESS]
Set language for this server to: `{{ lang }}`
[/CMD_SETLANG_SUCCESS]
4 changes: 0 additions & 4 deletions src/localization/en_us/cmd/en_us.cmd.setprefix.lang
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,16 @@
`Current prefix is \`${args.prefix}\`` :
'There is currently no prefix.'
!}}
[/CMD_PREFIX_CURRENT]

[CMD_PREFIX_ERR_CHAR_LIMIT]
Prefixes may only be up to 10 chars in length.
[/CMD_PREFIX_ERR_CHAR_LIMIT]

[CMD_PREFIX_ERR_INVALID_CHARS]
Prefixes may not contain backticks or backslashes.
[/CMD_PREFIX_ERR_INVALID_CHARS]

[CMD_PREFIX_SUCCESS]
{{!
args.prefix === '' ?
'Command prefix removed.' :
`Command prefix set to \`${args.prefix}\``
!}}
[/CMD_PREFIX_SUCCESS]
3 changes: 0 additions & 3 deletions src/localization/en_us/cmd/en_us.cmd.version.lang

This file was deleted.

5 changes: 0 additions & 5 deletions src/localization/en_us/cmd/en_us.cmd.whitelist.lang
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
[CMD_WHITELIST_ERR_OWNERONLY]
Only bot owners may remove a user from the global blacklist.
[/CMD_WHITELIST_ERR_OWNERONLY]

[CMD_WHITELIST_ERR_NOTGLOBAL]
That user is not currently on the global blacklist.
[/CMD_WHITELIST_ERR_NOTGLOBAL]

[CMD_WHITELIST_ERR_NOTBLACKLISTED]
That user is not currently blacklisted in this server.
[/CMD_WHITELIST_ERR_NOTBLACKLISTED]

[CMD_WHITELIST_GLOBALSUCCESS]
Removed {{ user }} from the global blacklist.
[/CMD_WHITELIST_GLOBALSUCCESS]

[CMD_WHITELIST_SUCCESS]
Removed {{ user }} from the blacklist for this server.
[/CMD_WHITELIST_SUCCESS]
Loading

0 comments on commit 0bcaf84

Please sign in to comment.