diff --git a/.gitignore b/.gitignore
index 86c063c..cedb7b8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,3 +15,6 @@ runtime.*.liblouis/runtimes/
# Rider / ReSharper per-user settings
*.DotSettings.user
+
+# Worktrees created by spawned Claude Code sessions
+.claude/worktrees/
diff --git a/LibLouis.NET.Test/BrailleSpec.cs b/LibLouis.NET.Test/BrailleSpec.cs
new file mode 100644
index 0000000..a3e944e
--- /dev/null
+++ b/LibLouis.NET.Test/BrailleSpec.cs
@@ -0,0 +1,398 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+using YamlDotNet.Core;
+using YamlDotNet.Core.Events;
+
+namespace LibLouis.NET.Test;
+
+///
+/// One translation case from an upstream braille spec.
+///
+public sealed record BrailleSpecCase(
+ string SpecFile,
+ int Line,
+ string TableQuery,
+ string? AssertMatch,
+ string DisplayTable,
+ string Input,
+ string Expected,
+ TestDirection Direction,
+ bool ExpectedToFail)
+{
+ public override string ToString() =>
+ $"{SpecFile}:{Line} {Direction} {Describe(Input)} -> {Describe(Expected)}";
+
+ // Braille output is mostly U+28xx, which is unreadable in a test runner's output, so show the
+ // code points for anything outside printable ASCII.
+ private static string Describe(string value) =>
+ value.All(c => c is >= ' ' and <= '~')
+ ? $"\"{value}\""
+ : string.Concat(value.Select(c => c is >= ' ' and <= '~' ? c.ToString() : $"\\u{(int)c:X4}"));
+}
+
+public enum TestDirection
+{
+ Forward,
+ Backward,
+}
+
+///
+/// How a spec entry's two values are used. The distinction matters: the backward leg of
+/// bothDirections swaps input and expected (lou_checkyaml.c:900-902), while an explicit
+/// backward testmode does not (lou_checkyaml.c:892-895).
+///
+public enum TestMode
+{
+ Forward,
+ Backward,
+ BothDirections,
+}
+
+///
+/// Reads liblouis braille spec files.
+///
+///
+/// These files are not YAML mappings and cannot be deserialised. A single document repeats
+/// table, flags and tests at the same level, which duplicate key handling
+/// would collapse or reject. lou_checkyaml treats the file as an event stream where each key
+/// mutates parser state, and tests executes against whatever is current
+/// (tools/lou_checkyaml.c:1087-1139), so this reader does the same over YamlDotNet's IParser.
+///
+/// Consecutive table keys accumulate rather than replace: the following tests block
+/// runs once per accumulated table. flags persists until the next flags.
+///
+/// Only the constructs the Danish specs actually use are supported. Anything else throws rather
+/// than being skipped, so a spec using a feature this reader does not model fails loudly instead
+/// of silently testing less than it appears to.
+///
+public static class BrailleSpecReader
+{
+ public static IReadOnlyList Read(string path)
+ {
+ string specFile = Path.GetFileName(path);
+ var cases = new List();
+
+ using var reader = new StreamReader(path);
+ var parser = new Parser(reader);
+
+ parser.Consume();
+ parser.Consume();
+ parser.Consume();
+
+ string displayTable = string.Empty;
+ var tables = new List<(string Query, string? AssertMatch)>();
+ TestMode mode = TestMode.Forward;
+
+ // Consecutive table keys accumulate, but the first one after a tests block starts a fresh
+ // set rather than adding to the one just used.
+ bool tablesUsed = false;
+
+ while (parser.Current is not MappingEnd)
+ {
+ string key = parser.Consume().Value;
+
+ switch (key)
+ {
+ case "display":
+ displayTable = ReadTableValue(parser).Query;
+ break;
+
+ case "table":
+ if (tablesUsed)
+ {
+ tables.Clear();
+ tablesUsed = false;
+ }
+
+ tables.Add(ReadTableValue(parser));
+ break;
+
+ case "flags":
+ mode = ReadFlags(parser);
+ break;
+
+ case "tests":
+ ReadTests(parser, specFile, tables, displayTable, mode, cases);
+ tablesUsed = true;
+ break;
+
+ default:
+ throw new NotSupportedException(
+ $"{specFile}: unsupported top level key '{key}'. This reader models only the " +
+ "constructs the Danish specs use; see lou_checkyaml.c for the full format.");
+ }
+
+ }
+
+ return cases;
+ }
+
+ ///
+ /// A table value is either a file name or a query mapping. Queries are passed to lou_findTable
+ /// as "key:value key:value"; __assert-match is a harness directive, not part of the query.
+ ///
+ private static (string Query, string? AssertMatch) ReadTableValue(IParser parser)
+ {
+ if (parser.Current is Scalar scalar)
+ {
+ parser.MoveNext();
+ return (scalar.Value, null);
+ }
+
+ parser.Consume();
+
+ var terms = new List();
+ string? assertMatch = null;
+
+ while (parser.Current is not MappingEnd)
+ {
+ string key = parser.Consume().Value;
+ string value = parser.Consume().Value;
+
+ if (key == "__assert-match")
+ {
+ assertMatch = value;
+ }
+ else
+ {
+ terms.Add($"{key}:{value}");
+ }
+ }
+
+ parser.Consume();
+
+ return (string.Join(' ', terms), assertMatch);
+ }
+
+ private static TestMode ReadFlags(IParser parser)
+ {
+ parser.Consume();
+
+ TestMode mode = TestMode.Forward;
+
+ while (parser.Current is not MappingEnd)
+ {
+ string key = parser.Consume().Value;
+ string value = parser.Consume().Value;
+
+ if (key != "testmode")
+ {
+ throw new NotSupportedException($"unsupported flag '{key}'");
+ }
+
+ mode = ParseTestMode(value);
+ }
+
+ parser.Consume();
+
+ return mode;
+ }
+
+ private static TestMode ParseTestMode(string value) => value switch
+ {
+ "forward" => TestMode.Forward,
+ "backward" => TestMode.Backward,
+ "bothDirections" => TestMode.BothDirections,
+ _ => throw new NotSupportedException($"unsupported testmode '{value}'"),
+ };
+
+ private static void ReadTests(
+ IParser parser,
+ string specFile,
+ List<(string Query, string? AssertMatch)> tables,
+ string displayTable,
+ TestMode mode,
+ List cases)
+ {
+ parser.Consume();
+
+ while (parser.Current is not SequenceEnd)
+ {
+ SequenceStart entryStart = parser.Consume();
+ int line = (int)entryStart.Start.Line;
+
+ string input = Unescape(parser.Consume().Value);
+ string expected = Unescape(parser.Consume().Value);
+
+ var xfail = XFail.None;
+ TestMode entryMode = mode;
+ bool skip = false;
+
+ if (parser.Current is MappingStart)
+ {
+ (xfail, entryMode, skip) = ReadTestOptions(parser, mode);
+ }
+
+ parser.Consume();
+
+ if (skip)
+ {
+ continue;
+ }
+
+ foreach ((string query, string? assertMatch) in tables)
+ {
+ // Forward compares translate(input) with expected. An explicit backward testmode
+ // means the entry is already written braille-first, so it is not swapped. The
+ // backward leg of bothDirections is: the expected braille is the input, and the
+ // original text is what back translation should produce.
+ if (entryMode is TestMode.Forward or TestMode.BothDirections)
+ {
+ cases.Add(new BrailleSpecCase(
+ specFile, line, query, assertMatch, displayTable,
+ input, expected, TestDirection.Forward, xfail.HasFlag(XFail.Forward)));
+ }
+
+ if (entryMode == TestMode.Backward)
+ {
+ cases.Add(new BrailleSpecCase(
+ specFile, line, query, assertMatch, displayTable,
+ input, expected, TestDirection.Backward, xfail.HasFlag(XFail.Backward)));
+ }
+ else if (entryMode == TestMode.BothDirections)
+ {
+ cases.Add(new BrailleSpecCase(
+ specFile, line, query, assertMatch, displayTable,
+ expected, input, TestDirection.Backward, xfail.HasFlag(XFail.Backward)));
+ }
+ }
+ }
+
+ parser.Consume();
+ }
+
+ [Flags]
+ private enum XFail
+ {
+ None = 0,
+ Forward = 1,
+ Backward = 2,
+ Both = Forward | Backward,
+ }
+
+ private static (XFail XFail, TestMode Mode, bool Skip) ReadTestOptions(
+ IParser parser, TestMode mode)
+ {
+ parser.Consume();
+
+ var xfail = XFail.None;
+ bool skip = false;
+
+ while (parser.Current is not MappingEnd)
+ {
+ string key = parser.Consume().Value;
+
+ switch (key)
+ {
+ case "xfail":
+ xfail = ReadXFail(parser);
+ break;
+
+ case "testmode":
+ mode = ParseTestMode(parser.Consume().Value);
+ break;
+
+ // Emphasis is applied through typeform, which this prototype does not drive yet.
+ // Skip the value so the rest of the file still parses, and drop the case: silently
+ // running it without the typeform would compare against the wrong expectation.
+ case "typeform":
+ parser.SkipThisAndNestedEvents();
+ skip = true;
+ break;
+
+ default:
+ throw new NotSupportedException($"unsupported test option '{key}'");
+ }
+ }
+
+ parser.Consume();
+
+ return (xfail, mode, skip);
+ }
+
+ ///
+ /// xfail is either a scalar, where only "false" and "off" are falsy
+ /// (tools/lou_checkyaml.c:379-389), or a mapping naming the failing directions.
+ ///
+ private static XFail ReadXFail(IParser parser)
+ {
+ if (parser.Current is Scalar scalar)
+ {
+ parser.MoveNext();
+ return scalar.Value is "false" or "off" ? XFail.None : XFail.Both;
+ }
+
+ parser.Consume();
+
+ var xfail = XFail.None;
+
+ while (parser.Current is not MappingEnd)
+ {
+ string key = parser.Consume().Value;
+ string value = parser.Consume().Value;
+ bool set = value is not ("false" or "off");
+
+ if (set)
+ {
+ xfail |= key switch
+ {
+ "forward" => XFail.Forward,
+ "backward" => XFail.Backward,
+ _ => throw new NotSupportedException($"unsupported xfail direction '{key}'"),
+ };
+ }
+ }
+
+ parser.Consume();
+
+ return xfail;
+ }
+
+ ///
+ /// The specs use single quoted scalars, where YAML performs no escape processing at all, and
+ /// rely on liblouis to interpret the escapes itself. Only the forms the Danish specs actually
+ /// use are handled: \xNNNN and \uNNNN code points, and \\ for a literal backslash.
+ /// Without the backslash case, 'at\\bliver' parses as two backslashes and translates to two
+ /// cells where upstream expects one.
+ ///
+ private static string Unescape(string value)
+ {
+ if (!value.Contains('\\', StringComparison.Ordinal))
+ {
+ return value;
+ }
+
+ var builder = new StringBuilder(value.Length);
+
+ for (int i = 0; i < value.Length; i++)
+ {
+ if (value[i] == '\\' && i + 1 < value.Length)
+ {
+ if (value[i + 1] is 'x' or 'y' or 'u' && i + 5 < value.Length &&
+ ushort.TryParse(
+ value.AsSpan(i + 2, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out ushort code))
+ {
+ builder.Append((char)code);
+ i += 5;
+ continue;
+ }
+
+ if (value[i + 1] is '\\' or '"')
+ {
+ builder.Append(value[i + 1]);
+ i++;
+ continue;
+ }
+ }
+
+ builder.Append(value[i]);
+ }
+
+ return builder.ToString();
+ }
+}
diff --git a/LibLouis.NET.Test/BrailleSpecTests.cs b/LibLouis.NET.Test/BrailleSpecTests.cs
new file mode 100644
index 0000000..3a8dc95
--- /dev/null
+++ b/LibLouis.NET.Test/BrailleSpecTests.cs
@@ -0,0 +1,194 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+using Xunit;
+
+namespace LibLouis.NET.Test;
+
+///
+/// Runs the upstream braille specs for Danish through the managed wrapper.
+///
+///
+/// These are liblouis's own expectations, so they check the wrapper end to end against thousands of
+/// cases nobody here had to invent: not just that a translation succeeds, but that it produces the
+/// characters upstream says it should, in both directions.
+///
+/// The specs live in braille-specs/ and are copied verbatim from
+/// upstream/liblouis-<version>/tests/braille-specs/. Re-copy them when the upstream version is
+/// bumped; the diff is the set of expectations that changed.
+///
+/// One test per spec file rather than per case. Ten thousand xunit cases makes discovery slow and
+/// buries a real regression in an unreadable log; a single failure listing every mismatch is more
+/// use than ten thousand separate red entries.
+///
+public class BrailleSpecTests
+{
+ private static readonly string SpecDirectory =
+ Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "braille-specs");
+
+ // tables/ is the upstream set. Nota's own tables live in nota-tables/ and no longer shadow it,
+ // so the specs can be checked against the tables they were actually written for.
+ private static readonly string TableDirectory =
+ Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables");
+
+ public static TheoryData SpecFiles()
+ {
+ var data = new TheoryData();
+
+ foreach (string path in Directory.EnumerateFiles(SpecDirectory, "*.yaml").OrderBy(f => f, StringComparer.Ordinal))
+ {
+ data.Add(Path.GetFileName(path));
+ }
+
+ return data;
+ }
+
+ [Theory]
+ [MemberData(nameof(SpecFiles))]
+ public void MatchesUpstreamExpectations(string specFile)
+ {
+ IReadOnlyList cases = BrailleSpecReader.Read(Path.Combine(SpecDirectory, specFile));
+
+ IndexUpstreamTables();
+
+ var mismatches = new List();
+ var unexpectedPasses = new List();
+ int checkedCount = 0;
+
+ foreach (BrailleSpecCase testCase in cases)
+ {
+
+ string table = ResolveTable(testCase, TableCache.Value);
+ string? actual = Run(testCase, table);
+ bool matched = actual == testCase.Expected;
+ checkedCount++;
+
+ if (testCase.ExpectedToFail)
+ {
+ // Upstream reports an unexpected pass as a warning rather than an error: the case
+ // is known-broken, and it passing usually means the expectation moved.
+ if (matched)
+ {
+ unexpectedPasses.Add(testCase.ToString());
+ }
+ }
+ else if (!matched)
+ {
+ mismatches.Add($"{testCase}\n actual: {Describe(actual)}");
+ }
+ }
+
+
+ Assert.True(
+ mismatches.Count == 0,
+ $"{specFile}: {mismatches.Count} of {checkedCount} cases did not match upstream " +
+ $"({unexpectedPasses.Count} xfail cases passed unexpectedly).\n " +
+ string.Join("\n ", mismatches.Take(25)) +
+ (mismatches.Count > 25 ? $"\n ... and {mismatches.Count - 25} more" : string.Empty));
+ }
+
+ private static string? Run(BrailleSpecCase testCase, string table)
+ {
+ string[] tables = [ResolveDisplayTable(testCase.DisplayTable), table];
+ int outputLength = Math.Max(testCase.Input.Length, testCase.Expected.Length) * 4;
+
+ try
+ {
+ return testCase.Direction == TestDirection.Forward
+ ? LibLouis.Instance.Translate(tables, testCase.Input, outputLength, null, null, TranslationMode.Regular)
+ : LibLouis.Instance.BackTranslate(tables, testCase.Input, outputLength, null, null, TranslationMode.Regular);
+ }
+ catch (LibLouisException ex)
+ {
+ // A translation that fails outright is a mismatch, not an error: upstream marks some of
+ // these xfail, and letting it throw would stop the whole file at the first one. The
+ // message is carried into the comparison so a failure says why, rather than only that
+ // nothing came back.
+ return $"";
+ }
+ }
+
+ // Every query from every spec is resolved once, up front, before any translation runs.
+ // lou_findTable's return value is freed by the marshaller with the wrong allocator (P/Invoke
+ // audit item 3), so interleaving these calls with translations corrupts the native heap.
+ private static readonly Lazy> TableCache = new(() =>
+ {
+ LibLouis.Instance.IndexTables(
+ Directory.EnumerateFiles(TableDirectory)
+ .Where(f => Path.GetExtension(f) is ".ctb" or ".utb" or ".uti" or ".dis" or ".cti" or ".dic"));
+
+ var resolved = new Dictionary(StringComparer.Ordinal);
+
+ foreach (string query in Directory.EnumerateFiles(SpecDirectory, "*.yaml")
+ .SelectMany(BrailleSpecReader.Read)
+ .Select(c => c.TableQuery)
+ .Distinct(StringComparer.Ordinal))
+ {
+ resolved[query] = LibLouis.Instance.FindTable(query) ?? string.Empty;
+ }
+
+ return resolved;
+ });
+
+ private static void IndexUpstreamTables() => _ = TableCache.Value;
+
+ ///
+ /// Resolving a table query is what lou_findTable does, and the specs assert which file a query
+ /// should select, so this covers table resolution as well as translation.
+ ///
+ private static string ResolveTable(BrailleSpecCase testCase, Dictionary cache)
+ {
+ if (!cache.TryGetValue(testCase.TableQuery, out string? resolved))
+ {
+ resolved = LibLouis.Instance.FindTable(testCase.TableQuery) ?? string.Empty;
+ cache[testCase.TableQuery] = resolved;
+ }
+
+ Assert.False(
+ string.IsNullOrEmpty(resolved),
+ $"No table matched the query '{testCase.TableQuery}' from {testCase.SpecFile}:{testCase.Line}");
+
+ if (testCase.AssertMatch is not null)
+ {
+ Assert.True(
+ string.Equals(Path.GetFileName(resolved), testCase.AssertMatch, StringComparison.Ordinal),
+ $"Query '{testCase.TableQuery}' resolved to {Path.GetFileName(resolved)}, " +
+ $"but {testCase.SpecFile}:{testCase.Line} asserts {testCase.AssertMatch}");
+ }
+
+ return resolved;
+ }
+
+ ///
+ /// A spec's display table is usually a file name, but it can also be an inline table written as
+ /// a YAML block scalar, for instance to include the standard one and then override a character.
+ /// liblouis only takes paths, so the inline form is written out next to the tables, where the
+ /// includes inside it resolve.
+ ///
+ private static string ResolveDisplayTable(string display)
+ {
+ // A file name never contains a newline, so this distinguishes the two forms.
+ if (!display.Contains('\n', StringComparison.Ordinal))
+ {
+ return Path.Combine(TableDirectory, display);
+ }
+
+ string name = $"inline-{Convert.ToHexString(System.Security.Cryptography.MD5.HashData(System.Text.Encoding.UTF8.GetBytes(display)))[..8]}.dis";
+ string path = Path.Combine(TableDirectory, name);
+
+ if (!File.Exists(path))
+ {
+ File.WriteAllText(path, display);
+ }
+
+ return path;
+ }
+
+ private static string Describe(string? value) =>
+ value is null
+ ? ""
+ : string.Concat(value.Select(c => c is >= ' ' and <= '~' ? c.ToString() : $"\\u{(int)c:X4}"));
+}
diff --git a/LibLouis.NET.Test/HyphenateTests.cs b/LibLouis.NET.Test/HyphenateTests.cs
index a9b022e..2da22eb 100644
--- a/LibLouis.NET.Test/HyphenateTests.cs
+++ b/LibLouis.NET.Test/HyphenateTests.cs
@@ -18,7 +18,7 @@ public class HyphenateTests
private static readonly string[] Tables = ["da-dk-braillo.dis", "da-dk-g26.ctb"];
private static string[] TablePaths() =>
- [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables", t))];
+ [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nota-tables", t))];
[Fact]
public void Hyphenate_ReturnsOneHyphenationFlagPerCharacter()
diff --git a/LibLouis.NET.Test/IndexTablesTests.cs b/LibLouis.NET.Test/IndexTablesTests.cs
index 8f0f8fa..7bfac4e 100644
--- a/LibLouis.NET.Test/IndexTablesTests.cs
+++ b/LibLouis.NET.Test/IndexTablesTests.cs
@@ -19,7 +19,7 @@ public class IndexTablesTests
private static readonly string[] Tables = ["da-dk-g26.ctb", "da-dk-g16-markers.ctb"];
private static string[] TablePaths() =>
- [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables", t))];
+ [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nota-tables", t))];
///
/// liblouis logs one "Analyzing table <name>" line per array entry it walks, so the number
diff --git a/LibLouis.NET.Test/InputLengthTests.cs b/LibLouis.NET.Test/InputLengthTests.cs
index 120d509..605a37e 100644
--- a/LibLouis.NET.Test/InputLengthTests.cs
+++ b/LibLouis.NET.Test/InputLengthTests.cs
@@ -29,7 +29,7 @@ public class InputLengthTests
private static readonly string[] Tables = ["da-dk-braillo.dis", "da-dk-g26.ctb"];
private static string[] TablePaths() =>
- [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables", t))];
+ [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nota-tables", t))];
///
/// Translate() only requires outputPosition to hold input.Length entries, so liblouis must
diff --git a/LibLouis.NET.Test/LibLouis.NET.Test.csproj b/LibLouis.NET.Test/LibLouis.NET.Test.csproj
index 7138be2..1e8ca27 100644
--- a/LibLouis.NET.Test/LibLouis.NET.Test.csproj
+++ b/LibLouis.NET.Test/LibLouis.NET.Test.csproj
@@ -17,6 +17,7 @@
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -29,7 +30,40 @@
-
+
+
+ PreserveNewest
+
+
+
+
+ PreserveNewest
+
+
+
+
PreserveNewest
diff --git a/LibLouis.NET.Test/NativeLockTests.cs b/LibLouis.NET.Test/NativeLockTests.cs
index d36966c..48ce8b8 100644
--- a/LibLouis.NET.Test/NativeLockTests.cs
+++ b/LibLouis.NET.Test/NativeLockTests.cs
@@ -27,7 +27,7 @@ public class NativeLockTests
private static readonly string[] Tables = ["da-dk-braillo.dis", "da-dk-g26.ctb"];
private static string[] TablePaths() =>
- [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables", t))];
+ [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nota-tables", t))];
[Fact]
public void VersionIsReported()
diff --git a/LibLouis.NET.Test/NativeMethodsTests.cs b/LibLouis.NET.Test/NativeMethodsTests.cs
index b95fa58..0bb2032 100644
--- a/LibLouis.NET.Test/NativeMethodsTests.cs
+++ b/LibLouis.NET.Test/NativeMethodsTests.cs
@@ -23,7 +23,7 @@ public void SingleMode()
Array.Fill(modes, TypeForm.ForeignLanguage);
string resultString = LibLouis.Instance.Translate(
- tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables", t)),
+ tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nota-tables", t)),
input,
outputLength,
modes,
@@ -48,7 +48,7 @@ public void NestedMode_EmphasisInForeignLanguage()
modes[6] = TypeForm.ForeignLanguage | TypeForm.Emphasis;
string resultString = LibLouis.Instance.Translate(
- tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables", t)),
+ tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nota-tables", t)),
input,
outputLength,
modes,
@@ -89,7 +89,7 @@ public void NestedMode_ForeignLanguageInEmphasis()
Assert.Equal(inputLength, modes.Length);
string resultString = LibLouis.Instance.Translate(
- tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables", t)),
+ tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nota-tables", t)),
input,
outputLength,
modes,
@@ -105,7 +105,7 @@ public void TestPositionResults()
const string input = "Første linje. Anden linje, med kursiveret tekst. Tredje linje.";
const string expected = "@fze linje. @anç linje, m kursi#rò ükz. @tàdje linje.";
- string[] tables = ["tables/da-dk-braillo.dis", "tables/da-dk-g26.ctb"];
+ string[] tables = ["nota-tables/da-dk-braillo.dis", "nota-tables/da-dk-g26.ctb"];
int outputLength = input.Length * 4;
int cursorPosition = 0;
diff --git a/LibLouis.NET.Test/NonBmpTests.cs b/LibLouis.NET.Test/NonBmpTests.cs
index 261417e..18a5999 100644
--- a/LibLouis.NET.Test/NonBmpTests.cs
+++ b/LibLouis.NET.Test/NonBmpTests.cs
@@ -23,7 +23,7 @@ public class NonBmpTests
private static readonly string[] Tables = ["da-dk-braillo.dis", "da-dk-g26.ctb"];
private static string[] TablePaths() =>
- [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables", t))];
+ [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nota-tables", t))];
///
/// How many widechars liblouis sees for : whole characters on a UCS-4
diff --git a/LibLouis.NET.Test/NotaTablesTests.cs b/LibLouis.NET.Test/NotaTablesTests.cs
new file mode 100644
index 0000000..dc9d247
--- /dev/null
+++ b/LibLouis.NET.Test/NotaTablesTests.cs
@@ -0,0 +1,98 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text.RegularExpressions;
+
+using Xunit;
+
+namespace LibLouis.NET.Test;
+
+///
+/// Guards the nota-tables/ directory, which the tests use in place of the upstream set.
+///
+public class NotaTablesTests
+{
+ private static readonly string NotaTableDirectory =
+ Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nota-tables");
+
+ private static readonly string UpstreamTableDirectory =
+ Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables");
+
+ ///
+ /// liblouis resolves an include relative to the directory of the table doing the including, so
+ /// every table nota-tables/ pulls in has to be there too. Most are Nota's own; the handful of
+ /// general upstream tables they need are copied in by an explicit list in the csproj, and an
+ /// explicit list is exactly the kind of thing that goes stale the moment a table gains an
+ /// include.
+ ///
+ [Fact]
+ public void NotaTablesAreSelfContained()
+ {
+ var present = TableFilesIn(NotaTableDirectory).ToHashSet(StringComparer.Ordinal);
+ var missing = new SortedSet(StringComparer.Ordinal);
+
+ foreach (string file in present)
+ {
+ foreach (string included in IncludesOf(Path.Combine(NotaTableDirectory, file)))
+ {
+ if (!present.Contains(included))
+ {
+ missing.Add($"{included} (included by {file})");
+ }
+ }
+ }
+
+ Assert.True(
+ missing.Count == 0,
+ "nota-tables/ is missing tables it includes, so those cannot be compiled from that " +
+ "directory alone. Add them to the upstream copy list in the csproj:\n " +
+ string.Join("\n ", missing));
+ }
+
+ ///
+ /// The separate directory exists so that nothing of Nota's shadows the upstream set. Sharing a
+ /// file name across the two directories is expected and fine - twenty two of Nota's tables are
+ /// forks of an upstream table of the same name. What must never happen is Nota's tables being
+ /// copied into tables/ as well, which is what the old single directory did.
+ ///
+ /// The tables that exist nowhere upstream are the reliable canary: if one of them turns up in
+ /// tables/, the copy is misconfigured, whatever the file names say.
+ ///
+ [Fact]
+ public void NotaTablesDoNotLeakIntoTheUpstreamDirectory()
+ {
+ Assert.True(Directory.Exists(UpstreamTableDirectory), "the upstream tables were not staged");
+
+ string[] notaOnly =
+ [
+ "da-dk-g16-markers.ctb",
+ "da-dk-g16_1993-markers.ctb",
+ "da-dk-braillo.dis",
+ "da-dk-g16-crossword.ctb",
+ "da-dk-g26l.ctb",
+ "da-dk-g26l-lit.ctb",
+ "da-dk-g28l.ctb",
+ "da-dk-g2_1993.dic",
+ ];
+
+ var upstream = TableFilesIn(UpstreamTableDirectory).ToHashSet(StringComparer.Ordinal);
+ var leaked = notaOnly.Where(upstream.Contains).OrderBy(f => f, StringComparer.Ordinal).ToList();
+
+ Assert.True(
+ leaked.Count == 0,
+ "tables/ should hold only the upstream set, but these tables of Nota's are in it, so " +
+ "the two are being copied to the same place again:\n " + string.Join("\n ", leaked));
+ }
+
+ private static IEnumerable TableFilesIn(string directory) =>
+ Directory.EnumerateFiles(directory)
+ .Select(Path.GetFileName)
+ .Where(f => f is not null && !f.EndsWith(".md", StringComparison.OrdinalIgnoreCase))!;
+
+ private static IEnumerable IncludesOf(string path) =>
+ File.ReadLines(path)
+ .Select(line => Regex.Match(line, @"^\s*include\s+(\S+)"))
+ .Where(m => m.Success)
+ .Select(m => m.Groups[1].Value);
+}
diff --git a/LibLouis.NET.Test/OutputDotsTests.cs b/LibLouis.NET.Test/OutputDotsTests.cs
index 290db35..6ce3373 100644
--- a/LibLouis.NET.Test/OutputDotsTests.cs
+++ b/LibLouis.NET.Test/OutputDotsTests.cs
@@ -18,7 +18,7 @@ public class OutputDotsTests
private static readonly string[] Tables = ["da-dk-braillo.dis", "da-dk-g08.ctb"];
private static string[] EightDotTables() =>
- [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables", t))];
+ [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nota-tables", t))];
private static TranslatedString TranslateWithTypeForm(string input)
{
diff --git a/LibLouis.NET.Test/PositionMappingTests.cs b/LibLouis.NET.Test/PositionMappingTests.cs
index aae28b8..9ec1d80 100644
--- a/LibLouis.NET.Test/PositionMappingTests.cs
+++ b/LibLouis.NET.Test/PositionMappingTests.cs
@@ -21,7 +21,7 @@ public class PositionMappingTests
private static readonly string[] Tables = ["da-dk-braillo.dis", "da-dk-g26.ctb"];
private static string[] TablePaths() =>
- [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables", t))];
+ [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nota-tables", t))];
private static TranslatedString Translate(string input)
{
diff --git a/LibLouis.NET.Test/ShutdownTests.cs b/LibLouis.NET.Test/ShutdownTests.cs
index e41c0fc..f7ccec0 100644
--- a/LibLouis.NET.Test/ShutdownTests.cs
+++ b/LibLouis.NET.Test/ShutdownTests.cs
@@ -24,7 +24,7 @@ public class ShutdownTests
private static readonly string[] Tables = ["da-dk-braillo.dis", "da-dk-g26.ctb"];
private static string[] TablePaths() =>
- [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables", t))];
+ [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nota-tables", t))];
private static FieldInfo ShutDownField =>
typeof(LibLouis).GetField("_shutDown", BindingFlags.NonPublic | BindingFlags.Static)
diff --git a/LibLouis.NET.Test/TypeFormBufferTests.cs b/LibLouis.NET.Test/TypeFormBufferTests.cs
index c4fd76d..3d01cf2 100644
--- a/LibLouis.NET.Test/TypeFormBufferTests.cs
+++ b/LibLouis.NET.Test/TypeFormBufferTests.cs
@@ -24,7 +24,7 @@ public class TypeFormBufferTests
private static readonly string[] Tables = ["da-dk-braillo.dis", "da-dk-g16-markers.ctb"];
private static string[] TablePaths() =>
- [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables", t))];
+ [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nota-tables", t))];
///
/// Documents the native contract that makes the overrun possible, independent of the wrapper:
diff --git a/LibLouis.NET.Test/UTF8StringNoFreeMarshallerTests.cs b/LibLouis.NET.Test/UTF8StringNoFreeMarshallerTests.cs
index 0373381..eea4522 100644
--- a/LibLouis.NET.Test/UTF8StringNoFreeMarshallerTests.cs
+++ b/LibLouis.NET.Test/UTF8StringNoFreeMarshallerTests.cs
@@ -16,7 +16,7 @@ public unsafe class UTF8StringNoFreeMarshallerTests
[Theory]
[InlineData("")]
[InlineData("a")]
- [InlineData("tables/da-dk-g26.ctb")]
+ [InlineData("nota-tables/da-dk-g26.ctb")]
[InlineData("Første linje")] // multi-byte UTF-8
[InlineData("\U0001D11E")] // non-BMP, surrogate pair on the managed side
public void ConvertToManaged_ReadsNulTerminatedUtf8(string value)
diff --git a/LibLouis.NET.Test/braille-specs/da-dk-6dot.yaml b/LibLouis.NET.Test/braille-specs/da-dk-6dot.yaml
new file mode 100644
index 0000000..c9a79a3
--- /dev/null
+++ b/LibLouis.NET.Test/braille-specs/da-dk-6dot.yaml
@@ -0,0 +1,1124 @@
+display: unicode-without-blank.dis
+
+# -------------
+# Grade 1 and 2
+# -------------
+
+# Round trip tests
+# Commented tests currently fail backwards but should be fixed.
+
+table: {language: da, grade: 1, dots: 6, version: 2022, __assert-match: da-dk-g16.ctb}
+table: {language: da, grade: 2, dots: 6, version: 2022, __assert-match: da-dk-g26.ctb}
+flags: {testmode: bothDirections}
+tests:
+
+# Characters
+
+ - [" ", " "]
+ - ["\"", "⠶"]
+ - ["\u0023", "⠘⠼"]
+ - ["$", "⠘⠙"]
+ - ["%", "⠚⠴"]
+ - ["'", "⠈"]
+ - ["+", "⠘⠖"]
+ - [",", "⠂"]
+ - ["-", "⠤⠤"]
+ - [".", "⠄"]
+ - ["0", "⠼⠚"]
+ - ["1", "⠼⠁"]
+ - ["2", "⠼⠃"]
+ - ["3", "⠼⠉"]
+ - ["4", "⠼⠙"]
+ - ["5", "⠼⠑"]
+ - ["6", "⠼⠋"]
+ - ["7", "⠼⠛"]
+ - ["8", "⠼⠓"]
+ - ["9", "⠼⠊"]
+ - [":", "⠒"]
+ - [";", "⠆"]
+ - ["<", "⠘⠍"]
+ - ["=", "⠘⠶"]
+ - [">", "⠘⠎"]
+ - ["?", "⠢"]
+ - ["@", "⠘⠁"]
+ - ["[", "⠐⠦"]
+ - ["]", "⠐⠴"]
+ - ["^", "⠘⠬"]
+ - ["_", "⠘⠤"]
+ - ["{", "⠘⠪"]
+ - ["}", "⠘⠕"]
+ - ["~", "⠘⠆"]
+ - ["€", "⠘⠑"]
+ - ["ƒ", "⠘⠋"]
+ - ["‰", "⠚⠴⠴"]
+ - ["Š", "⠠⠐⠎"]
+ - ["Ž", "⠠⠐⠵"]
+ - ["•", "⠘⠄"]
+ - ["™", "⠘⠞"]
+ - ["š", "⠐⠎"]
+ - ["©", "⠘⠉"]
+ - ["®", "⠘⠗"]
+ - ["°", "⠘⠴"]
+ - ["µ", "⠐⠍"]
+ - ["Ä", "⠠⠐⠜"]
+ - ["Ç", "⠠⠐⠉"]
+ - ["Î", "⠠⠐⠊"]
+ - ["Ð", "⠠⠐⠙"]
+ - ["Ñ", "⠠⠐⠝"]
+ - ["Ô", "⠠⠐⠕"]
+ - ["Ö", "⠠⠐⠪"]
+ - ["Û", "⠠⠐⠥"]
+ - ["Ý", "⠠⠐⠽"]
+ - ["Þ", "⠠⠐⠞"]
+ - ["ç", "⠐⠉"]
+ - ["î", "⠐⠊"]
+ - ["ð", "⠐⠙"]
+ - ["ñ", "⠐⠝"]
+ - ["ô", "⠐⠕"]
+ - ["ö", "⠐⠪"]
+ - ["û", "⠐⠥"]
+ - ["ý", "⠐⠽"]
+ - ["þ", "⠐⠞"]
+
+# Misc. Unicode (most cannot be back-translated)
+# Some tests may be repititions of tests above, since
+# some characters can occur both inside and outside the 8 bit range.
+# for accented letters in the range u+0080 - u+00ff: the letters
+# that are thought to occur most frequently in Danish texts are used
+# for back-translation.
+# For all accented letters above u+00ff, the first occurring instance is chosen for back-translation.
+# There are no rules about this in the specs of Danish Braille,
+# So the choice is arbitrary and may change over time.
+
+ - ["\u0134\u0135", "⠠⠐⠚⠐⠚"]
+ - ["\u0138", "⠐⠟"]
+ - ["\u0192", "⠘⠋"]
+
+# Greek letters (with dot 5 as prefix)
+
+ - ["\u0392\u03b2", "⠠⠐⠃⠐⠃"]
+ - ["\u0393\u03b3", "⠠⠐⠛⠐⠛"]
+ - ["\u0397\u03b7", "⠠⠐⠱⠐⠱"]
+ - ["\u0398\u03b8", "⠠⠐⠹⠐⠹"]
+ - ["\u039a\u03ba", "⠠⠐⠅⠐⠅"]
+ - ["\u039b\u03bb", "⠠⠐⠇⠐⠇"]
+ - ["\u039e\u03be", "⠠⠐⠭⠐⠭"]
+ - ["\u03a0\u03c0", "⠠⠐⠏⠐⠏"]
+ - ["\u03a1\u03c1", "⠠⠐⠗⠐⠗"]
+ - ["\u03a6\u03c6", "⠠⠐⠋⠐⠋"]
+ - ["\u03a7\u03c7", "⠠⠐⠓⠐⠓"]
+ - ["\u03a9\u03c9", "⠠⠐⠺⠐⠺"]
+
+# Arrows (only a few in 6 dots)
+
+ - ["\u2190", "⠘⠺"]
+ - ["\u2191", "⠘⠷"]
+ - ["\u2193", "⠘⠟"]
+
+# Section sign
+
+ - ["§ 3", "⠬⠼⠉"]
+ - ["§ 3:", "⠬⠼⠉⠒"]
+ - ["§§ 3-5", "⠬⠬⠼⠉⠤⠼⠑"]
+
+# Caps and mixed case
+
+ - ["Foobar", "⠠⠋⠕⠕⠃⠁⠗"]
+ - ["FOOBAR", "⠸⠋⠕⠕⠃⠁⠗"]
+ - ["FOObar", "⠸⠋⠕⠕⠰⠃⠁⠗"]
+ - ["FOO-barfOObar", "⠸⠋⠕⠕⠤⠃⠁⠗⠋⠸⠕⠕⠰⠃⠁⠗"]
+
+# Times vs. bullit
+
+ - ["\u2022Bullit", "⠘⠄⠠⠃⠥⠇⠇⠊⠞"]
+# - ["2 \u00d7 2 = 4", "⠼⠃ ⠘⠄ ⠼⠃ ⠘⠶ ⠼⠙"]
+
+# Numbers and punctuation
+
+ - ["1,2", "⠼⠁⠂⠃"]
+ - ["123.456", "⠼⠁⠃⠉⠄⠙⠑⠋"]
+ - ["3-4", "⠼⠉⠤⠼⠙"]
+ - ["56-", "⠼⠑⠋⠤"]
+ - ["1/2", "⠼⠁⠌⠃"]
+ - ["12:34", "⠼⠁⠃⠒⠉⠙"]
+ - ["2^10", "⠼⠃⠘⠬⠁⠚"]
+ - ["-dashes-", "⠤⠙⠁⠎⠓⠑⠎⠤"]
+ - ["---", "⠤⠤⠤"]
+ - ["-", "⠤⠤"]
+# - [" -", " ⠤⠤"]
+ - [" - ", " ⠤⠤ "]
+
+# Digits and letters
+
+ - ["1a", "⠼⠁⠰⠁"]
+ - ["1.,-a", "⠼⠁⠄⠂⠤⠰⠁"]
+
+# Characters and constructs which cannot be properly back-translated
+
+flags: {testmode: forward}
+tests:
+
+# Single characters
+
+ - ['\x0009', ' ']
+ - ['\x000a', ' ']
+ - ['\x000b', ' ']
+ - ['\x000c', ' ']
+ - ['\x000d', ' ']
+ - ["`", "⠈"]
+ - ["‚", "⠈"]
+ - ["„", "⠶"]
+ - ["…", "⠄⠄⠄"]
+ - ["‹", "⠈"]
+ - ["‘", "⠈"]
+ - ["’", "⠈"]
+ - ["“", "⠶"]
+ - ["”", "⠶"]
+ - ["Œ", "⠠⠕⠑"]
+ - ["–", "⠤⠤"]
+ - ["—", "⠤⠤"]
+ - ["˜", "⠘⠆"]
+ - ["›", "⠈"]
+ - ["œ", "⠕⠑"]
+ - ["Ÿ", "⠠⠐⠽"]
+ - ['\x00a0', ' ']
+ - ["«", "⠶"]
+ - ["±", "⠘⠖⠤"]
+ - ["´", "⠈"]
+ - ["»", "⠶"]
+ - ["¼", "⠼⠁⠌⠙"]
+ - ["½", "⠼⠁⠌⠃"]
+ - ["¾", "⠼⠉⠌⠙"]
+ - ["Á", "⠠⠐⠁"]
+ - ["Â", "⠠⠐⠁"]
+ - ["Ã", "⠠⠐⠁"]
+ - ["Ë", "⠠⠐⠑"]
+ - ["Ì", "⠠⠐⠊"]
+ - ["Í", "⠠⠐⠊"]
+ - ["Ï", "⠠⠐⠊"]
+ - ["Ò", "⠠⠐⠕"]
+ - ["Ó", "⠠⠐⠕"]
+ - ["Õ", "⠠⠐⠕"]
+ - ["Ù", "⠠⠐⠥"]
+ - ["Ú", "⠠⠐⠥"]
+ - ["ß", "⠎⠎"]
+ - ["á", "⠐⠁"]
+ - ["â", "⠐⠁"]
+ - ["ã", "⠐⠁"]
+ - ["ë", "⠐⠑"]
+ - ["ì", "⠐⠊"]
+ - ["í", "⠐⠊"]
+ - ["ï", "⠐⠊"]
+ - ["ò", "⠐⠕"]
+ - ["ó", "⠐⠕"]
+ - ["õ", "⠐⠕"]
+ - ["ù", "⠐⠥"]
+ - ["ú", "⠐⠥"]
+ - ["ÿ", "⠐⠽"]
+
+# Latin Extended-A
+
+ - ["\u0100\u0101", "⠠⠐⠁⠐⠁"]
+ - ["\u0102\u0103", "⠠⠐⠁⠐⠁"]
+ - ["\u0104\u0105", "⠠⠐⠁⠐⠁"]
+ - ["\u0106\u0107", "⠠⠐⠉⠐⠉"]
+ - ["\u0108\u0109", "⠠⠐⠉⠐⠉"]
+ - ["\u010a\u010b", "⠠⠐⠉⠐⠉"]
+ - ["\u010c\u010d", "⠠⠐⠉⠐⠉"]
+ - ["\u010e\u010f", "⠠⠐⠙⠐⠙"]
+ - ["\u0110\u0111", "⠠⠐⠙⠐⠙"]
+ - ["\u0112\u0113", "⠠⠐⠑⠐⠑"]
+ - ["\u0114\u0115", "⠠⠐⠑⠐⠑"]
+ - ["\u0116\u0117", "⠠⠐⠑⠐⠑"]
+ - ["\u0118\u0119", "⠠⠐⠑⠐⠑"]
+ - ["\u011a\u011b", "⠠⠐⠑⠐⠑"]
+ - ["\u011c\u011d", "⠠⠐⠛⠐⠛"]
+ - ["\u011e\u011f", "⠠⠐⠛⠐⠛"]
+ - ["\u0120\u0121", "⠠⠐⠛⠐⠛"]
+ - ["\u0122\u0123", "⠠⠐⠛⠐⠛"]
+ - ["\u0124\u0125", "⠠⠐⠓⠐⠓"]
+ - ["\u0126\u0127", "⠠⠐⠓⠐⠓"]
+ - ["\u0128\u0129", "⠠⠐⠊⠐⠊"]
+ - ["\u012a\u012b", "⠠⠐⠊⠐⠊"]
+ - ["\u012c\u012d", "⠠⠐⠊⠐⠊"]
+ - ["\u012e\u012f", "⠠⠐⠊⠐⠊"]
+ - ["\u0130\u0131", "⠠⠐⠊⠐⠊"]
+ - ["\u0132\u0133", "⠠⠊⠚⠊⠚"]
+ - ["\u0136\u0137", "⠠⠐⠅⠐⠅"]
+ - ["\u0139\u013a", "⠠⠐⠇⠐⠇"]
+ - ["\u013b\u013c", "⠠⠐⠇⠐⠇"]
+ - ["\u013d\u013e", "⠠⠐⠇⠐⠇"]
+ - ["\u013f\u0140", "⠠⠐⠇⠐⠇"]
+ - ["\u0141\u0142", "⠠⠐⠇⠐⠇"]
+ - ["\u0143\u0144", "⠠⠐⠝⠐⠝"]
+ - ["\u0145\u0146", "⠠⠐⠝⠐⠝"]
+ - ["\u0147\u0148", "⠠⠐⠝⠐⠝"]
+ - ["\u0149", "⠈⠝"]
+ - ["\u014a\u014b", "⠠⠐⠝⠐⠝"]
+ - ["\u014c\u014d", "⠠⠐⠕⠐⠕"]
+ - ["\u014e\u014f", "⠠⠐⠕⠐⠕"]
+ - ["\u0150\u0151", "⠠⠐⠕⠐⠕"]
+ - ["\u0152\u0153", "⠠⠕⠑⠕⠑"]
+ - ["\u0154\u0155", "⠠⠐⠗⠐⠗"]
+ - ["\u0156\u0157", "⠠⠐⠗⠐⠗"]
+ - ["\u0158\u0159", "⠠⠐⠗⠐⠗"]
+ - ["\u015a\u015b", "⠠⠐⠎⠐⠎"]
+ - ["\u015c\u015d", "⠠⠐⠎⠐⠎"]
+ - ["\u015e\u015f", "⠠⠐⠎⠐⠎"]
+ - ["\u0160\u0161", "⠠⠐⠎⠐⠎"]
+ - ["\u0162\u0163", "⠠⠐⠞⠐⠞"]
+ - ["\u0164\u0165", "⠠⠐⠞⠐⠞"]
+ - ["\u0166\u0167", "⠠⠐⠞⠐⠞"]
+ - ["\u0168\u0169", "⠠⠐⠥⠐⠥"]
+ - ["\u016a\u016b", "⠠⠐⠥⠐⠥"]
+ - ["\u016c\u016d", "⠠⠐⠥⠐⠥"]
+ - ["\u016e\u016f", "⠠⠐⠥⠐⠥"]
+ - ["\u0170\u0171", "⠠⠐⠥⠐⠥"]
+ - ["\u0172\u0173", "⠠⠐⠥⠐⠥"]
+ - ["\u0174\u0175", "⠠⠐⠺⠐⠺"]
+ - ["\u0176\u0177", "⠠⠐⠽⠐⠽"]
+ - ["\u0178\u00ff", "⠠⠐⠽⠐⠽"]
+ - ["\u0179\u017a", "⠠⠐⠵⠐⠵"]
+ - ["\u017b\u017c", "⠠⠐⠵⠐⠵"]
+ - ["\u017d\u017e", "⠠⠐⠵⠐⠵"]
+ - ["\u017f", "⠐⠎"]
+
+# Latin Extended-B
+
+ - ["\u02dc", "⠘⠆"]
+
+# Greek letters (with dot 5 as prefix)
+
+ - ["\u0386\u03ac", "⠠⠐⠁⠐⠁"]
+ - ["\u0388\u03ad", "⠠⠐⠑⠐⠑"]
+ - ["\u0389\u03ae", "⠠⠐⠱⠐⠱"]
+ - ["\u038a\u03af", "⠠⠐⠊⠐⠊"]
+ - ["\u038c\u03cc", "⠠⠐⠕⠐⠕"]
+ - ["\u038e\u03cd", "⠠⠐⠥⠐⠥"]
+ - ["\u038f\u03ce", "⠠⠐⠺⠐⠺"]
+ - ["\u0391\u03b1", "⠠⠐⠁⠐⠁"]
+ - ["\u0394\u03b4", "⠠⠐⠙⠐⠙"]
+ - ["\u0395\u03b5", "⠠⠐⠑⠐⠑"]
+ - ["\u0396\u03b6", "⠠⠐⠵⠐⠵"]
+ - ["\u0399\u03b9", "⠠⠐⠊⠐⠊"]
+ - ["\u039c\u03bc", "⠠⠐⠍⠐⠍"]
+ - ["\u039d\u03bd", "⠠⠐⠝⠐⠝"]
+ - ["\u039f\u03bf", "⠠⠐⠕⠐⠕"]
+ - ["\u03a3\u03c3", "⠠⠐⠎⠐⠎"]
+ - ["\u03a4\u03c4", "⠠⠐⠞⠐⠞"]
+ - ["\u03a5\u03c5", "⠠⠐⠥⠐⠥"]
+ - ["\u03a8\u03c8", "⠠⠐⠽⠐⠽"]
+
+# Punctuation and bullits
+
+ - ["\u2000", " "]
+ - ["\u2001", " "]
+ - ["\u2002", " "]
+ - ["\u2003", " "]
+ - ["\u2004", " "]
+ - ["\u2005", " "]
+ - ["\u2006", " "]
+ - ["\u2007", " "]
+ - ["\u2008", " "]
+ - ["\u2009", " "]
+ - ["\u200a", " "]
+ - ["\u2010", "⠤"]
+ - ["\u2011", "⠤"]
+ - ["\u2012", "⠤"]
+ - ["\u2013", "⠤⠤"]
+ - ["\u2014", "⠤⠤"]
+ - ["\u2018", "⠈"]
+ - ["\u2019", "⠈"]
+ - ["\u201a", "⠈"]
+ - ["\u201b", "⠈"]
+ - ["\u201c", "⠶"]
+ - ["\u201d", "⠶"]
+ - ["\u201e", "⠶"]
+ - ["\u201f", "⠶"]
+ - ["\u2023", "⠘⠄"]
+ - ["\u2026", "⠄⠄⠄"]
+ - ["\u202f", " "]
+ - ["\u2030", "⠚⠴⠴"]
+ - ["\u2039", "⠈"]
+ - ["\u203a", "⠈"]
+ - ["\u203c", "⠖⠖"]
+ - ["\u203d", "⠢⠖"]
+ - ["\u2043", "⠘⠄"]
+ - ["\u2047", "⠢⠢"]
+ - ["\u2048", "⠢⠖"]
+ - ["\u2049", "⠖⠢"]
+ - ["\u204c", "⠘⠄"]
+ - ["\u204d", "⠘⠄"]
+ - ["\u20ac", "⠘⠑"]
+ - ["\u2122", "⠘⠞"]
+
+# Arrows (only a few in 6 dots)
+
+ - ["\u2192", "⠘⠗"] # back-translates as "registered".
+
+# Geometrical shapes
+
+ - ["\u25e6", "⠘⠄"]
+
+# Extra digits
+
+ - ["1\u00bc + 1\u00bd = 2\u00be", "⠼⠁⠼⠁⠌⠙ ⠘⠖ ⠼⠁⠼⠁⠌⠃ ⠘⠶ ⠼⠃⠼⠉⠌⠙"]
+
+# Dashes
+
+ - ["\u2014 \u0096 \u0097 \u00ad", "⠤⠤ ⠤⠤ ⠤⠤ ⠤⠤"]
+
+# Quotes
+
+ - ["\u201e \u0084 \u201c \u0093 \u201d \u0094 \u00ab \u00bb", "⠶ ⠶ ⠶ ⠶ ⠶ ⠶ ⠶ ⠶"]
+
+# Apostrophes
+
+ - ["` \u201a \u0082 \u2039 \u008b \u2018 \u0091 \u2019 \u0092 \u203a \u009b \u00b4", "⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈"]
+
+# Characters and constructs which cannot be properly back-translated in grade 2
+
+table: {language: da, grade: 1, dots: 6, version: 2022}
+flags: {testmode: bothDirections}
+tests:
+
+ - ["²", "⠼⠬⠃"]
+ - ["³", "⠼⠬⠉"]
+ - ["¹", "⠼⠬⠁"]
+ - ["Ê", "⠠⠐⠑"]
+ - ["×", "⠘⠔"]
+ - ["ê", "⠐⠑"]
+ - ["÷", "⠘⠲"]
+
+# same tests but forward direction only
+table: {language: da, grade: 2, dots: 6, version: 2022}
+flags: {testmode: forward}
+tests:
+
+ - ["²", "⠼⠬⠃"]
+ - ["³", "⠼⠬⠉"]
+ - ["¹", "⠼⠬⠁"]
+ - ["Ê", "⠠⠐⠑"]
+ - ["×", "⠘⠔"]
+ - ["ê", "⠐⠑"]
+ - ["÷", "⠘⠲"]
+
+# Braille patterns which back-translate to something other than the original
+# Typically, single character representations back-translating to strings with more than one character
+
+table: {language: da, grade: 1, dots: 6, version: 2022}
+table: {language: da, grade: 2, dots: 6, version: 2022}
+flags: {testmode: backward}
+tests:
+
+# Characters
+
+ - ["⠄⠄⠄", "..."]
+ - ["⠠⠕⠑", "Oe"]
+ - ["⠕⠑", "oe"]
+ - ["⠘⠖⠤", "±", {xfail: true}]
+ - ["⠼⠁⠌⠙", "1/4"]
+ - ["⠼⠁⠌⠃", "1/2"]
+ - ["⠼⠉⠌⠙", "3/4"]
+
+# Extra digits
+
+ - ["⠼⠁⠼⠁⠌⠙ ⠘⠖ ⠼⠁⠼⠁⠌⠃ ⠘⠶ ⠼⠃⠼⠉⠌⠙", "1\u00bc + 1\u00bd = 2\u00be", {xfail: true}]
+
+# -------
+# Grade 1
+# -------
+
+# Round trip tests
+# Commented tests currently fail backwards but should be fixed.
+
+table: {language: da, grade: 1, dots: 6, version: 2022}
+flags: {testmode: bothDirections}
+tests:
+
+# Characters
+
+ - ["&", "⠯"]
+ - ["(", "⠦"]
+ - [")", "⠴"]
+ - ["*", "⠔"]
+ - ["/", "⠌"]
+ - ["A", "⠠⠁"]
+ - ["B", "⠠⠃"]
+ - ["C", "⠠⠉"]
+ - ["D", "⠠⠙"]
+ - ["E", "⠠⠑"]
+ - ["F", "⠠⠋"]
+ - ["G", "⠠⠛"]
+ - ["H", "⠠⠓"]
+ - ["I", "⠠⠊"]
+ - ["J", "⠠⠚"]
+ - ["K", "⠠⠅"]
+ - ["L", "⠠⠇"]
+ - ["M", "⠠⠍"]
+ - ["N", "⠠⠝"]
+ - ["O", "⠠⠕"]
+ - ["P", "⠠⠏"]
+ - ["Q", "⠠⠟"]
+ - ["R", "⠠⠗"]
+ - ["S", "⠠⠎"]
+ - ["T", "⠠⠞"]
+ - ["U", "⠠⠥"]
+ - ["V", "⠠⠧"]
+ - ["W", "⠠⠺"]
+ - ["X", "⠠⠭"]
+ - ["Y", "⠠⠽"]
+ - ["Z", "⠠⠵"]
+ - ["\u005c\u005c", "⠘⠌"]
+ - ["a", "⠁"]
+ - ["b", "⠃"]
+ - ["c", "⠉"]
+ - ["d", "⠙"]
+ - ["e", "⠑"]
+ - ["f", "⠋"]
+ - ["g", "⠛"]
+ - ["h", "⠓"]
+ - ["i", "⠊"]
+ - ["j", "⠚"]
+ - ["k", "⠅"]
+ - ["l", "⠇"]
+ - ["m", "⠍"]
+ - ["n", "⠝"]
+ - ["o", "⠕"]
+ - ["p", "⠏"]
+ - ["q", "⠟"]
+ - ["r", "⠗"]
+ - ["s", "⠎"]
+ - ["t", "⠞"]
+ - ["u", "⠥"]
+ - ["v", "⠧"]
+ - ["w", "⠺"]
+ - ["x", "⠭"]
+ - ["y", "⠽"]
+ - ["z", "⠵"]
+ - ["|", "⠘⠧"]
+ - ["ž", "⠐⠵"]
+ - ["¢", "⠘⠒"]
+ - ["£", "⠘⠇"]
+ - ["¥", "⠘⠽"]
+ - ["§", "⠬"]
+ - ["À", "⠠⠷"]
+ - ["Å", "⠠⠡"]
+ - ["Æ", "⠠⠜"]
+ - ["È", "⠠⠮"]
+ - ["É", "⠠⠿"]
+ - ["Ø", "⠠⠪"]
+ - ["Ü", "⠠⠳"]
+ - ["à", "⠷"]
+ - ["å", "⠡"]
+ - ["ä", "⠐⠜"]
+ - ["æ", "⠜"]
+ - ["è", "⠮"]
+ - ["é", "⠿"]
+ - ["ø", "⠪"]
+ - ["ü", "⠳"]
+
+# Pangram
+
+ - - "Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Walther spillede på xylofon."
+ - "⠠⠟⠥⠊⠵⠙⠑⠇⠞⠁⠛⠑⠗⠝⠑ ⠎⠏⠊⠎⠞⠑ ⠚⠕⠗⠙⠃⠜⠗ ⠍⠑⠙ ⠋⠇⠪⠙⠑⠂ ⠍⠑⠝⠎ ⠉⠊⠗⠅⠥⠎⠅⠇⠕⠧⠝⠑⠝ ⠠⠺⠁⠇⠞⠓⠑⠗ ⠎⠏⠊⠇⠇⠑⠙⠑ ⠏⠡ ⠭⠽⠇⠕⠋⠕⠝⠄"
+
+# Numbers and punctuation
+
+ - ["J) j) %) ') \u2030)", "⠠⠚⠰⠴ ⠚⠰⠴ ⠚⠴⠰⠴ ⠈⠴ ⠚⠴⠴⠰⠴"]
+ - ["\"quotes\"", "⠶⠟⠥⠕⠞⠑⠎⠶"]
+ - [":-) :-(", "⠒⠤⠴ ⠒⠤⠦"]
+ - [";-) ;-(", "⠆⠤⠴ ⠆⠤⠦"]
+ - [" a-", " ⠁⠤"]
+ - [" -a-", " ⠤⠁⠤"]
+ - ["(parentheses)", "⠦⠏⠁⠗⠑⠝⠞⠓⠑⠎⠑⠎⠴"]
+
+# Multi-pass tests
+
+# - ["~x |z", "⠘⠰⠭ ⠘⠸⠵"]
+# - ["~X |Z", "⠘⠰⠠⠭ ⠘⠸⠠⠵"]
+ - ["5É", "⠼⠑⠠⠿"]
+
+# Characters and constructs which cannot be properly back-translated
+
+flags: {testmode: forward}
+tests:
+
+# Single characters
+
+ - ["¡", "⠲"]
+ - ["", "⠤⠤"]
+ - ["¯", "⠢"]
+
+# Apostrophes
+
+ - ["\u0089) \u201a) \u0082) \u2039) \u009b) \u2018) \u0091) \u2019) \u0092) \u203a) \u009b)", "⠚⠴⠴⠰⠴ ⠈⠴ ⠈⠴ ⠈⠴ ⠈⠴ ⠈⠴ ⠈⠴ ⠈⠴ ⠈⠴ ⠈⠴ ⠈⠴"]
+
+# Emphasis
+
+ - # Bold line
+ - En linje med fed.
+ - ⠨⠠⠑⠝ ⠇⠊⠝⠚⠑ ⠍⠑⠙ ⠋⠑⠙⠄⠨
+ - typeform:
+ bold: '+++++++++++++++++'
+ - # Bold word
+ - Et ord med fed.
+ - ⠠⠑⠞ ⠨⠕⠗⠙⠨ ⠍⠑⠙ ⠋⠑⠙⠄
+ - typeform:
+ bold: ' +++ '
+ - # Bold letter
+ - Et bogstav med fed.
+ - ⠠⠑⠞ ⠃⠕⠛⠨⠎⠨⠞⠁⠧ ⠍⠑⠙ ⠋⠑⠙⠄
+ - typeform:
+ bold: ' + '
+
+ - # Italic line
+ - En linje med kursiv.
+ - ⠨⠠⠑⠝ ⠇⠊⠝⠚⠑ ⠍⠑⠙ ⠅⠥⠗⠎⠊⠧⠄⠨
+ - typeform:
+ italic: '++++++++++++++++++++'
+ - # Italic word
+ - Et ord med kursiv.
+ - ⠠⠑⠞ ⠨⠕⠗⠙⠨ ⠍⠑⠙ ⠅⠥⠗⠎⠊⠧⠄
+ - typeform:
+ italic: ' +++ '
+ - # Italic letter
+ - Et bogstav med kursiv.
+ - ⠠⠑⠞ ⠃⠕⠛⠨⠎⠨⠞⠁⠧ ⠍⠑⠙ ⠅⠥⠗⠎⠊⠧⠄
+ - typeform:
+ italic: ' + '
+
+ - # Underlined line
+ - En linje med understreget.
+ - ⠨⠠⠑⠝ ⠇⠊⠝⠚⠑ ⠍⠑⠙ ⠥⠝⠙⠑⠗⠎⠞⠗⠑⠛⠑⠞⠄⠨
+ - typeform:
+ underline: '++++++++++++++++++++++++++'
+ - # Underlined word
+ - Et ord med understreget.
+ - ⠠⠑⠞ ⠨⠕⠗⠙⠨ ⠍⠑⠙ ⠥⠝⠙⠑⠗⠎⠞⠗⠑⠛⠑⠞⠄
+ - typeform:
+ underline: ' +++ '
+ - # Underlined letter
+ - Et bogstav med understreget.
+ - ⠠⠑⠞ ⠃⠕⠛⠨⠎⠨⠞⠁⠧ ⠍⠑⠙ ⠥⠝⠙⠑⠗⠎⠞⠗⠑⠛⠑⠞⠄
+ - typeform:
+ underline: ' + '
+
+ - # Bold, italic and underlined line
+ - En linje med alt.
+ - ⠨⠠⠑⠝ ⠇⠊⠝⠚⠑ ⠍⠑⠙ ⠁⠇⠞⠄⠨
+ - typeform:
+ bold: '+++++++++++++++++'
+ italic: '+++++++++++++++++'
+ underline: '+++++++++++++++++'
+ - # Bold, italic and underlined word
+ - Et ord med alt.
+ - ⠠⠑⠞ ⠨⠕⠗⠙⠨ ⠍⠑⠙ ⠁⠇⠞⠄
+ - typeform:
+ bold: ' +++ '
+ italic: ' +++ '
+ underline: ' +++ '
+ - # Bold, italic and underlined letter
+ - Et bogstav med alt.
+ - ⠠⠑⠞ ⠃⠕⠛⠨⠎⠨⠞⠁⠧ ⠍⠑⠙ ⠁⠇⠞⠄
+ - typeform:
+ bold: ' + '
+ italic: ' + '
+ underline: ' + '
+
+# -------
+# Grade 2
+# -------
+
+# Round trip tests
+# Commented tests currently fail backwards but should be fixed.
+
+table: {language: da, grade: 2, dots: 6, version: 2022}
+flags: {testmode: bothDirections}
+tests:
+
+# Characters
+
+ - ["&", "⠰⠯"]
+ - ["(", "⠰⠦"]
+ - [")", "⠰⠴"]
+ - ["*", "⠰⠔"]
+ - ["/", "⠰⠌", {xfail: {forward: true}}]
+ - ["A", "⠰⠠⠁"]
+ - ["B", "⠰⠠⠃"]
+ - ["C", "⠰⠠⠉"]
+ - ["D", "⠰⠠⠙"]
+ - ["E", "⠰⠠⠑"]
+ - ["F", "⠰⠠⠋"]
+ - ["G", "⠰⠠⠛"]
+ - ["H", "⠰⠠⠓"]
+ - ["I", "⠠⠊"]
+ - ["J", "⠰⠠⠚"]
+ - ["K", "⠰⠠⠅"]
+ - ["L", "⠰⠠⠇"]
+ - ["M", "⠰⠠⠍"]
+ - ["N", "⠰⠠⠝"]
+ - ["O", "⠰⠠⠕"]
+ - ["P", "⠰⠠⠏"]
+ - ["Q", "⠰⠠⠟"]
+ - ["R", "⠰⠠⠗"]
+ - ["S", "⠰⠠⠎"]
+ - ["T", "⠰⠠⠞"]
+ - ["U", "⠰⠠⠥"]
+ - ["V", "⠰⠠⠧"]
+ - ["W", "⠰⠠⠺"]
+ - ["X", "⠰⠠⠭"]
+ - ["Y", "⠰⠠⠽"]
+ - ["Z", "⠰⠠⠵"]
+ - ["\u005c\u005c", "⠘⠡"]
+ - ["a", "⠰⠁"]
+ - ["b", "⠰⠃"]
+ - ["c", "⠰⠉"]
+ - ["d", "⠰⠙"]
+ - ["e", "⠰⠑"]
+ - ["f", "⠰⠋"]
+ - ["g", "⠰⠛"]
+ - ["h", "⠰⠓"]
+ - ["i", "⠊"]
+ - ["j", "⠰⠚"]
+ - ["k", "⠰⠅"]
+ - ["l", "⠰⠇"]
+ - ["m", "⠰⠍"]
+ - ["n", "⠰⠝"]
+ - ["o", "⠰⠕"]
+ - ["p", "⠰⠏"]
+ - ["q", "⠰⠟"]
+ - ["r", "⠰⠗"]
+ - ["s", "⠰⠎"]
+ - ["t", "⠰⠞"]
+ - ["u", "⠰⠥"]
+ - ["v", "⠰⠧"]
+ - ["w", "⠰⠺"]
+ - ["x", "⠰⠭"]
+ - ["y", "⠰⠽"]
+ - ["z", "⠰⠵"]
+ - ["|", "⠘⠸"]
+ - ["ž", "⠐⠵"]
+ - ["¡", "⠰⠲"]
+ - ["¢", "⠘⠒"]
+ - ["£", "⠘⠇"]
+ - ["¥", "⠘⠽"]
+ - ["À", "⠰⠠⠷"]
+ - ["Å", "⠰⠠⠡"]
+ - ["Æ", "⠰⠠⠜"]
+ - ["È", "⠰⠠⠮"]
+ - ["É", "⠰⠠⠿"]
+ - ["Ø", "⠰⠠⠪"]
+ - ["Ü", "⠰⠠⠳"]
+ - ["à", "⠰⠷"]
+ - ["ä", "⠐⠜"]
+ - ["å", "⠰⠡"]
+ - ["æ", "⠰⠜"]
+ - ["è", "⠰⠮"]
+ - ["é", "⠰⠿"]
+ - ["ø", "⠰⠪"]
+ - ["ü", "⠰⠳"]
+
+# Pangram
+
+ - - "Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Walther spillede på xylofon."
+ - "⠰⠠⠟⠥⠊⠰⠵⠹⠇⠞⠁⠛⠱⠫ ⠎⠏⠊⠵⠑ ⠚⠭⠙⠃⠜⠗ ⠍ ⠋⠇⠪⠹⠂ ⠍⠣⠎ ⠉⠊⠗⠅⠥⠎⠅⠇⠕⠧⠝⠣ ⠰⠠⠺⠁⠇⠞⠓⠱ ⠎⠏⠊⠇⠇⠑⠹ ⠏ ⠰⠭⠽⠇⠕⠋⠕⠝⠄"
+
+# Percent and permille
+
+ - ["1%", "⠼⠁ ⠚⠴"]
+
+# Numbers and punctuation
+
+# - ["2\u00d72", "⠼⠃⠘⠄⠼⠃"]
+ - ["\"quotes\"", "⠶⠰⠟⠥⠕⠳⠎⠶"]
+ - [":-) :-(", "⠒⠤⠰⠴ ⠒⠤⠰⠦"]
+ - [";-) ;-(", "⠆⠤⠰⠴ ⠆⠤⠰⠦"]
+ - [" a-", " ⠰⠁⠤"]
+ - [" -a-", " ⠤⠰⠁⠤"]
+ - ["(parentheses)", "⠦⠏⠁⠗⠣⠞⠓⠑⠎⠑⠎⠴"]
+
+# Exclamation
+
+ - ["\u00a1Que lastima!", "⠰⠲⠰⠠⠟⠥⠑ ⠇⠁⠵⠊⠍⠁⠖"]
+
+# URLs emails and file names
+
+ - ["$at", "⠘⠙⠁⠞"]
+ - ["\u005c\u005cat\u005c\u005cbliver", "⠘⠡⠁⠞⠘⠡⠃⠇⠊⠧⠑⠗"]
+ - ["at@bliver.og", "⠁⠞⠘⠁⠃⠇⠊⠧⠑⠗⠄⠕⠛"]
+ - ["http://at.bliver.og", "⠓⠞⠞⠏⠒⠌⠌⠁⠞⠄⠃⠇⠊⠧⠑⠗⠄⠕⠛"]
+ - ["www.at.bliver.og", "⠺⠺⠺⠄⠁⠞⠄⠃⠇⠊⠧⠑⠗⠄⠕⠛"]
+ - ["www.at.bliver.com", "⠺⠺⠺⠄⠁⠞⠄⠃⠇⠊⠧⠑⠗⠄⠉⠕⠍"]
+ - ["www.a.b.c", "⠺⠺⠺⠄⠰⠁⠄⠰⠃⠄⠰⠉"]
+
+# Word contractions
+
+ - ["At", "⠠⠁"]
+ - ["at", "⠁"]
+ - ["Aldrig", "⠠⠁⠔"]
+ - ["aldrig", "⠁⠔"]
+ - ["aig", "⠁⠊⠛"]
+ - ["Alle", "⠠⠁⠑"]
+ - ["alle", "⠁⠑"]
+ - ["ae", "⠰⠁⠑"]
+ - ["Allerede", "⠠⠁⠇⠗"]
+ - ["allerede", "⠁⠇⠗"]
+ - ["alr", "⠰⠁⠇⠗"]
+ - ["Alligevel", "⠠⠁⠇⠧"]
+ - ["alligevel", "⠁⠇⠧"]
+ - ["alv", "⠰⠁⠇⠧"]
+ - ["Altid", "⠠⠁⠞⠙"]
+ - ["altid", "⠁⠞⠙"]
+ - ["atd", "⠰⠁⠞⠙"]
+ - ["Altså", "⠠⠁⠡"]
+ - ["altså", "⠁⠡"]
+ - ["aå", "⠰⠁⠡"]
+ - ["Bliver", "⠠⠃"]
+ - ["bliver", "⠃"]
+ - ["Og", "⠠⠉"]
+ - ["og", "⠉"]
+ - ["Deres", "⠠⠲"]
+ - ["deres", "⠲"]
+ - ["Du", "⠠⠙"]
+ - ["du", "⠙"]
+ - ["Eller", "⠠⠑"]
+ - ["eller", "⠑"]
+ - ["For", "⠠⠋"]
+ - ["for", "⠋"]
+ - ["Gør", "⠠⠛"]
+ - ["gør", "⠛"]
+ - ["Har", "⠠⠓"]
+ - ["har", "⠓"]
+ - ["Jeg", "⠠⠚"]
+ - ["jeg", "⠚"]
+ - ["Kan", "⠠⠅"]
+ - ["kan", "⠅"]
+ - ["Lige", "⠠⠇"]
+ - ["lige", "⠇"]
+ - ["Med", "⠠⠍"]
+ - ["med", "⠍"]
+ - ["Når", "⠠⠝"]
+ - ["når", "⠝"]
+ - ["Op", "⠠⠕"]
+ - ["op", "⠕"]
+ - ["På", "⠠⠏"]
+ - ["på", "⠏"]
+ - ["Under", "⠠⠟"]
+ - ["under", "⠟"]
+ - ["Rigtig", "⠠⠗"]
+ - ["rigtig", "⠗"]
+ - ["Som", "⠠⠎"]
+ - ["som", "⠎"]
+ - ["Til", "⠠⠞"]
+ - ["til", "⠞"]
+ - ["Hun", "⠠⠥"]
+ - ["hun", "⠥"]
+ - ["Ved", "⠠⠧"]
+ - ["ved", "⠧"]
+ - ["Hvad", "⠠⠺"]
+ - ["hvad", "⠺"]
+ - ["Over", "⠠⠭"]
+ - ["over", "⠭"]
+ - ["Han", "⠠⠽"]
+ - ["han", "⠽"]
+ - ["Efter", "⠠⠵"]
+ - ["efter", "⠵"]
+ - ["Være", "⠠⠜"]
+ - ["være", "⠜"]
+ - ["Før", "⠠⠪"]
+ - ["før", "⠪"]
+ - ["Så", "⠠⠡"]
+ - ["så", "⠡"]
+ - ["Den", "⠠⠯"]
+ - ["den", "⠯"]
+ - ["Der", "⠠⠾"]
+ - ["der", "⠾"]
+ - ["Det", "⠠⠮"]
+ - ["det", "⠮"]
+ - ["De", "⠠⠹"]
+ - ["de", "⠹"]
+ - ["En", "⠠⠣"]
+ - ["en", "⠣"]
+ - ["Er", "⠠⠱"]
+ - ["er", "⠱"]
+ - ["Et", "⠠⠬"]
+ - ["et", "⠬"]
+ - ["Gennem", "⠠⠻"]
+ - ["gennem", "⠻"]
+ - ["Hvor", "⠠⠌"]
+ - ["hvor", "⠌"]
+ - ["Men", "⠠⠩"]
+ - ["men", "⠩"]
+ - ["Ned", "⠠⠫"]
+ - ["ned", "⠫"]
+ - ["Ret", "⠠⠷"]
+ - ["ret", "⠷"]
+ - ["Skal", "⠠⠿"]
+ - ["skal", "⠿"]
+ - ["Te", "⠠⠳"]
+ - ["te", "⠳"]
+ - ["Var", "⠠⠼"]
+ - ["var", "⠼"]
+ - ["Ve", "⠠⠧⠑"]
+ - ["ve", "⠧⠑"]
+
+# Partword/nocross
+
+ - ["Denne", "⠠⠯⠫"]
+ - ["denne", "⠯⠫"]
+ - ["Mændene", "⠠⠍⠜⠝⠹⠫"]
+ - ["mændene", "⠍⠜⠝⠹⠫"]
+ - ["Derhos", "⠠⠾⠓⠕⠎"]
+ - ["derhos", "⠾⠓⠕⠎"]
+ - ["Hunderace", "⠠⠓⠥⠝⠹⠗⠁⠉⠑"]
+ - ["hunderace", "⠓⠥⠝⠹⠗⠁⠉⠑"]
+ - ["Dette", "⠠⠮⠳"]
+ - ["dette", "⠮⠳"]
+ - ["Detalje", "⠠⠹⠞⠁⠇⠚⠑"]
+ - ["detalje", "⠹⠞⠁⠇⠚⠑"]
+
+# Nocross multiple cells
+
+ - ["Endda", "⠠⠑⠟⠙⠁"]
+ - ["endda", "⠑⠟⠙⠁"]
+ - ["Morgendag", "⠠⠍⠭⠛⠣⠙⠁⠛"]
+ - ["morgendag", "⠍⠭⠛⠣⠙⠁⠛"]
+ - ["Gendanne", "⠠⠛⠣⠙⠁⠝⠫"]
+ - ["gendanne", "⠛⠣⠙⠁⠝⠫"]
+ - ["Generelt", "⠠⠻⠫⠷⠇⠞"]
+ - ["generelt", "⠻⠫⠷⠇⠞"]
+
+ - ["Fra!", "⠠⠋⠗⠁⠖"]
+ - ["fra!", "⠋⠗⠁⠖"]
+ - ["!Fra", "⠰⠖⠠⠖"]
+ - ["!fra", "⠖⠋⠗⠁"]
+ - ["'Af", "⠈⠠⠴"]
+ - ["'af", "⠈⠁⠋"]
+
+# No single cell contractions before or after dashes
+
+ - ["at-bliver", "⠁⠞⠤⠃"]
+ - ["d-d-du", "⠰⠙⠤⠰⠙⠤⠙⠥"]
+
+# Combinations with slashes and other punctuation signs
+
+ - ["at!", "⠁⠖"]
+ - ["bliver!", "⠃⠖"]
+ - ["og!", "⠉⠖"]
+ - ["Han/hun", "⠠⠽⠌⠥"]
+ - ["han/hun", "⠽⠌⠥"]
+ - ["Over/under", "⠠⠭⠌⠟"]
+ - ["over/under", "⠭⠌⠟"]
+ - ["Til/fra", "⠠⠞⠌⠖"]
+ - ["til/fra", "⠞⠌⠖"]
+
+# Combinations which require letsign
+
+ - ["1st", "⠼⠁⠰⠎⠞"]
+ - ["2nd", "⠼⠃⠰⠝⠙"]
+ - ["1A", "⠼⠁⠰⠠⠁"]
+ - ["1a", "⠼⠁⠰⠁"]
+ - ["2B", "⠼⠃⠰⠠⠃"]
+ - ["2b", "⠼⠃⠰⠃"]
+
+# Multi-pass te⠄sts
+
+ - ["~x |z", "⠘⠆⠰⠭ ⠘⠸⠰⠵"]
+ - ["~X |Z", "⠘⠆⠰⠠⠭ ⠘⠸⠰⠠⠵"]
+ - ["5É", "⠼⠑⠰⠠⠿"]
+
+# Examples from "Den danske punktskrift 2021"
+
+# Section 5.3.1 Syllables
+
+ - [Anders, ⠠⠁⠝⠾⠎]
+ - [banegården, ⠃⠁⠫⠛⠡⠗⠯]
+ - [banegårdene, ⠃⠁⠫⠛⠡⠗⠹⠫]
+ - [penge, ⠏⠣⠻]
+ - [ringe, ⠗⠊⠝⠻]
+ - [skriveregel, ⠿⠗⠊⠼⠷⠻⠇]
+ - [Roskilde, ⠠⠗⠕⠿⠊⠇⠹, {xfail: {forward: true}}]
+ - [hviske, ⠺⠊⠿⠑]
+ - [taske, ⠞⠁⠿⠑]
+ - [taste, ⠞⠁⠵⠑]
+ - [vristen, ⠧⠗⠊⠵⠣]
+
+# Section 5.3.3 Use last contraction
+
+ - [bager, ⠃⠁⠛⠱]
+ - [haner, ⠓⠁⠝⠱]
+
+# Section 5.3.4 "St" and "hv"
+
+ - [stedet, ⠵⠑⠮]
+ - [stene, ⠵⠑⠫]
+ - [hvede, ⠺⠑⠹]
+
+# Section 5.3.5 "Ve" as begword
+
+ - [vej, ⠧⠑⠚]
+ - [veje, ⠧⠑⠚⠑]
+ - [vejene, ⠼⠚⠑⠫]
+ - [veg, ⠧⠑⠛]
+ - [veda, ⠧⠑⠙⠁]
+
+# Section 5.3.6 Multiple cell partword
+
+ - [danskvand, ⠙⠿⠧⠁⠟]
+ - [danskhed, ⠙⠿⠓⠑⠙]
+ - [gangbro, ⠛⠛⠃⠗⠕]
+ - [gangbar, ⠛⠛⠃⠁⠗]
+ - [kvindelig, ⠅⠧⠹⠇⠔]
+ - [kvindekamp, ⠅⠧⠹⠅⠁⠍⠏]
+ - [menneskelig, ⠩⠿⠑⠇⠔]
+ - [problemformulering, ⠏⠃⠋⠭⠍⠥⠇⠑⠗⠊⠝⠛]
+ - [virkelighedsflugt, ⠧⠗⠅⠓⠑⠙⠎⠋⠇⠥⠛⠞]
+
+# Section 6.1 Period
+
+ - ["St. St. Blicher", "⠰⠠⠎⠞⠄ ⠰⠠⠎⠞⠄ ⠠⠃⠇⠊⠉⠓⠱"]
+ - ["Skt. Hans", "⠠⠿⠞⠄ ⠠⠽⠎"]
+
+# Section 6.4 Hyphens
+
+ - ["ret- og vrang-strikning", "⠗⠬⠤ ⠉ ⠧⠗⠁⠝⠛⠤⠵⠗⠊⠅⠝⠊⠝⠛"]
+ - [over-komme, ⠕⠧⠱⠤⠅⠕⠍⠩, {xfail: {forward: true}}]
+
+# Section 7.1 Capsletter
+
+ - - Han åbnede døren.
+ - ⠠⠽ ⠡⠃⠫⠹ ⠙⠪⠗⠣⠄
+ - - Jeg hilste på Søren og hans datter Xenia.
+ - ⠠⠚ ⠓⠊⠇⠵⠑ ⠏ ⠠⠎⠪⠗⠣ ⠉ ⠽⠎ ⠙⠁⠞⠞⠱ ⠰⠠⠭⠑⠝⠊⠁⠄
+ - - Jeg læser gerne bøger af H. C. Andersen og St. St. Blicher.
+ - ⠠⠚ ⠇⠜⠎⠱ ⠛⠱⠫ ⠃⠪⠛⠱ ⠴ ⠰⠠⠓⠄ ⠰⠠⠉⠄ ⠠⠁⠝⠾⠎⠣ ⠉ ⠰⠠⠎⠞⠄ ⠰⠠⠎⠞⠄ ⠠⠃⠇⠊⠉⠓⠱⠄
+ - - Læs afsnit A underafsnit a
+ - ⠠⠇⠜⠎ ⠁⠋⠎⠝⠊⠞ ⠰⠠⠁ ⠥⠝⠾⠁⠋⠎⠝⠊⠞ ⠰⠁
+
+# Section 7.2 Capsword
+
+ - [DBS, ⠸⠙⠃⠎]
+ - ["DEN GAMLE MAND OG HAVET", "⠸⠯ ⠸⠛⠁⠍⠇⠑ ⠸⠍⠁⠟ ⠸⠉ ⠸⠓⠁⠧⠬"]
+ - ["Din kode er DSB345Qz", "⠠⠙⠝ ⠅⠕⠹ ⠱ ⠸⠙⠎⠃⠰⠼⠉⠙⠑⠰⠠⠟⠰⠵"]
+ - ["NATOs", "⠸⠝⠁⠞⠕⠰⠎"]
+ - ["DBS's forretningsudvalg.", "⠸⠙⠃⠎⠈⠰⠎ ⠋⠭⠗⠬⠝⠊⠝⠛⠎⠥⠙⠧⠁⠇⠛⠄"]
+ - ["TiBS", "⠠⠞⠊⠸⠃⠎"]
+
+# Section 7.3 Letsign
+
+ - - Skjern Å blev rettet ud.
+ - ⠠⠿⠚⠱⠝ ⠰⠠⠡ ⠃⠧ ⠗⠬⠞⠬ ⠥⠙⠄
+ - [jazz, ⠚⠁⠰⠵⠰⠵]
+ - - han løb fx 2 km.
+ - ⠽ ⠇⠪⠃ ⠋⠰⠭ ⠼⠃ ⠰⠅⠍⠄
+ - - han fik 5 kr. (1%). Sidste år var det mindre (1‰).
+ - ⠽ ⠋⠅ ⠼⠑ ⠅⠗⠄ ⠦⠼⠁ ⠚⠴⠰⠴⠄ ⠠⠎⠵⠑ ⠡⠗ ⠼ ⠮ ⠍⠊⠝⠙⠷ ⠦⠼⠁ ⠚⠴⠴⠰⠴⠄
+
+# Section 7.4 Emphasis
+
+flags: {testmode: forward}
+tests:
+ - - Du spørger, hvad jeg laver. Hvad laver du?
+ - ⠠⠙ ⠎⠏⠪⠗⠛⠱⠂ ⠺ ⠨⠚⠨ ⠇⠁⠧⠱⠄ ⠠⠺ ⠇⠁⠧⠱ ⠨⠙⠨⠢
+ - typeform:
+ italic: " +++ ++ "
+ - - Hvad du gør nu, lige nu i dette øjeblik, får betydning for dig resten af dit liv.
+ - ⠠⠺ ⠙ ⠛ ⠝⠥⠂ ⠨⠇ ⠝⠥ ⠊ ⠮⠳ ⠪⠚⠃⠂⠨ ⠋⠡⠗ ⠃⠑⠞⠽⠙⠝⠊⠝⠛ ⠋ ⠨⠙⠔⠨ ⠷⠵⠣ ⠴ ⠙⠞ ⠇⠊⠧⠄
+ - typeform:
+ italic: " ++++++++++++++++++++++++ +++ "
+ - - Den gamle stavemåde var Revshaleøen.
+ - ⠠⠯ ⠛⠁⠍⠇⠑ ⠵⠁⠼⠍⠡⠹ ⠼ ⠠⠷⠨⠧⠨⠎⠓⠁⠇⠑⠪⠣⠄
+ - typeform:
+ italic: " + "
+
+# Section 7.5.2 Misc letters with accents
+
+flags: {testmode: bothDirections}
+tests:
+ - ["Antonín Dvořák", "⠠⠁⠝⠞⠕⠝⠐⠊⠝ ⠠⠙⠧⠕⠐⠗⠐⠁⠅"]
+ - [Lübeck, ⠠⠇⠰⠳⠃⠑⠉⠅]
+ - [Göteborg, ⠠⠛⠐⠪⠳⠃⠭⠛]
+ - [Malmö, ⠠⠍⠁⠇⠍⠐⠪]
+ - [Gävle, ⠠⠛⠐⠜⠧⠇⠑]
+
+# Characters and constructs which cannot be properly back-translated
+
+flags: {testmode: forward}
+tests:
+
+# Single characters
+
+ - ["§", "⠬"]
+
+# Parentheses and misc
+
+ - ["J) j) %) ') \u2030) \u0089) \u201a) \u0082) \u2039) \u009b) \u2018) \u0091) \u2019) \u0092) \u203a) \u009b)", "⠰⠠⠚⠰⠴ ⠰⠚⠰⠴ ⠚⠴⠰⠴ ⠈⠰⠴ ⠚⠴⠴⠰⠴ ⠚⠴⠴⠰⠴ ⠈⠰⠴ ⠈⠰⠴ ⠈⠰⠴ ⠈⠰⠴ ⠈⠰⠴ ⠈⠰⠴ ⠈⠰⠴ ⠈⠰⠴ ⠈⠰⠴ ⠈⠰⠴"]
+
+# Emphasis
+# Single letter emphasis currently fails due to contraction across emphasis.
+
+ - # Bold line
+ - En linje med fed.
+ - ⠨⠠⠣ ⠇⠊⠝⠚⠑ ⠍ ⠋⠑⠙⠄⠨
+ - typeform:
+ bold: '+++++++++++++++++'
+ - # Bold word
+ - Et ord med fed.
+ - ⠠⠬ ⠨⠭⠙⠨ ⠍ ⠋⠑⠙⠄
+ - typeform:
+ bold: ' +++ '
+ - # Bold letter
+ - Et bogstav med fed.
+ - ⠠⠬ ⠃⠕⠛⠨⠎⠨⠞⠁⠧ ⠍ ⠋⠑⠙⠄
+ - {typeform: {bold: ' + '}, xfail: true}
+
+ - # Italic line
+ - En linje med kursiv.
+ - ⠨⠠⠣ ⠇⠊⠝⠚⠑ ⠍ ⠅⠥⠗⠎⠊⠧⠄⠨
+ - typeform:
+ italic: '++++++++++++++++++++'
+ - # Italic word
+ - Et ord med kursiv.
+ - ⠠⠬ ⠨⠭⠙⠨ ⠍ ⠅⠥⠗⠎⠊⠧⠄
+ - typeform:
+ italic: ' +++ '
+ - # Italic letter
+ - Et bogstav med kursiv.
+ - ⠠⠬ ⠃⠕⠛⠨⠎⠨⠞⠁⠧ ⠍ ⠅⠥⠗⠎⠊⠧⠄
+ - {typeform: {italic: ' + '}, xfail: true}
+
+ - # Underlined line
+ - En linje med understreget.
+ - ⠨⠠⠣ ⠇⠊⠝⠚⠑ ⠍ ⠥⠝⠾⠵⠷⠛⠬⠄⠨
+ - typeform:
+ underline: '++++++++++++++++++++++++++'
+ - # Underlined word
+ - Et ord med understreget.
+ - ⠠⠬ ⠨⠭⠙⠨ ⠍ ⠥⠝⠾⠵⠷⠛⠬⠄
+ - typeform:
+ underline: ' +++ '
+ - # Underlined letter
+ - Et bogstav med understreget.
+ - ⠠⠬ ⠃⠕⠛⠨⠎⠨⠞⠁⠧ ⠍ ⠥⠝⠾⠵⠷⠛⠬⠄
+ - {typeform: {underline: ' + '}, xfail: true}
+
+ - # Bold, italic and underlined line
+ - En linje med alt.
+ - ⠨⠠⠣ ⠇⠊⠝⠚⠑ ⠍ ⠁⠇⠞⠄⠨
+ - typeform:
+ bold: '+++++++++++++++++'
+ italic: '+++++++++++++++++'
+ underline: '+++++++++++++++++'
+ - # Bold, italic and underlined word
+ - Et ord med alt.
+ - ⠠⠬ ⠨⠭⠙⠨ ⠍ ⠁⠇⠞⠄
+ - typeform:
+ bold: ' +++ '
+ italic: ' +++ '
+ underline: ' +++ '
+ - # Bold, italic and underlined letter
+ - Et bogstav med alt.
+ - ⠠⠬ ⠃⠕⠛⠨⠎⠨⠞⠁⠧ ⠍ ⠁⠇⠞⠄
+ - {typeform: {bold: ' + ', italic: ' + ', underline: ' + '}, xfail: true}
+
diff --git a/LibLouis.NET.Test/braille-specs/da-dk-8dot.yaml b/LibLouis.NET.Test/braille-specs/da-dk-8dot.yaml
new file mode 100644
index 0000000..4c0e058
--- /dev/null
+++ b/LibLouis.NET.Test/braille-specs/da-dk-8dot.yaml
@@ -0,0 +1,1003 @@
+display: unicode-without-blank.dis
+
+# ----------------
+# Grade 0, 1 and 2
+# ----------------
+
+table: {language: da, grade: 0, dots: 8, version: 2022, __assert-match: da-dk-g08.ctb}
+table: {language: da, grade: 1, dots: 8, version: 2022, __assert-match: da-dk-g18.ctb}
+table: {language: da, grade: 2, dots: 8, version: 2022, __assert-match: da-dk-g28.ctb}
+flags: {testmode: bothDirections}
+tests:
+
+# Characters from 0x21 to 0xff
+
+ - [' ', ' ']
+ - ['"', '⠶']
+ - ['$', '⣙']
+ - ['%', '⣠']
+ - ['&', '⢯']
+ - ['''', '⠈']
+ - ['(', '⢦']
+ - [')', '⢴']
+ - ['+', '⢖']
+ - [',', '⠂']
+ - ['-', '⠤']
+ - ['.', '⠄']
+ - ['/', '⢌']
+ - ['0', '⢚']
+ - ['1', '⢁']
+ - ['2', '⢃']
+ - ['3', '⢉']
+ - ['4', '⢙']
+ - ['5', '⢑']
+ - ['6', '⢋']
+ - ['7', '⢛']
+ - ['8', '⢓']
+ - ['9', '⢊']
+ - [':', '⠒']
+ - [';', '⠆']
+ - ['<', '⢔']
+ - ['=', '⢶']
+ - ['>', '⡢']
+ - ['?', '⠢']
+ - ['@', '⣁']
+ - ['[', '⣦']
+ - [']', '⣴']
+ - ['^', '⢏']
+ - ['_', '⣤']
+ - ['`', '⠐']
+ - ['{', '⣧']
+ - ['|', '⢸']
+ - ['}', '⣼']
+ - ['~', '⣆']
+ - ['€', '⣑']
+ - ['‚', '⡘']
+ - ['ƒ', '⢐']
+ - ['„', '⡨']
+ - ['†', '⠘']
+ - ['‡', '⠸']
+ - ['ˆ', '⣰']
+ - ['‰', '⣺']
+ - ['‹', '⣖']
+ - ['‘', '⡈']
+ - ['’', '⢈']
+ - ['“', '⡆']
+ - ['”', '⢰']
+ - ['•', '⡄']
+ - ['–', '⢤']
+ - ['—', '⡤']
+ - ['˜', '⣎']
+ - ['™', '⣞']
+ - ['›', '⡸']
+ - ['¢', '⣒']
+ - ['£', '⣇']
+ - ['¥', '⣽']
+ - ['¦', '⣌']
+ - ['§', '⣐']
+ - ['¨', '⠰']
+ - ['©', '⣉']
+ - ['«', '⡐']
+ - ['®', '⣗']
+ - ['¯', '⡶']
+ - ['±', '⣋']
+ - ['²', '⢆']
+ - ['³', '⢒']
+ - ['´', '⢘']
+ - ['¶', '⢿']
+ - ['·', '⢄']
+ - ['¸', '⣨']
+ - ['¹', '⢂']
+ - ['»', '⡰']
+ - ['¼', '⢥']
+ - ['½', '⢨']
+ - ['¾', '⢭']
+ - ['÷', '⢲']
+
+# -------------
+# Grade 0 and 1
+# -------------
+
+table: {language: da, grade: 0, dots: 8, version: 2022}
+table: {language: da, grade: 1, dots: 8, version: 2022}
+flags: {testmode: bothDirections}
+tests:
+
+# Characters from 0x21 to 0xff
+
+ - ['*', '⠔']
+ - ['A', '⡁']
+ - ['B', '⡃']
+ - ['C', '⡉']
+ - ['D', '⡙']
+ - ['E', '⡑']
+ - ['F', '⡋']
+ - ['G', '⡛']
+ - ['H', '⡓']
+ - ['I', '⡊']
+ - ['J', '⡚']
+ - ['K', '⡅']
+ - ['L', '⡇']
+ - ['M', '⡍']
+ - ['N', '⡝']
+ - ['O', '⡕']
+ - ['P', '⡏']
+ - ['Q', '⡟']
+ - ['R', '⡗']
+ - ['S', '⡎']
+ - ['T', '⡞']
+ - ['U', '⡥']
+ - ['V', '⡧']
+ - ['W', '⡺']
+ - ['X', '⡭']
+ - ['Y', '⡽']
+ - ['Z', '⡵']
+ - ['\\', '⡌']
+ - ['a', '⠁']
+ - ['b', '⠃']
+ - ['c', '⠉']
+ - ['d', '⠙']
+ - ['e', '⠑']
+ - ['f', '⠋']
+ - ['g', '⠛']
+ - ['h', '⠓']
+ - ['i', '⠊']
+ - ['j', '⠚']
+ - ['k', '⠅']
+ - ['l', '⠇']
+ - ['m', '⠍']
+ - ['n', '⠝']
+ - ['o', '⠕']
+ - ['p', '⠏']
+ - ['q', '⠟']
+ - ['r', '⠗']
+ - ['s', '⠎']
+ - ['t', '⠞']
+ - ['u', '⠥']
+ - ['v', '⠧']
+ - ['w', '⠺']
+ - ['x', '⠭']
+ - ['y', '⠽']
+ - ['z', '⠵']
+ - ['…', '⠠']
+ - ['Œ', '⣕']
+ - ['Ž', '⡬']
+ - ['œ', '⢕']
+ - ['ž', '⠬']
+ - ['Ÿ', '⣾']
+ - ['¡', '⠲']
+ - ['¤', '⡦']
+ - ['ª', '⣮']
+ - ['°', '⠴']
+ - ['µ', '⠦']
+ - ['º', '⣿']
+ - ['À', '⡷']
+ - ['Á', '⣷']
+ - ['Â', '⣡']
+ - ['Ã', '⣩']
+ - ['Ä', '⣜']
+ - ['Å', '⡡']
+ - ['Æ', '⡜']
+ - ['Ç', '⡯']
+ - ['È', '⡮']
+ - ['É', '⡿']
+ - ['Ê', '⡣']
+ - ['Ë', '⡫']
+ - ['Ì', '⣱']
+ - ['Í', '⣣']
+ - ['Î', '⡩']
+ - ['Ï', '⡻']
+ - ['Ð', '⡠']
+ - ['Ñ', '⣻']
+ - ['Ò', '⣫']
+ - ['Ó', '⣬']
+ - ['Ô', '⡹']
+ - ['Õ', '⣹']
+ - ['Ö', '⣪']
+ - ['×', '⠼']
+ - ['Ø', '⡪']
+ - ['Ù', '⡾']
+ - ['Ú', '⣳']
+ - ['Û', '⡱']
+ - ['Ü', '⡳']
+ - ['Ý', '⣶']
+ - ['Þ', '⣅']
+ - ['ß', '⢮']
+ - ['à', '⠷']
+ - ['á', '⢷']
+ - ['â', '⢡']
+ - ['ã', '⢩']
+ - ['ä', '⢜']
+ - ['å', '⠡']
+ - ['æ', '⠜']
+ - ['ç', '⠯']
+ - ['è', '⠮']
+ - ['é', '⠿']
+ - ['ê', '⠣']
+ - ['ë', '⠫']
+ - ['ì', '⢱']
+ - ['í', '⢣']
+ - ['î', '⠩']
+ - ['ï', '⠻']
+ - ['ð', '⢽']
+ - ['ñ', '⢻']
+ - ['ò', '⢫']
+ - ['ó', '⢬']
+ - ['ô', '⠹']
+ - ['õ', '⢹']
+ - ['ö', '⢪']
+ - ['ø', '⠪']
+ - ['ù', '⠾']
+ - ['ú', '⢳']
+ - ['û', '⠱']
+ - ['ü', '⠳']
+ - ['ý', '⢍']
+ - ['þ', '⢅']
+ - ['ÿ', '⢾']
+
+# Pangram
+
+ - - 'Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Walther spillede på xylofon.'
+ - '⡟⠥⠊⠵⠙⠑⠇⠞⠁⠛⠑⠗⠝⠑ ⠎⠏⠊⠎⠞⠑ ⠚⠕⠗⠙⠃⠜⠗ ⠍⠑⠙ ⠋⠇⠪⠙⠑⠂ ⠍⠑⠝⠎ ⠉⠊⠗⠅⠥⠎⠅⠇⠕⠧⠝⠑⠝ ⡺⠁⠇⠞⠓⠑⠗ ⠎⠏⠊⠇⠇⠑⠙⠑ ⠏⠡ ⠭⠽⠇⠕⠋⠕⠝⠄'
+
+# -------
+# Grade 0
+# -------
+
+table: {language: da, grade: 0, dots: 8, version: 2022}
+flags: {testmode: bothDirections}
+tests:
+
+ - ['\x0009', '⣊']
+ - ['\x000a', '⣚']
+ - ['\x000b', '⢝']
+ - ['\x000c', '⢇']
+ - ['\x000d', '⡒']
+
+# Characters from 0x21 to 0xff
+
+ - ['Š', '⠨']
+ - ['š', '⢎']
+ - [' ', '⢞']
+
+# -------------
+# Grade 1 and 2
+# -------------
+
+table: {language: da, grade: 1, dots: 8, version: 2022}
+table: {language: da, grade: 2, dots: 8, version: 2022}
+flags: {testmode: bothDirections}
+tests:
+
+# Misc Unicode chars
+# For each accented letter, the first occurring instance is chosen for back-translation.
+# There are no rules about this in the specs of Danish Braille,
+# So the choice is arbitrary and may change over time.
+
+ - ['\x0100\x0101', '⠐⡁⠐⠁']
+ - ['\x0106\x0107', '⠐⡉⠐⠉']
+ - ['\x010e\x010f', '⠐⡙⠐⠙']
+ - ['\x0112\x0113', '⠐⡑⠐⠑']
+ - ['\x011c\x011d', '⠐⡛⠐⠛']
+ - ['\x0124\x0125', '⠐⡓⠐⠓']
+ - ['\x0128\x0129', '⠐⡊⠐⠊']
+ - ['\x0134\x0135', '⠐⡚⠐⠚']
+ - ['\x0136\x0137', '⠐⡅⠐⠅']
+ - ['\x0138', '⠐⠟']
+ - ['\x0139\x013a', '⠐⡇⠐⠇']
+ - ['\x0143\x0144', '⠐⡝⠐⠝']
+ - ['\x014c\x014d', '⠐⡕⠐⠕']
+ - ['\x0154\x0155', '⠐⡗⠐⠗']
+ - ['\x0162\x0163', '⠐⡞⠐⠞']
+ - ['\x0168\x0169', '⠐⡥⠐⠥']
+ - ['\x0174\x0175', '⠐⡺⠐⠺']
+ - ['\x0176\x0177', '⠐⡽⠐⠽']
+ - ['\x0179\x017a', '⠐⡵⠐⠵']
+
+# Punctuation and bullits
+
+ - ['\x2016', '⠘⢸']
+ - ['\x2017', '⠘⣤']
+
+# Arrows
+
+ - ['\x2190', '⠘⠳⠪']
+ - ['\x2191', '⠘⠳⠬']
+ - ['\x2192', '⠘⠳⠕']
+ - ['\x2193', '⠘⠳⠩']
+ - ['\x2194', '⠘⠳⠺⠗⠕']
+ - ['\x2196', '⠘⠳⠱']
+ - ['\x2197', '⠘⠳⠎']
+ - ['\x2198', '⠘⠳⠣']
+ - ['\x2199', '⠘⠳⠜']
+ - ['\x21D4', '⠘⠳⠺⠶⠗⠕']
+
+# Math signs (experimental)
+
+ - ['\x2200', '⠘⠁']
+ - ['\x2208', '⠘⠑']
+ - ['\x2213', '⠸⠤']
+ - ['\x221d', '⠸⠐⢶']
+ - ['\x2229', '⠨⠦']
+ - ['\x222a', '⠨⠖']
+ - ['\x2243', '⠸⠔']
+ - ['\x2245', '⠐⠘⠔']
+ - ['\x2248', '⠘⠔']
+ - ['\x224f', '⠘⠐⢶']
+ - ['\x2251', '⠨⠐⢶']
+ - ['\x2260', '⠐⢶⠈⠱']
+ - ['\x2261', '⠸⠿']
+ - ['\x2264', '⠸⢔']
+ - ['\x2265', '⠸⡢']
+ - ['\x226a', '⠨⢔']
+ - ['\x226b', '⠨⡢']
+ - ['\x22c5', '⠐⠲']
+
+# Section sign
+
+ - ["§ 3", "⣐⢉"]
+ - ["§ 3:", "⣐⢉⠒"]
+ - ["§§ 3-5", "⣐⣐⢉⠤⢑"]
+
+# Characters and constructs which cannot be properly back-translated
+
+flags: {testmode: forward}
+tests:
+
+ - ['\x0009', ' ']
+ - ['\x000a', ' ']
+ - ['\x000b', ' ']
+ - ['\x000c', ' ']
+ - ['\x000d', ' ']
+ - ['\x00a0', ' ']
+ - ['\x0102\x0103', '⠐⡁⠐⠁']
+ - ['\x0104\x0105', '⠐⡁⠐⠁']
+ - ['\x0108\x0109', '⠐⡉⠐⠉']
+ - ['\x010a\x010b', '⠐⡉⠐⠉']
+ - ['\x010c\x010d', '⠐⡉⠐⠉']
+ - ['\x0110\x0111', '⠐⡙⠐⠙']
+ - ['\x0114\x0115', '⠐⡑⠐⠑']
+ - ['\x0116\x0117', '⠐⡑⠐⠑']
+ - ['\x0118\x0119', '⠐⡑⠐⠑']
+ - ['\x011a\x011b', '⠐⡑⠐⠑']
+ - ['\x011e\x011f', '⠐⡛⠐⠛']
+ - ['\x0120\x0121', '⠐⡛⠐⠛']
+ - ['\x0122\x0123', '⠐⡛⠐⠛']
+ - ['\x0126\x0127', '⠐⡓⠐⠓']
+ - ['\x012a\x012b', '⠐⡊⠐⠊']
+ - ['\x012c\x012d', '⠐⡊⠐⠊']
+ - ['\x012e\x012f', '⠐⡊⠐⠊']
+ - ['\x0130\x0131', '⠐⡊⠐⠊']
+ - ['\x0132\x0133', '⡊⠚⠊⠚']
+ - ['\x013b\x013c', '⠐⡇⠐⠇']
+ - ['\x013d\x013e', '⠐⡇⠐⠇']
+ - ['\x013f\x0140', '⠐⡇⠐⠇']
+ - ['\x0141\x0142', '⠐⡇⠐⠇']
+ - ['\x0145\x0146', '⠐⡝⠐⠝']
+ - ['\x0147\x0148', '⠐⡝⠐⠝']
+ - ['\x0149', '⠈⠝']
+ - ['\x014a\x014b', '⠐⡝⠐⠝']
+ - ['\x014e\x014f', '⠐⡕⠐⠕']
+ - ['\x0150\x0151', '⠐⡕⠐⠕']
+ - ['\x0156\x0157', '⠐⡗⠐⠗']
+ - ['\x0158\x0159', '⠐⡗⠐⠗']
+ - ['\x015a\x015b', '⠐⡎⠐⠎']
+ - ['\x015c\x015d', '⠐⡎⠐⠎']
+ - ['\x015e\x015f', '⠐⡎⠐⠎']
+ - ['\x0164\x0165', '⠐⡞⠐⠞']
+ - ['\x0166\x0167', '⠐⡞⠐⠞']
+ - ['\x016a\x016b', '⠐⡥⠐⠥']
+ - ['\x016c\x016d', '⠐⡥⠐⠥']
+ - ['\x016e\x016f', '⠐⡥⠐⠥']
+ - ['\x0170\x0171', '⠐⡥⠐⠥']
+ - ['\x0172\x0173', '⠐⡥⠐⠥']
+ - ['\x017b\x017c', '⠐⡵⠐⠵']
+ - ['\x017f', '⠐⠎']
+
+# Punctuation and bullits
+
+ - ['\x2000', ' ']
+ - ['\x2001', ' ']
+ - ['\x2002', ' ']
+ - ['\x2003', ' ']
+ - ['\x2004', ' ']
+ - ['\x2005', ' ']
+ - ['\x2006', ' ']
+ - ['\x2007', ' ']
+ - ['\x2008', ' ']
+ - ['\x2009', ' ']
+ - ['\x200a', ' ']
+ - ['\x2010', '⠤']
+ - ['\x2011', '⠤']
+ - ['\x2012', '⠤']
+ - ['\x201b', '⠈']
+ - ['\x201f', '⠶']
+ - ['\x2023', '⡄']
+ - ['\x202f', ' ']
+ - ['\x203c', '⠖⠖']
+ - ['\x203d', '⠢⠖']
+ - ['\x2043', '⡄']
+ - ['\x2047', '⠢⠢']
+ - ['\x2048', '⠢⠖']
+ - ['\x2049', '⠖⠢']
+ - ['\x204c', '⡄']
+ - ['\x204d', '⡄']
+
+# Geometrical shapes
+
+ - ['\x25e6', '⡄']
+
+# Tests that apply for grade 1 and 2 but currently fail for grade 2
+
+table: {language: da, grade: 1, dots: 8, version: 2022}
+flags: {testmode: bothDirections}
+tests:
+
+# Greek letters (with dots 458 as prefix)
+
+ - ['\x0386\x03ac', '⢘⠐⡁⢘⠐⠁']
+ - ['\x0388\x03ad', '⢘⠐⡑⢘⠐⠑']
+ - ['\x0389\x03ae', '⢘⠐⡱⢘⠐⠱']
+ - ['\x038a\x03af', '⢘⠐⡊⢘⠐⠊']
+ - ['\x038c\x03cc', '⢘⠐⡕⢘⠐⠕']
+ - ['\x038e\x03cd', '⢘⠐⡥⢘⠐⠥']
+ - ['\x038f\x03ce', '⢘⠐⡺⢘⠐⠺']
+ - ['\x0391\x03b1', '⢘⡁⢘⠁']
+ - ['\x0392\x03b2', '⢘⡃⢘⠃']
+ - ['\x0393\x03b3', '⢘⡛⢘⠛']
+ - ['\x0394\x03b4', '⢘⡙⢘⠙']
+ - ['\x0395\x03b5', '⢘⡑⢘⠑']
+ - ['\x0396\x03b6', '⢘⡵⢘⠵']
+ - ['\x0397\x03b7', '⢘⡱⢘⠱']
+ - ['\x0398\x03b8', '⢘⡹⢘⠹']
+ - ['\x0399\x03b9', '⢘⡊⢘⠊']
+ - ['\x039a\x03ba', '⢘⡅⢘⠅']
+ - ['\x039b\x03bb', '⢘⡇⢘⠇']
+ - ['\x039c\x03bc', '⢘⡍⢘⠍']
+ - ['\x039d\x03bd', '⢘⡝⢘⠝']
+ - ['\x039e\x03be', '⢘⡭⢘⠭']
+ - ['\x039f\x03bf', '⢘⡕⢘⠕']
+ - ['\x03a0\x03c0', '⢘⡏⢘⠏']
+ - ['\x03a1\x03c1', '⢘⡗⢘⠗']
+ - ['\x03a3\x03c3', '⢘⡎⢘⠎']
+ - ['\x03a4\x03c4', '⢘⡞⢘⠞']
+ - ['\x03a5\x03c5', '⢘⡥⢘⠥']
+ - ['\x03a6\x03c6', '⢘⡋⢘⠋']
+ - ['\x03a7\x03c7', '⢘⡯⢘⠯']
+ - ['\x03a8\x03c8', '⢘⡽⢘⠽']
+ - ['\x03a9\x03c9', '⢘⡺⢘⠺']
+
+# same tests but with xfail
+table: {language: da, grade: 2, dots: 8, version: 2022}
+flags: {testmode: bothDirections}
+tests:
+ - ['\x0386\x03ac', '⢘⠐⡁⢘⠐⠁', {xfail: {forward: true}}]
+ - ['\x0388\x03ad', '⢘⠐⡑⢘⠐⠑', {xfail: {forward: true}}]
+ - ['\x0389\x03ae', '⢘⠐⡱⢘⠐⠱', {xfail: {forward: true}}]
+ - ['\x038a\x03af', '⢘⠐⡊⢘⠐⠊', {xfail: {forward: true}}]
+ - ['\x038c\x03cc', '⢘⠐⡕⢘⠐⠕', {xfail: {forward: true}}]
+ - ['\x038e\x03cd', '⢘⠐⡥⢘⠐⠥', {xfail: {forward: true}}]
+ - ['\x038f\x03ce', '⢘⠐⡺⢘⠐⠺', {xfail: {forward: true}}]
+ - ['\x0391\x03b1', '⢘⡁⢘⠁', {xfail: {forward: true}}]
+ - ['\x0392\x03b2', '⢘⡃⢘⠃', {xfail: {forward: true}}]
+ - ['\x0393\x03b3', '⢘⡛⢘⠛', {xfail: {forward: true}}]
+ - ['\x0394\x03b4', '⢘⡙⢘⠙', {xfail: {forward: true}}]
+ - ['\x0395\x03b5', '⢘⡑⢘⠑', {xfail: {forward: true}}]
+ - ['\x0396\x03b6', '⢘⡵⢘⠵', {xfail: {forward: true}}]
+ - ['\x0397\x03b7', '⢘⡱⢘⠱', {xfail: {forward: true}}]
+ - ['\x0398\x03b8', '⢘⡹⢘⠹', {xfail: {forward: true}}]
+ - ['\x0399\x03b9', '⢘⡊⢘⠊', {xfail: {forward: true}}]
+ - ['\x039a\x03ba', '⢘⡅⢘⠅', {xfail: {forward: true}}]
+ - ['\x039b\x03bb', '⢘⡇⢘⠇', {xfail: {forward: true}}]
+ - ['\x039c\x03bc', '⢘⡍⢘⠍', {xfail: {forward: true}}]
+ - ['\x039d\x03bd', '⢘⡝⢘⠝', {xfail: {forward: true}}]
+ - ['\x039e\x03be', '⢘⡭⢘⠭', {xfail: {forward: true}}]
+ - ['\x039f\x03bf', '⢘⡕⢘⠕', {xfail: {forward: true}}]
+ - ['\x03a0\x03c0', '⢘⡏⢘⠏', {xfail: {forward: true}}]
+ - ['\x03a1\x03c1', '⢘⡗⢘⠗', {xfail: {forward: true}}]
+ - ['\x03a3\x03c3', '⢘⡎⢘⠎', {xfail: {forward: true}}]
+ - ['\x03a4\x03c4', '⢘⡞⢘⠞', {xfail: {forward: true}}]
+ - ['\x03a5\x03c5', '⢘⡥⢘⠥', {xfail: {forward: true}}]
+ - ['\x03a6\x03c6', '⢘⡋⢘⠋', {xfail: {forward: true}}]
+ - ['\x03a7\x03c7', '⢘⡯⢘⠯', {xfail: {forward: true}}]
+ - ['\x03a8\x03c8', '⢘⡽⢘⠽', {xfail: {forward: true}}]
+ - ['\x03a9\x03c9', '⢘⡺⢘⠺', {xfail: {forward: true}}]
+
+# -------
+# Grade 1
+# -------
+
+table: {language: da, grade: 1, dots: 8, version: 2022}
+flags: {testmode: bothDirections}
+tests:
+
+# Characters from 0x21 to 0xff
+
+ - ['Š', '⠐⡎']
+ - ['š', '⠐⠎']
+
+# Emphasis (cannot be back-translated)
+
+flags: {testmode: forward}
+tests:
+
+ - # Bold line
+ - En linje med fed.
+ - ⠨⡑⠝ ⠇⠊⠝⠚⠑ ⠍⠑⠙ ⠋⠑⠙⠄⠨
+ - typeform:
+ bold: '+++++++++++++++++'
+ - # Bold word
+ - Et ord med fed.
+ - ⡑⠞ ⠨⠕⠗⠙⠨ ⠍⠑⠙ ⠋⠑⠙⠄
+ - typeform:
+ bold: ' +++ '
+ - # Bold letter
+ - Et bogstav med fed.
+ - ⡑⠞ ⠃⠕⠛⠨⠎⠨⠞⠁⠧ ⠍⠑⠙ ⠋⠑⠙⠄
+ - typeform:
+ bold: ' + '
+
+ - # Italic line
+ - En linje med kursiv.
+ - ⠨⡑⠝ ⠇⠊⠝⠚⠑ ⠍⠑⠙ ⠅⠥⠗⠎⠊⠧⠄⠨
+ - typeform:
+ italic: '++++++++++++++++++++'
+ - # Italic word
+ - Et ord med kursiv.
+ - ⡑⠞ ⠨⠕⠗⠙⠨ ⠍⠑⠙ ⠅⠥⠗⠎⠊⠧⠄
+ - typeform:
+ italic: ' +++ '
+ - # Italic letter
+ - Et bogstav med kursiv.
+ - ⡑⠞ ⠃⠕⠛⠨⠎⠨⠞⠁⠧ ⠍⠑⠙ ⠅⠥⠗⠎⠊⠧⠄
+ - typeform:
+ italic: ' + '
+
+ - # Underlined line
+ - En linje med understreget.
+ - ⠨⡑⠝ ⠇⠊⠝⠚⠑ ⠍⠑⠙ ⠥⠝⠙⠑⠗⠎⠞⠗⠑⠛⠑⠞⠄⠨
+ - typeform:
+ underline: '++++++++++++++++++++++++++'
+ - # Underlined word
+ - Et ord med understreget.
+ - ⡑⠞ ⠨⠕⠗⠙⠨ ⠍⠑⠙ ⠥⠝⠙⠑⠗⠎⠞⠗⠑⠛⠑⠞⠄
+ - typeform:
+ underline: ' +++ '
+ - # Underlined letter
+ - Et bogstav med understreget.
+ - ⡑⠞ ⠃⠕⠛⠨⠎⠨⠞⠁⠧ ⠍⠑⠙ ⠥⠝⠙⠑⠗⠎⠞⠗⠑⠛⠑⠞⠄
+ - typeform:
+ underline: ' + '
+
+ - # Bold, italic and underlined line
+ - En linje med alt.
+ - ⠨⡑⠝ ⠇⠊⠝⠚⠑ ⠍⠑⠙ ⠁⠇⠞⠄⠨
+ - typeform:
+ bold: '+++++++++++++++++'
+ italic: '+++++++++++++++++'
+ underline: '+++++++++++++++++'
+ - # Bold, italic and underlined word
+ - Et ord med alt.
+ - ⡑⠞ ⠨⠕⠗⠙⠨ ⠍⠑⠙ ⠁⠇⠞⠄
+ - typeform:
+ bold: ' +++ '
+ italic: ' +++ '
+ underline: ' +++ '
+ - # Bold, italic and underlined letter
+ - Et bogstav med alt.
+ - ⡑⠞ ⠃⠕⠛⠨⠎⠨⠞⠁⠧ ⠍⠑⠙ ⠁⠇⠞⠄
+ - typeform:
+ bold: ' + '
+ italic: ' + '
+ underline: ' + '
+
+# -------
+# Grade 2
+# -------
+
+table: {language: da, grade: 2, dots: 8, version: 2022}
+flags: {testmode: bothDirections}
+tests:
+
+# Characters from 0x21 to 0xff
+
+ - ['*', '⠰⠔']
+ - ['A', '⠰⡁']
+ - ['B', '⠰⡃']
+ - ['C', '⠰⡉']
+ - ['D', '⠰⡙']
+ - ['E', '⠰⡑']
+ - ['F', '⠰⡋']
+ - ['G', '⠰⡛']
+ - ['H', '⠰⡓']
+ - ['I', '⡊']
+ - ['J', '⠰⡚']
+ - ['K', '⠰⡅']
+ - ['L', '⠰⡇']
+ - ['M', '⠰⡍']
+ - ['N', '⠰⡝']
+ - ['O', '⠰⡕']
+ - ['P', '⠰⡏']
+ - ['Q', '⠰⡟']
+ - ['R', '⠰⡗']
+ - ['S', '⠰⡎']
+ - ['T', '⠰⡞']
+ - ['U', '⠰⡥']
+ - ['V', '⠰⡧']
+ - ['W', '⠰⡺']
+ - ['X', '⠰⡭']
+ - ['Y', '⠰⡽']
+ - ['Z', '⠰⡵']
+ - ['\\', '⠰⡌']
+ - ['a', '⠰⠁']
+ - ['b', '⠰⠃']
+ - ['c', '⠰⠉']
+ - ['d', '⠰⠙']
+ - ['e', '⠰⠑']
+ - ['f', '⠰⠋']
+ - ['g', '⠰⠛']
+ - ['h', '⠰⠓']
+ - ['i', '⠊']
+ - ['j', '⠰⠚']
+ - ['k', '⠰⠅']
+ - ['l', '⠰⠇']
+ - ['m', '⠰⠍']
+ - ['n', '⠰⠝']
+ - ['o', '⠰⠕']
+ - ['p', '⠰⠏']
+ - ['q', '⠰⠟']
+ - ['r', '⠰⠗']
+ - ['s', '⠰⠎']
+ - ['t', '⠰⠞']
+ - ['u', '⠰⠥']
+ - ['v', '⠰⠧']
+ - ['w', '⠰⠺']
+ - ['x', '⠰⠭']
+ - ['y', '⠰⠽']
+ - ['z', '⠰⠵']
+ - ['…', '⠰⠄⠄⠄']
+ - ['Š', '⠐⡎']
+ - ['Œ', '⠰⣕']
+ - ['Ž', '⠰⡬']
+ - ['š', '⠐⠎']
+ - ['œ', '⠰⢕']
+ - ['ž', '⠰⠬']
+ - ['Ÿ', '⠰⣾']
+ - ['¡', '⠰⠲']
+ - ['¤', '⠰⡦']
+ - ['ª', '⠰⣮']
+ - ['¬', '⠰⡼']
+ - ['', '⠰⣄']
+ - ['°', '⠰⠴']
+ - ['µ', '⠰⠦']
+ - ['º', '⠰⣿']
+ - ['À', '⠰⡷']
+ - ['Á', '⠰⣷']
+ - ['Â', '⠰⣡']
+ - ['Ã', '⠰⣩']
+ - ['Ä', '⠰⣜']
+ - ['Å', '⠰⡡']
+ - ['Æ', '⠰⡜']
+ - ['Ç', '⠰⡯']
+ - ['È', '⠰⡮']
+ - ['É', '⠰⡿']
+ - ['Ê', '⠰⡣']
+ - ['Ë', '⠰⡫']
+ - ['Ì', '⠰⣱']
+ - ['Í', '⠰⣣']
+ - ['Î', '⠰⡩']
+ - ['Ï', '⠰⡻']
+ - ['Ð', '⠰⡠']
+ - ['Ñ', '⠰⣻']
+ - ['Ò', '⠰⣫']
+ - ['Ó', '⠰⣬']
+ - ['Ô', '⠰⡹']
+ - ['Õ', '⠰⣹']
+ - ['Ö', '⠰⣪']
+ - ['×', '⠰⠼']
+ - ['Ø', '⠰⡪']
+ - ['Ù', '⠰⡾']
+ - ['Ú', '⠰⣳']
+ - ['Û', '⠰⡱']
+ - ['Ü', '⠰⡳']
+ - ['Ý', '⠰⣍']
+ - ['Þ', '⠰⣅']
+ - ['ß', '⠰⢮']
+ - ['à', '⠰⠷']
+ - ['á', '⠰⢷']
+ - ['â', '⠰⢡']
+ - ['ã', '⠰⢩']
+ - ['ä', '⠰⢜']
+ - ['å', '⠰⠡']
+ - ['æ', '⠰⠜']
+ - ['ç', '⠰⠯']
+ - ['è', '⠰⠮']
+ - ['é', '⠰⠿']
+ - ['ê', '⠰⠣']
+ - ['ë', '⠰⠫']
+ - ['ì', '⠰⢱']
+ - ['í', '⠰⢣']
+ - ['î', '⠰⠩']
+ - ['ï', '⠰⠻']
+ - ['ð', '⠰⢽']
+ - ['ñ', '⠰⢻']
+ - ['ò', '⠰⢫']
+ - ['ó', '⠰⢬']
+ - ['ô', '⠰⠹']
+ - ['õ', '⠰⢹']
+ - ['ö', '⠰⢪']
+ - ['ø', '⠰⠪']
+ - ['ù', '⠰⠾']
+ - ['ú', '⠰⢳']
+ - ['û', '⠰⠱']
+ - ['ü', '⠰⠳']
+ - ['ý', '⠰⢍']
+ - ['þ', '⠰⢅']
+ - ['ÿ', '⠰⢾']
+
+# Pangram
+
+ - - 'Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Walther spillede på xylofon.'
+ - '⠰⡟⠥⠊⠰⠵⠹⠇⠞⠁⠛⠱⠫ ⠎⠏⠊⠵⠑ ⠚⠭⠙⠃⠜⠗ ⠍ ⠋⠇⠪⠹⠂ ⠍⠣⠎ ⠉⠊⠗⠅⠥⠎⠅⠇⠕⠧⠝⠣ ⠰⡺⠁⠇⠞⠓⠱ ⠎⠏⠊⠇⠇⠑⠹ ⠏ ⠰⠭⠽⠇⠕⠋⠕⠝⠄'
+
+# Inverted exclamation
+
+ - ['¡Que lastima!', '⠰⠲⠰⡟⠥⠑ ⠇⠁⠵⠊⠍⠁⠖']
+
+# No letsign before numbers
+
+ - ['v8', '⠰⠧⢓']
+ - ['A4', '⠰⡁⢙']
+ - ['Eleva2ren', '⡑⠇⠑⠧⠁⢃⠗⠣']
+
+# URLs emails and file names
+
+ - ['$at', '⣙⠁⠞']
+ - ['\\at\\bliver', '⠰⡌⠁⠞⠰⡌⠃⠇⠊⠧⠑⠗']
+ - ['at@bliver.og', '⠁⠞⣁⠃⠇⠊⠧⠑⠗⠄⠕⠛']
+ - ['http://at.bliver.og', '⠓⠞⠞⠏⠒⢌⢌⠁⠞⠄⠃⠇⠊⠧⠑⠗⠄⠕⠛']
+ - ['www.at.bliver.og', '⠺⠺⠺⠄⠁⠞⠄⠃⠇⠊⠧⠑⠗⠄⠕⠛']
+ - ['www.at.bliver.com', '⠺⠺⠺⠄⠁⠞⠄⠃⠇⠊⠧⠑⠗⠄⠉⠕⠍']
+ - ['www.a.b.c', '⠺⠺⠺⠄⠰⠁⠄⠰⠃⠄⠰⠉']
+
+# Word contractions
+
+ - ['At', '⡁']
+ - ['at', '⠁']
+ - ['Aldrig', '⡁⠔']
+ - ['aldrig', '⠁⠔']
+ - ['aig', '⠁⠊⠛']
+ - ['Alle', '⡁⠑']
+ - ['alle', '⠁⠑']
+ - ['ae', '⠰⠁⠑']
+ - ['Allerede', '⡁⠇⠗']
+ - ['allerede', '⠁⠇⠗']
+ - ['alr', '⠰⠁⠇⠗']
+ - ['Alligevel', '⡁⠇⠧']
+ - ['alligevel', '⠁⠇⠧']
+ - ['alv', '⠰⠁⠇⠧']
+ - ['Altid', '⡁⠞⠙']
+ - ['altid', '⠁⠞⠙']
+ - ['atd', '⠰⠁⠞⠙']
+ - ['Altså', '⡁⠡']
+ - ['altså', '⠁⠡']
+ - ['aå', '⠰⠁⠡']
+ - ['Bliver', '⡃']
+ - ['bliver', '⠃']
+ - ['Og', '⡉']
+ - ['og', '⠉']
+ - ['Deres', '⡲']
+ - ['deres', '⠲']
+ - ['Du', '⡙']
+ - ['du', '⠙']
+ - ['Eller', '⡑']
+ - ['eller', '⠑']
+ - ['For', '⡋']
+ - ['for', '⠋']
+ - ['Gør', '⡛']
+ - ['gør', '⠛']
+ - ['Har', '⡓']
+ - ['har', '⠓']
+ - ['Jeg', '⡚']
+ - ['jeg', '⠚']
+ - ['Kan', '⡅']
+ - ['kan', '⠅']
+ - ['Lige', '⡇']
+ - ['lige', '⠇']
+ - ['Med', '⡍']
+ - ['med', '⠍']
+ - ['Når', '⡝']
+ - ['når', '⠝']
+ - ['Op', '⡕']
+ - ['op', '⠕']
+ - ['På', '⡏']
+ - ['på', '⠏']
+ - ['Under', '⡟']
+ - ['under', '⠟']
+ - ['Rigtig', '⡗']
+ - ['rigtig', '⠗']
+ - ['Som', '⡎']
+ - ['som', '⠎']
+ - ['Til', '⡞']
+ - ['til', '⠞']
+ - ['Hun', '⡥']
+ - ['hun', '⠥']
+ - ['Ved', '⡧']
+ - ['ved', '⠧']
+ - ['Hvad', '⡺']
+ - ['hvad', '⠺']
+ - ['Over', '⡭']
+ - ['over', '⠭']
+ - ['Han', '⡽']
+ - ['han', '⠽']
+ - ['Efter', '⡵']
+ - ['efter', '⠵']
+ - ['Være', '⡜']
+ - ['være', '⠜']
+ - ['Før', '⡪']
+ - ['før', '⠪']
+ - ['Så', '⡡']
+ - ['så', '⠡']
+ - ['Den', '⡯']
+ - ['den', '⠯']
+ - ['Der', '⡾']
+ - ['der', '⠾']
+ - ['Det', '⡮']
+ - ['det', '⠮']
+ - ['De', '⡹']
+ - ['de', '⠹']
+ - ['En', '⡣']
+ - ['en', '⠣']
+ - ['Er', '⡱']
+ - ['er', '⠱']
+ - ['Et', '⡬']
+ - ['et', '⠬']
+ - ['Gennem', '⡻']
+ - ['gennem', '⠻']
+ - ['Hvor', '⡌']
+ - ['hvor', '⠌']
+ - ['Men', '⡩']
+ - ['men', '⠩']
+ - ['Ned', '⡫']
+ - ['ned', '⠫']
+ - ['Ret', '⡷']
+ - ['ret', '⠷']
+ - ['Skal', '⡿']
+ - ['skal', '⠿']
+ - ['Te', '⡳']
+ - ['te', '⠳']
+ - ['Var', '⡼']
+ - ['var', '⠼']
+
+# Partword/nocross
+
+ - ['Denne', '⡯⠫']
+ - ['denne', '⠯⠫']
+ - ['Mændene', '⡍⠜⠝⠹⠫']
+ - ['mændene', '⠍⠜⠝⠹⠫']
+ - ['Derhos', '⡾⠓⠕⠎']
+ - ['derhos', '⠾⠓⠕⠎']
+ - ['Hunderace', '⡓⠥⠝⠹⠗⠁⠉⠑']
+ - ['hunderace', '⠓⠥⠝⠹⠗⠁⠉⠑']
+ - ['Dette', '⡮⠳']
+ - ['dette', '⠮⠳']
+ - ['Detalje', '⡹⠞⠁⠇⠚⠑']
+ - ['detalje', '⠹⠞⠁⠇⠚⠑']
+
+# Nocross multiple cells
+
+ - ['Endda', '⡑⠟⠙⠁']
+ - ['endda', '⠑⠟⠙⠁']
+ - ['Morgendag', '⡍⠭⠛⠣⠙⠁⠛']
+ - ['morgendag', '⠍⠭⠛⠣⠙⠁⠛']
+ - ['Gendanne', '⡛⠣⠙⠁⠝⠫']
+ - ['gendanne', '⠛⠣⠙⠁⠝⠫']
+ - ['Generelt', '⡻⠫⠷⠇⠞']
+ - ['generelt', '⠻⠫⠷⠇⠞']
+
+ - ['Fra!', '⡋⠗⠁⠖']
+ - ['fra!', '⠋⠗⠁⠖']
+ - ['!Fra', '⠰⠖⡖']
+ - ['!fra', '⠖⠋⠗⠁']
+ - ['''Af', '⠈⡴']
+ - ['''af', '⠈⠁⠋']
+
+# Capsnocont
+
+ - ['UNDER et', '⡥⡝⡙⡑⡗ ⠬']
+
+# No single cell contractions before or after dashes
+
+ - ['at-bliver', '⠁⠞⠤⠃']
+ - ['d-d-du', '⠰⠙⠤⠰⠙⠤⠙⠥']
+
+# Combinations with slashes and other punctuation signs
+
+ - ["at!", "⠁⠖"]
+ - ["bliver!", "⠃⠖"]
+ - ["og!", "⠉⠖"]
+ - ['Han/hun', '⡽⢌⠥']
+ - ['han/hun', '⠽⢌⠥']
+ - ['Over/under', '⡭⢌⠟']
+ - ['over/under', '⠭⢌⠟']
+ - ['Til/fra', '⡞⢌⠖']
+ - ['til/fra', '⠞⢌⠖']
+
+# Combinations which require letsign
+
+ - ['1st', '⢁⠰⠎⠞']
+ - ['2nd', '⢃⠝⠙']
+ - ['1A', '⢁⠰⡁']
+ - ['1a', '⢁⠰⠁']
+ - ['2B', '⢃⠰⡃']
+ - ['2b', '⢃⠰⠃']
+
+# Emphasis (cannot be back-translated)
+# Single letter emphasis currently fails due to contraction across emphasis.
+
+flags: {testmode: forward}
+tests:
+
+ - # Bold line
+ - En linje med fed.
+ - ⠨⡣ ⠇⠊⠝⠚⠑ ⠍ ⠋⠑⠙⠄⠨
+ - typeform:
+ bold: '+++++++++++++++++'
+ - # Bold word
+ - Et ord med fed.
+ - ⡬ ⠨⠭⠙⠨ ⠍ ⠋⠑⠙⠄
+ - typeform:
+ bold: ' +++ '
+ - # Bold letter
+ - Et bogstav med fed.
+ - ⡬ ⠃⠕⠛⠨⠎⠨⠞⠁⠧ ⠍ ⠋⠑⠙⠄
+ - {typeform: {bold: ' + '}, xfail: true}
+
+ - # Italic line
+ - En linje med kursiv.
+ - ⠨⡣ ⠇⠊⠝⠚⠑ ⠍ ⠅⠥⠗⠎⠊⠧⠄⠨
+ - typeform:
+ italic: '++++++++++++++++++++'
+ - # Italic word
+ - Et ord med kursiv.
+ - ⡬ ⠨⠭⠙⠨ ⠍ ⠅⠥⠗⠎⠊⠧⠄
+ - typeform:
+ italic: ' +++ '
+ - # Italic letter
+ - Et bogstav med kursiv.
+ - ⡬ ⠃⠕⠛⠨⠎⠨⠞⠁⠧ ⠍ ⠅⠥⠗⠎⠊⠧⠄
+ - {typeform: {italic: ' + '}, xfail: true}
+
+ - # Underlined line
+ - En linje med understreget.
+ - ⠨⡣ ⠇⠊⠝⠚⠑ ⠍ ⠥⠝⠾⠵⠷⠛⠬⠄⠨
+ - typeform:
+ underline: '++++++++++++++++++++++++++'
+ - # Underlined word
+ - Et ord med understreget.
+ - ⡬ ⠨⠭⠙⠨ ⠍ ⠥⠝⠾⠵⠷⠛⠬⠄
+ - typeform:
+ underline: ' +++ '
+ - # Underlined letter
+ - Et bogstav med understreget.
+ - ⡬ ⠃⠕⠛⠨⠎⠨⠞⠁⠧ ⠍ ⠥⠝⠾⠵⠷⠛⠬⠄
+ - {typeform: {underline: ' + '}, xfail: true}
+
+ - # Bold, italic and underlined line
+ - En linje med alt.
+ - ⠨⡣ ⠇⠊⠝⠚⠑ ⠍ ⠁⠇⠞⠄⠨
+ - typeform:
+ bold: '+++++++++++++++++'
+ italic: '+++++++++++++++++'
+ underline: '+++++++++++++++++'
+ - # Bold, italic and underlined word
+ - Et ord med alt.
+ - ⡬ ⠨⠭⠙⠨ ⠍ ⠁⠇⠞⠄
+ - typeform:
+ bold: ' +++ '
+ italic: ' +++ '
+ underline: ' +++ '
+ - # Bold, italic and underlined letter
+ - Et bogstav med alt.
+ - ⡬ ⠃⠕⠛⠨⠎⠨⠞⠁⠧ ⠍ ⠁⠇⠞⠄
+ - {typeform: {bold: ' + ', italic: ' + ', underline: ' + '}, xfail: true}
diff --git a/LibLouis.NET.Test/braille-specs/da-dk_1993.yaml b/LibLouis.NET.Test/braille-specs/da-dk_1993.yaml
new file mode 100644
index 0000000..a1d0cbf
--- /dev/null
+++ b/LibLouis.NET.Test/braille-specs/da-dk_1993.yaml
@@ -0,0 +1,5970 @@
+# This file contains tests for the complete Danish 1993 braille
+# standard: all grades (0, 1, 1.5 and 2), 6-dot and 8-dot, regular and
+# "literary" (not back-translatable). Previously there was one test
+# file for each variant, but now that there is a new standard and the
+# table for the old standard are pretty much frozen, it has been
+# decided to collect the tests in a single file to keep things
+# tidy. The dictionary tests were left in separate files.
+
+# There is a lot of repetition in this file which could be eliminated
+# with some refactoring, but because we're dealing with a deprecated
+# standard we're not going to bother.
+
+display: unicode-without-blank.dis
+
+#############
+### 6-DOT ###
+#############
+
+# -----------------
+# Grade 1 (regular)
+# -----------------
+
+# Round trip tests
+# Commented tests currently fail backwards but should be fixed.
+
+table: {language: da, grade: 1, dots: 6, direction: both, version: 1993, __assert-match: da-dk-g16_1993.ctb}
+flags: {testmode: bothDirections}
+tests:
+
+# Characters
+
+ - [" ", " "]
+ - ["\"", "⠶"]
+ - ["\u0023", "⠘⠼"]
+ - ["$", "⠘⠲"]
+ - ["%", "⠚⠴"]
+ - ["&", "⠯"]
+ - ["'", "⠈"]
+ - ["(", "⠦"]
+ - [")", "⠴"]
+ - ["*", "⠔"]
+ - ["+", "⠘⠖"]
+ - [",", "⠂"]
+ - ["-", "⠤⠤"]
+ - [".", "⠄"]
+ - ["/", "⠌"]
+ - ["0", "⠼⠚"]
+ - ["1", "⠼⠁"]
+ - ["2", "⠼⠃"]
+ - ["3", "⠼⠉"]
+ - ["4", "⠼⠙"]
+ - ["5", "⠼⠑"]
+ - ["6", "⠼⠋"]
+ - ["7", "⠼⠛"]
+ - ["8", "⠼⠓"]
+ - ["9", "⠼⠊"]
+ - [":", "⠒"]
+ - [";", "⠆"]
+ - ["<", "⠘⠍"]
+ - ["=", "⠘⠶"]
+ - [">", "⠘⠎"]
+ - ["?", "⠢"]
+ - ["@", "⠘⠁"]
+ - ["A", "⠨⠁"]
+ - ["B", "⠨⠃"]
+ - ["C", "⠨⠉"]
+ - ["D", "⠨⠙"]
+ - ["E", "⠨⠑"]
+ - ["F", "⠨⠋"]
+ - ["G", "⠨⠛"]
+ - ["H", "⠨⠓"]
+ - ["I", "⠨⠊"]
+ - ["J", "⠨⠚"]
+ - ["K", "⠨⠅"]
+ - ["L", "⠨⠇"]
+ - ["M", "⠨⠍"]
+ - ["N", "⠨⠝"]
+ - ["O", "⠨⠕"]
+ - ["P", "⠨⠏"]
+ - ["Q", "⠨⠟"]
+ - ["R", "⠨⠗"]
+ - ["S", "⠨⠎"]
+ - ["T", "⠨⠞"]
+ - ["U", "⠨⠥"]
+ - ["V", "⠨⠧"]
+ - ["W", "⠨⠺"]
+ - ["X", "⠨⠭"]
+ - ["Y", "⠨⠽"]
+ - ["Z", "⠨⠵"]
+ - ["[", "⠐⠦"]
+ - ["\u005c\u005c", "⠘⠡"]
+ - ["]", "⠐⠴"]
+ - ["^", "⠘⠬"]
+ - ["_", "⠘⠤"]
+ - ["a", "⠁"]
+ - ["b", "⠃"]
+ - ["c", "⠉"]
+ - ["d", "⠙"]
+ - ["e", "⠑"]
+ - ["f", "⠋"]
+ - ["g", "⠛"]
+ - ["h", "⠓"]
+ - ["i", "⠊"]
+ - ["j", "⠚"]
+ - ["k", "⠅"]
+ - ["l", "⠇"]
+ - ["m", "⠍"]
+ - ["n", "⠝"]
+ - ["o", "⠕"]
+ - ["p", "⠏"]
+ - ["q", "⠟"]
+ - ["r", "⠗"]
+ - ["s", "⠎"]
+ - ["t", "⠞"]
+ - ["u", "⠥"]
+ - ["v", "⠧"]
+ - ["w", "⠺"]
+ - ["x", "⠭"]
+ - ["y", "⠽"]
+ - ["z", "⠵"]
+ - ["{", "⠘⠪"]
+ - ["|", "⠘⠸"]
+ - ["}", "⠘⠕"]
+ - ["€", "⠘⠑"]
+ - ["ƒ", "⠘⠋"]
+ - ["‰", "⠚⠴⠴"]
+ - ["Š", "⠨⠐⠎"]
+ - ["Ž", "⠨⠐⠵"]
+ - ["•", "⠘⠄"]
+ - ["™", "⠘⠞"]
+ - ["š", "⠐⠎"]
+ - ["ž", "⠐⠵"]
+ - ["¢", "⠘⠒"]
+ - ["£", "⠘⠇"]
+ - ["¥", "⠘⠽"]
+ - ["§", "⠬"]
+ - ["©", "⠘⠉"]
+ - ["®", "⠘⠗"]
+ - ["°", "⠈⠴"]
+ - ["²", "⠼⠬⠃"]
+ - ["³", "⠼⠬⠉"]
+ - ["µ", "⠐⠍"]
+ - ["¹", "⠼⠬⠁"]
+ - ["À", "⠨⠐⠁"]
+ - ["Å", "⠨⠡"]
+ - ["Æ", "⠨⠜"]
+ - ["Ç", "⠨⠐⠉"]
+ - ["É", "⠨⠐⠑"]
+ - ["Î", "⠨⠐⠊"]
+ - ["Ð", "⠨⠐⠙"]
+ - ["Ñ", "⠨⠐⠝"]
+ - ["Ô", "⠨⠐⠕"]
+ - ["Ø", "⠨⠪"]
+ - ["Û", "⠨⠐⠥"]
+ - ["Ü", "⠨⠳"]
+ - ["Ý", "⠨⠐⠽"]
+ - ["Þ", "⠨⠐⠞"]
+ - ["à", "⠐⠁"]
+ - ["å", "⠡"]
+ - ["æ", "⠜"]
+ - ["ç", "⠐⠉"]
+ - ["é", "⠐⠑"]
+ - ["î", "⠐⠊"]
+ - ["ð", "⠐⠙"]
+ - ["ñ", "⠐⠝"]
+ - ["ô", "⠐⠕"]
+ - ["÷", "⠲"]
+ - ["ø", "⠪"]
+ - ["û", "⠐⠥"]
+ - ["ü", "⠳"]
+ - ["ý", "⠐⠽"]
+ - ["þ", "⠐⠞"]
+
+# Misc. Unicode (most cannot be back-translated)
+# Some tests may be repetitions of tests above, since
+# some characters can occur both inside and outside the 8 bit range.
+# for accented letters in the range u+0080 - u+00ff: the letters
+# that are thought to occur most frequently in Danish texts are used
+# for back-translation.
+# For all accented letters above u+00ff, the first occurring instance is chosen for back-translation.
+# There are no rules about this in the specs of Danish Braille,
+# So the choice is arbitrary and may change over time.
+
+ - ["\u0134\u0135", "⠨⠐⠚⠐⠚"]
+ - ["\u0138", "⠐⠟"]
+ - ["\u0192", "⠘⠋"]
+
+# Greek letters (with dot 5 as prefix)
+
+ - ["\u0392\u03b2", "⠨⠐⠃⠐⠃"]
+ - ["\u0393\u03b3", "⠨⠐⠛⠐⠛"]
+ - ["\u0397\u03b7", "⠨⠐⠱⠐⠱"]
+ - ["\u0398\u03b8", "⠨⠐⠹⠐⠹"]
+ - ["\u039a\u03ba", "⠨⠐⠅⠐⠅"]
+ - ["\u039b\u03bb", "⠨⠐⠇⠐⠇"]
+ - ["\u039e\u03be", "⠨⠐⠭⠐⠭"]
+ - ["\u03a0\u03c0", "⠨⠐⠏⠐⠏"]
+ - ["\u03a1\u03c1", "⠨⠐⠗⠐⠗"]
+ - ["\u03a6\u03c6", "⠨⠐⠋⠐⠋"]
+ - ["\u03a7\u03c7", "⠨⠐⠓⠐⠓"]
+ - ["\u03a9\u03c9", "⠨⠐⠺⠐⠺"]
+
+# Arrows (only a few in 6 dots)
+
+ - ["\u2190", "⠘⠺"]
+ - ["\u2191", "⠘⠷"]
+ - ["\u2193", "⠘⠟"]
+
+# Pangram
+
+ - - "Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Walther spillede på xylofon."
+ - "⠨⠟⠥⠊⠵⠙⠑⠇⠞⠁⠛⠑⠗⠝⠑ ⠎⠏⠊⠎⠞⠑ ⠚⠕⠗⠙⠃⠜⠗ ⠍⠑⠙ ⠋⠇⠪⠙⠑⠂ ⠍⠑⠝⠎ ⠉⠊⠗⠅⠥⠎⠅⠇⠕⠧⠝⠑⠝ ⠨⠺⠁⠇⠞⠓⠑⠗ ⠎⠏⠊⠇⠇⠑⠙⠑ ⠏⠡ ⠭⠽⠇⠕⠋⠕⠝⠄"
+
+# Caps and mixed case
+
+ - ["Foobar", "⠨⠋⠕⠕⠃⠁⠗"]
+ - ["FOOBAR", "⠸⠋⠕⠕⠃⠁⠗"]
+ - ["FOObar", "⠸⠋⠕⠕⠠⠃⠁⠗"]
+ - ["FOO-barfOObar", "⠸⠋⠕⠕⠤⠃⠁⠗⠋⠸⠕⠕⠠⠃⠁⠗"]
+
+# Times vs. bullit
+
+ - ["\u2022Bullit", "⠘⠄⠨⠃⠥⠇⠇⠊⠞"]
+# - ["2 \u00d7 2 = 4", "⠼⠃ ⠘⠄ ⠼⠃ ⠘⠶ ⠼⠙"]
+
+# Section sign
+
+ - ["§ 3", "⠬⠼⠉"]
+ - ["§ 3:", "⠬⠼⠉⠒"]
+
+# Numbers and punctuation
+
+ - ["1,2", "⠼⠁⠂⠃"]
+ - ["123.456", "⠼⠁⠃⠉⠄⠙⠑⠋"]
+ - ["3-4", "⠼⠉⠤⠼⠙"]
+ - ["56-", "⠼⠑⠋⠤"]
+ - ["1/2", "⠼⠁⠌⠃"]
+ - ["12:34", "⠼⠁⠃⠒⠉⠙"]
+ - ["2^10", "⠼⠃⠘⠬⠁⠚"]
+ - ["J) j) %) ') \u2030)", "⠨⠚⠠⠴ ⠚⠠⠴ ⠚⠴⠠⠴ ⠈⠠⠴ ⠚⠴⠴⠠⠴"]
+
+ - ["\"quotes\"", "⠶⠟⠥⠕⠞⠑⠎⠶"]
+ - ["-dashes-", "⠤⠙⠁⠎⠓⠑⠎⠤"]
+ - [":-) :-(", "⠒⠤⠴ ⠒⠤⠦"]
+ - [";-) ;-(", "⠆⠤⠴ ⠆⠤⠦"]
+ - ["---", "⠤⠤⠤"]
+ - ["-", "⠤⠤"]
+# - [" -", " ⠤⠤"]
+ - [" a-", " ⠁⠤"]
+ - [" - ", " ⠤⠤ "]
+ - [" -a-", " ⠤⠁⠤"]
+ - [" ", " "]
+ - ["(parentheses)", "⠦⠏⠁⠗⠑⠝⠞⠓⠑⠎⠑⠎⠴"]
+
+# Digits and letters
+
+ - ["1a", "⠼⠁⠠⠁"]
+ - ["1.,-a", "⠼⠁⠄⠂⠤⠠⠁"]
+
+# Multi-pass tests
+
+# - ["~x |z", "⠘⠠⠭ ⠘⠸⠵"]
+# - ["~X |Z", "⠘⠠⠨⠭ ⠘⠸⠨⠵"]
+ - ["5É", "⠼⠑⠨⠐⠑"]
+
+# Characters and constructs which cannot be properly back-translated
+
+flags: {testmode: forward}
+tests:
+
+ - ["`", "⠈"]
+ - ["~", "⠘⠠"]
+ - ["‚", "⠈"]
+ - ["„", "⠶"]
+ - ["…", "⠄⠄⠄"]
+ - ["‹", "⠈"]
+ - ["Œ", "⠨⠕⠑"]
+ - ["‘", "⠈"]
+ - ["’", "⠈"]
+ - ["“", "⠶"]
+ - ["”", "⠶"]
+ - ["–", "⠤⠤"]
+ - ["—", "⠤⠤"]
+ - ["˜", "⠘⠠"]
+ - ["›", "⠈"]
+ - ["œ", "⠕⠑"]
+ - ["Ÿ", "⠨⠐⠽"]
+ - ["¡", "⠲"]
+ - ["«", "⠶"]
+ - ["", "⠤⠤"]
+ - ["¯", "⠢"]
+ - ["±", "⠘⠖⠤"]
+ - ["´", "⠈"]
+ - ["»", "⠶"]
+ - ["¼", "⠼⠁⠌⠙"]
+ - ["½", "⠼⠁⠌⠃"]
+ - ["¾", "⠼⠉⠌⠙"]
+ - ["Á", "⠨⠐⠁"]
+ - ["Â", "⠨⠐⠁"]
+ - ["Ã", "⠨⠐⠁"]
+ - ["Ä", "⠨⠜"]
+ - ["È", "⠨⠐⠑"]
+ - ["Ê", "⠨⠐⠑"]
+ - ["Ë", "⠨⠐⠑"]
+ - ["Ì", "⠨⠐⠊"]
+ - ["Í", "⠨⠐⠊"]
+ - ["Ï", "⠨⠐⠊"]
+ - ["Ò", "⠨⠐⠕"]
+ - ["Ó", "⠨⠐⠕"]
+ - ["Õ", "⠨⠐⠕"]
+ - ["Ö", "⠨⠪"]
+ - ["×", "⠘⠄"]
+ - ["Ù", "⠨⠐⠥"]
+ - ["Ú", "⠨⠐⠥"]
+ - ["ß", "⠎⠎"]
+ - ["á", "⠐⠁"]
+ - ["â", "⠐⠁"]
+ - ["ã", "⠐⠁"]
+ - ["ä", "⠜"]
+ - ["è", "⠐⠑"]
+ - ["ê", "⠐⠑"]
+ - ["ë", "⠐⠑"]
+ - ["ì", "⠐⠊"]
+ - ["í", "⠐⠊"]
+ - ["ï", "⠐⠊"]
+ - ["ò", "⠐⠕"]
+ - ["ó", "⠐⠕"]
+ - ["õ", "⠐⠕"]
+ - ["ö", "⠪"]
+ - ["ù", "⠐⠥"]
+ - ["ú", "⠐⠥"]
+ - ["ÿ", "⠐⠽"]
+
+# Latin Extended-A
+
+ - ["\u0100\u0101", "⠨⠐⠁⠐⠁"]
+ - ["\u0102\u0103", "⠨⠐⠁⠐⠁"]
+ - ["\u0104\u0105", "⠨⠐⠁⠐⠁"]
+ - ["\u0106\u0107", "⠨⠐⠉⠐⠉"]
+ - ["\u0108\u0109", "⠨⠐⠉⠐⠉"]
+ - ["\u010a\u010b", "⠨⠐⠉⠐⠉"]
+ - ["\u010c\u010d", "⠨⠐⠉⠐⠉"]
+ - ["\u010e\u010f", "⠨⠐⠙⠐⠙"]
+ - ["\u0110\u0111", "⠨⠐⠙⠐⠙"]
+ - ["\u0112\u0113", "⠨⠐⠑⠐⠑"]
+ - ["\u0114\u0115", "⠨⠐⠑⠐⠑"]
+ - ["\u0116\u0117", "⠨⠐⠑⠐⠑"]
+ - ["\u0118\u0119", "⠨⠐⠑⠐⠑"]
+ - ["\u011a\u011b", "⠨⠐⠑⠐⠑"]
+ - ["\u011c\u011d", "⠨⠐⠛⠐⠛"]
+ - ["\u011e\u011f", "⠨⠐⠛⠐⠛"]
+ - ["\u0120\u0121", "⠨⠐⠛⠐⠛"]
+ - ["\u0122\u0123", "⠨⠐⠛⠐⠛"]
+ - ["\u0124\u0125", "⠨⠐⠓⠐⠓"]
+ - ["\u0126\u0127", "⠨⠐⠓⠐⠓"]
+ - ["\u0128\u0129", "⠨⠐⠊⠐⠊"]
+ - ["\u012a\u012b", "⠨⠐⠊⠐⠊"]
+ - ["\u012c\u012d", "⠨⠐⠊⠐⠊"]
+ - ["\u012e\u012f", "⠨⠐⠊⠐⠊"]
+ - ["\u0130\u0131", "⠨⠐⠊⠐⠊"]
+ - ["\u0132\u0133", "⠨⠊⠚⠊⠚"]
+ - ["\u0136\u0137", "⠨⠐⠅⠐⠅"]
+ - ["\u0139\u013a", "⠨⠐⠇⠐⠇"]
+ - ["\u013b\u013c", "⠨⠐⠇⠐⠇"]
+ - ["\u013d\u013e", "⠨⠐⠇⠐⠇"]
+ - ["\u013f\u0140", "⠨⠐⠇⠐⠇"]
+ - ["\u0141\u0142", "⠨⠐⠇⠐⠇"]
+ - ["\u0143\u0144", "⠨⠐⠝⠐⠝"]
+ - ["\u0145\u0146", "⠨⠐⠝⠐⠝"]
+ - ["\u0147\u0148", "⠨⠐⠝⠐⠝"]
+ - ["\u0149", "⠈⠝"]
+ - ["\u014a\u014b", "⠨⠐⠝⠐⠝"]
+ - ["\u014c\u014d", "⠨⠐⠕⠐⠕"]
+ - ["\u014e\u014f", "⠨⠐⠕⠐⠕"]
+ - ["\u0150\u0151", "⠨⠐⠕⠐⠕"]
+ - ["\u0152\u0153", "⠨⠕⠑⠕⠑"]
+ - ["\u0154\u0155", "⠨⠐⠗⠐⠗"]
+ - ["\u0156\u0157", "⠨⠐⠗⠐⠗"]
+ - ["\u0158\u0159", "⠨⠐⠗⠐⠗"]
+ - ["\u015a\u015b", "⠨⠐⠎⠐⠎"]
+ - ["\u015c\u015d", "⠨⠐⠎⠐⠎"]
+ - ["\u015e\u015f", "⠨⠐⠎⠐⠎"]
+ - ["\u0160\u0161", "⠨⠐⠎⠐⠎"]
+ - ["\u0162\u0163", "⠨⠐⠞⠐⠞"]
+ - ["\u0164\u0165", "⠨⠐⠞⠐⠞"]
+ - ["\u0166\u0167", "⠨⠐⠞⠐⠞"]
+ - ["\u0168\u0169", "⠨⠐⠥⠐⠥"]
+ - ["\u016a\u016b", "⠨⠐⠥⠐⠥"]
+ - ["\u016c\u016d", "⠨⠐⠥⠐⠥"]
+ - ["\u016e\u016f", "⠨⠐⠥⠐⠥"]
+ - ["\u0170\u0171", "⠨⠐⠥⠐⠥"]
+ - ["\u0172\u0173", "⠨⠐⠥⠐⠥"]
+ - ["\u0174\u0175", "⠨⠐⠺⠐⠺"]
+ - ["\u0176\u0177", "⠨⠐⠽⠐⠽"]
+ - ["\u0178\u00ff", "⠨⠐⠽⠐⠽"]
+ - ["\u0179\u017a", "⠨⠐⠵⠐⠵"]
+ - ["\u017b\u017c", "⠨⠐⠵⠐⠵"]
+ - ["\u017d\u017e", "⠨⠐⠵⠐⠵"]
+ - ["\u017f", "⠐⠎"]
+
+# Latin Extended-B
+
+ - ["\u02dc", "⠘⠠"]
+
+# Greek letters (with dot 5 as prefix)
+
+ - ["\u0386\u03ac", "⠨⠐⠁⠐⠁"]
+ - ["\u0388\u03ad", "⠨⠐⠑⠐⠑"]
+ - ["\u0389\u03ae", "⠨⠐⠱⠐⠱"]
+ - ["\u038a\u03af", "⠨⠐⠊⠐⠊"]
+ - ["\u038c\u03cc", "⠨⠐⠕⠐⠕"]
+ - ["\u038e\u03cd", "⠨⠐⠥⠐⠥"]
+ - ["\u038f\u03ce", "⠨⠐⠺⠐⠺"]
+ - ["\u0391\u03b1", "⠨⠐⠁⠐⠁"]
+ - ["\u0394\u03b4", "⠨⠐⠙⠐⠙"]
+ - ["\u0395\u03b5", "⠨⠐⠑⠐⠑"]
+ - ["\u0396\u03b6", "⠨⠐⠵⠐⠵"]
+ - ["\u0399\u03b9", "⠨⠐⠊⠐⠊"]
+ - ["\u039c\u03bc", "⠨⠐⠍⠐⠍"]
+ - ["\u039d\u03bd", "⠨⠐⠝⠐⠝"]
+ - ["\u039f\u03bf", "⠨⠐⠕⠐⠕"]
+ - ["\u03a3\u03c3", "⠨⠐⠎⠐⠎"]
+ - ["\u03a4\u03c4", "⠨⠐⠞⠐⠞"]
+ - ["\u03a5\u03c5", "⠨⠐⠥⠐⠥"]
+ - ["\u03a8\u03c8", "⠨⠐⠽⠐⠽"]
+
+# Punctuation and bullits
+
+ - ["\u2000", " "]
+ - ["\u2001", " "]
+ - ["\u2002", " "]
+ - ["\u2003", " "]
+ - ["\u2004", " "]
+ - ["\u2005", " "]
+ - ["\u2006", " "]
+ - ["\u2007", " "]
+ - ["\u2008", " "]
+ - ["\u2009", " "]
+ - ["\u200a", " "]
+ - ["\u2010", "⠤"]
+ - ["\u2011", "⠤"]
+ - ["\u2012", "⠤"]
+ - ["\u2013", "⠤⠤"]
+ - ["\u2014", "⠤⠤"]
+ - ["\u2018", "⠈"]
+ - ["\u2019", "⠈"]
+ - ["\u201a", "⠈"]
+ - ["\u201b", "⠈"]
+ - ["\u201c", "⠶"]
+ - ["\u201d", "⠶"]
+ - ["\u201e", "⠶"]
+ - ["\u201f", "⠶"]
+ - ["\u2023", "⠘⠄"]
+ - ["\u2026", "⠄⠄⠄"]
+ - ["\u202f", " "]
+ - ["\u2030", "⠚⠴⠴"]
+ - ["\u2039", "⠈"]
+ - ["\u203a", "⠈"]
+ - ["\u203c", "⠖⠖"]
+ - ["\u203d", "⠢⠖"]
+ - ["\u2043", "⠘⠄"]
+ - ["\u2047", "⠢⠢"]
+ - ["\u2048", "⠢⠖"]
+ - ["\u2049", "⠖⠢"]
+ - ["\u204c", "⠘⠄"]
+ - ["\u204d", "⠘⠄"]
+ - ["\u20ac", "⠘⠑"]
+ - ["\u2122", "⠘⠞"]
+
+# Arrows (only a few in 6 dots)
+
+ - ["\u2192", "⠘⠗"] # back-translates as "registered".
+
+# Geometrical shapes
+
+ - ["\u25e6", "⠘⠄"]
+
+# Extra digits
+
+ - ["1\u00bc + 1\u00bd = 2\u00be", "⠼⠁⠼⠁⠌⠙ ⠘⠖ ⠼⠁⠼⠁⠌⠃ ⠘⠶ ⠼⠃⠼⠉⠌⠙"]
+
+# Dashes
+
+ - ["\u2014 \u0096 \u0097 \u00ad", "⠤⠤ ⠤⠤ ⠤⠤ ⠤⠤"]
+
+# Quotes
+
+ - ["\u201e \u0084 \u201c \u0093 \u201d \u0094 \u00ab \u00bb", "⠶ ⠶ ⠶ ⠶ ⠶ ⠶ ⠶ ⠶"]
+
+# Apostrophes
+
+ - ["` \u201a \u0082 \u2039 \u008b \u2018 \u0091 \u2019 \u0092 \u203a \u009b \u00b4", "⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈"]
+
+ - ["\u0089) \u201a) \u0082) \u2039) \u009b) \u2018) \u0091) \u2019) \u0092) \u203a) \u009b)", "⠚⠴⠴⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴"]
+
+# Emphasis
+
+ - # Bold line
+ - En linje med fed.
+ - ⠰⠨⠑⠝ ⠇⠊⠝⠚⠑ ⠍⠑⠙ ⠋⠑⠙⠄⠰
+ - typeform:
+ bold: '+++++++++++++++++'
+ - # Bold word
+ - Et ord med fed.
+ - ⠨⠑⠞ ⠰⠕⠗⠙⠰ ⠍⠑⠙ ⠋⠑⠙⠄
+ - typeform:
+ bold: ' +++ '
+ - # Bold letter
+ - Et bogstav med fed.
+ - ⠨⠑⠞ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍⠑⠙ ⠋⠑⠙⠄
+ - typeform:
+ bold: ' + '
+
+ - # Italic line
+ - En linje med kursiv.
+ - ⠰⠨⠑⠝ ⠇⠊⠝⠚⠑ ⠍⠑⠙ ⠅⠥⠗⠎⠊⠧⠄⠰
+ - typeform:
+ italic: '++++++++++++++++++++'
+ - # Italic word
+ - Et ord med kursiv.
+ - ⠨⠑⠞ ⠰⠕⠗⠙⠰ ⠍⠑⠙ ⠅⠥⠗⠎⠊⠧⠄
+ - typeform:
+ italic: ' +++ '
+ - # Italic letter
+ - Et bogstav med kursiv.
+ - ⠨⠑⠞ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍⠑⠙ ⠅⠥⠗⠎⠊⠧⠄
+ - typeform:
+ italic: ' + '
+
+ - # Underlined line
+ - En linje med understreget.
+ - ⠰⠨⠑⠝ ⠇⠊⠝⠚⠑ ⠍⠑⠙ ⠥⠝⠙⠑⠗⠎⠞⠗⠑⠛⠑⠞⠄⠰
+ - typeform:
+ underline: '++++++++++++++++++++++++++'
+ - # Underlined word
+ - Et ord med understreget.
+ - ⠨⠑⠞ ⠰⠕⠗⠙⠰ ⠍⠑⠙ ⠥⠝⠙⠑⠗⠎⠞⠗⠑⠛⠑⠞⠄
+ - typeform:
+ underline: ' +++ '
+ - # Underlined letter
+ - Et bogstav med understreget.
+ - ⠨⠑⠞ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍⠑⠙ ⠥⠝⠙⠑⠗⠎⠞⠗⠑⠛⠑⠞⠄
+ - typeform:
+ underline: ' + '
+
+ - # Bold, italic and underlined line
+ - En linje med alt.
+ - ⠰⠨⠑⠝ ⠇⠊⠝⠚⠑ ⠍⠑⠙ ⠁⠇⠞⠄⠰
+ - typeform:
+ bold: '+++++++++++++++++'
+ italic: '+++++++++++++++++'
+ underline: '+++++++++++++++++'
+ - # Bold, italic and underlined word
+ - Et ord med alt.
+ - ⠨⠑⠞ ⠰⠕⠗⠙⠰ ⠍⠑⠙ ⠁⠇⠞⠄
+ - typeform:
+ bold: ' +++ '
+ italic: ' +++ '
+ underline: ' +++ '
+ - # Bold, italic and underlined letter
+ - Et bogstav med alt.
+ - ⠨⠑⠞ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍⠑⠙ ⠁⠇⠞⠄
+ - typeform:
+ bold: ' + '
+ italic: ' + '
+ underline: ' + '
+
+# Braille patterns which back-translate to something other than the original
+# Typically, single character representations back-translating to strings with more than one character
+
+flags: {testmode: backward}
+tests:
+
+# Characters
+
+ - ["⠄⠄⠄", "..."]
+ - ["⠨⠕⠑", "Oe"]
+ - ["⠕⠑", "oe"]
+ - ["⠘⠖⠤", "±", {xfail: true}]
+ - ["⠼⠁⠌⠙", "1/4"]
+ - ["⠼⠁⠌⠃", "1/2"]
+ - ["⠼⠉⠌⠙", "3/4"]
+
+# Extra digits
+
+ - ["⠼⠁⠼⠁⠌⠙ ⠘⠖ ⠼⠁⠼⠁⠌⠃ ⠘⠶ ⠼⠃⠼⠉⠌⠙", "1\u00bc + 1\u00bd = 2\u00be", {xfail: true}]
+
+# -------------------------------
+# Grade 1 literary (forward only)
+# -------------------------------
+
+table: {language: da, grade: 1, dots: 6, direction: forward, version: 1993, __assert-match: da-dk-g16-lit_1993.ctb}
+flags: {testmode: forward}
+tests:
+
+# Characters
+
+ - [" ", " "]
+ - ["\"", "⠶"]
+ - ["\u0023", "⠘⠼"]
+ - ["$", "⠘⠲"]
+ - ["%", "⠚⠴"]
+ - ["&", "⠯"]
+ - ["'", "⠈"]
+ - ["(", "⠦"]
+ - [")", "⠴"]
+ - ["*", "⠔"]
+ - ["+", "⠘⠖"]
+ - [",", "⠂"]
+ - ["-", "⠤⠤"]
+ - [".", "⠄"]
+ - ["/", "⠌"]
+ - ["0", "⠼⠚"]
+ - ["1", "⠼⠁"]
+ - ["2", "⠼⠃"]
+ - ["3", "⠼⠉"]
+ - ["4", "⠼⠙"]
+ - ["5", "⠼⠑"]
+ - ["6", "⠼⠋"]
+ - ["7", "⠼⠛"]
+ - ["8", "⠼⠓"]
+ - ["9", "⠼⠊"]
+ - [":", "⠒"]
+ - [";", "⠆"]
+ - ["<", "⠘⠍"]
+ - ["=", "⠘⠶"]
+ - [">", "⠘⠎"]
+ - ["?", "⠢"]
+ - ["@", "⠘⠁"]
+ - ["A", "⠨⠁"]
+ - ["B", "⠨⠃"]
+ - ["C", "⠨⠉"]
+ - ["D", "⠨⠙"]
+ - ["E", "⠨⠑"]
+ - ["F", "⠨⠋"]
+ - ["G", "⠨⠛"]
+ - ["H", "⠨⠓"]
+ - ["I", "⠨⠊"]
+ - ["J", "⠨⠚"]
+ - ["K", "⠨⠅"]
+ - ["L", "⠨⠇"]
+ - ["M", "⠨⠍"]
+ - ["N", "⠨⠝"]
+ - ["O", "⠨⠕"]
+ - ["P", "⠨⠏"]
+ - ["Q", "⠨⠟"]
+ - ["R", "⠨⠗"]
+ - ["S", "⠨⠎"]
+ - ["T", "⠨⠞"]
+ - ["U", "⠨⠥"]
+ - ["V", "⠨⠧"]
+ - ["W", "⠨⠺"]
+ - ["X", "⠨⠭"]
+ - ["Y", "⠨⠽"]
+ - ["Z", "⠨⠵"]
+ - ["[", "⠐⠦"]
+ - ["\u005c\u005c", "⠘⠡"]
+ - ["]", "⠐⠴"]
+ - ["^", "⠘⠬"]
+ - ["_", "⠘⠤"]
+ - ["`", "⠈"]
+ - ["a", "⠁"]
+ - ["b", "⠃"]
+ - ["c", "⠉"]
+ - ["d", "⠙"]
+ - ["e", "⠑"]
+ - ["f", "⠋"]
+ - ["g", "⠛"]
+ - ["h", "⠓"]
+ - ["i", "⠊"]
+ - ["j", "⠚"]
+ - ["k", "⠅"]
+ - ["l", "⠇"]
+ - ["m", "⠍"]
+ - ["n", "⠝"]
+ - ["o", "⠕"]
+ - ["p", "⠏"]
+ - ["q", "⠟"]
+ - ["r", "⠗"]
+ - ["s", "⠎"]
+ - ["t", "⠞"]
+ - ["u", "⠥"]
+ - ["v", "⠧"]
+ - ["w", "⠺"]
+ - ["x", "⠭"]
+ - ["y", "⠽"]
+ - ["z", "⠵"]
+ - ["{", "⠘⠪"]
+ - ["|", "⠘⠸"]
+ - ["}", "⠘⠕"]
+ - ["~", "⠘⠠"]
+ - ["€", "⠘⠑"]
+ - ["‚", "⠈"]
+ - ["ƒ", "⠘⠋"]
+ - ["„", "⠶"]
+ - ["…", "⠄⠄⠄"]
+ - ["‰", "⠚⠴⠴"]
+ - ["Š", "⠨⠐⠎"]
+ - ["‹", "⠈"]
+ - ["Œ", "⠨⠕⠑"]
+ - ["Ž", "⠨⠐⠵"]
+ - ["‘", "⠈"]
+ - ["’", "⠈"]
+ - ["“", "⠶"]
+ - ["”", "⠶"]
+ - ["•", "⠘⠄"]
+ - ["–", "⠤⠤"]
+ - ["—", "⠤⠤"]
+ - ["˜", "⠘⠠"]
+ - ["™", "⠘⠞"]
+ - ["š", "⠐⠎"]
+ - ["›", "⠈"]
+ - ["œ", "⠕⠑"]
+ - ["ž", "⠐⠵"]
+ - ["Ÿ", "⠨⠐⠽"]
+ - ["¡", "⠲"]
+ - ["¢", "⠘⠒"]
+ - ["£", "⠘⠇"]
+ - ["¥", "⠘⠽"]
+ - ["§", "⠬"]
+ - ["©", "⠘⠉"]
+ - ["«", "⠶"]
+ - ["", "⠤⠤"]
+ - ["®", "⠘⠗"]
+ - ["¯", "⠢"]
+ - ["°", "⠈⠴"]
+ - ["±", "⠘⠖⠤"]
+ - ["²", "⠼⠬⠃"]
+ - ["³", "⠼⠬⠉"]
+ - ["´", "⠈"]
+ - ["µ", "⠐⠍"]
+ - ["¹", "⠼⠬⠁"]
+ - ["»", "⠶"]
+ - ["¼", "⠼⠁⠌⠙"]
+ - ["½", "⠼⠁⠌⠃"]
+ - ["¾", "⠼⠉⠌⠙"]
+ - ["À", "⠨⠐⠁"]
+ - ["Á", "⠨⠐⠁"]
+ - ["Â", "⠨⠐⠁"]
+ - ["Ã", "⠨⠐⠁"]
+ - ["Ä", "⠨⠜"]
+ - ["Å", "⠨⠡"]
+ - ["Æ", "⠨⠜"]
+ - ["Ç", "⠨⠐⠉"]
+ - ["È", "⠨⠐⠑"]
+ - ["É", "⠨⠐⠑"]
+ - ["Ê", "⠨⠐⠑"]
+ - ["Ë", "⠨⠐⠑"]
+ - ["Ì", "⠨⠐⠊"]
+ - ["Í", "⠨⠐⠊"]
+ - ["Î", "⠨⠐⠊"]
+ - ["Ï", "⠨⠐⠊"]
+ - ["Ð", "⠨⠐⠙"]
+ - ["Ñ", "⠨⠐⠝"]
+ - ["Ò", "⠨⠐⠕"]
+ - ["Ó", "⠨⠐⠕"]
+ - ["Ô", "⠨⠐⠕"]
+ - ["Õ", "⠨⠐⠕"]
+ - ["Ö", "⠨⠪"]
+ - ["×", "⠘⠄"]
+ - ["Ø", "⠨⠪"]
+ - ["Ù", "⠨⠐⠥"]
+ - ["Ú", "⠨⠐⠥"]
+ - ["Û", "⠨⠐⠥"]
+ - ["Ü", "⠨⠳"]
+ - ["Ý", "⠨⠐⠽"]
+ - ["Þ", "⠨⠐⠞"]
+ - ["ß", "⠎⠎"]
+ - ["à", "⠐⠁"]
+ - ["á", "⠐⠁"]
+ - ["â", "⠐⠁"]
+ - ["ã", "⠐⠁"]
+ - ["ä", "⠜"]
+ - ["å", "⠡"]
+ - ["æ", "⠜"]
+ - ["ç", "⠐⠉"]
+ - ["è", "⠐⠑"]
+ - ["é", "⠐⠑"]
+ - ["ê", "⠐⠑"]
+ - ["ë", "⠐⠑"]
+ - ["ì", "⠐⠊"]
+ - ["í", "⠐⠊"]
+ - ["î", "⠐⠊"]
+ - ["ï", "⠐⠊"]
+ - ["ð", "⠐⠙"]
+ - ["ñ", "⠐⠝"]
+ - ["ò", "⠐⠕"]
+ - ["ó", "⠐⠕"]
+ - ["ô", "⠐⠕"]
+ - ["õ", "⠐⠕"]
+ - ["ö", "⠪"]
+ - ["÷", "⠲"]
+ - ["ø", "⠪"]
+ - ["ù", "⠐⠥"]
+ - ["ú", "⠐⠥"]
+ - ["û", "⠐⠥"]
+ - ["ü", "⠳"]
+ - ["ý", "⠐⠽"]
+ - ["þ", "⠐⠞"]
+ - ["ÿ", "⠐⠽"]
+
+# Latin Extended-A
+
+ - ["\u0100\u0101", "⠐⠁⠐⠁"]
+ - ["\u0102\u0103", "⠐⠁⠐⠁"]
+ - ["\u0104\u0105", "⠐⠁⠐⠁"]
+ - ["\u0106\u0107", "⠐⠉⠐⠉"]
+ - ["\u0108\u0109", "⠐⠉⠐⠉"]
+ - ["\u010a\u010b", "⠐⠉⠐⠉"]
+ - ["\u010c\u010d", "⠐⠉⠐⠉"]
+ - ["\u010e\u010f", "⠐⠙⠐⠙"]
+ - ["\u0110\u0111", "⠐⠙⠐⠙"]
+ - ["\u0112\u0113", "⠐⠑⠐⠑"]
+ - ["\u0114\u0115", "⠐⠑⠐⠑"]
+ - ["\u0116\u0117", "⠐⠑⠐⠑"]
+ - ["\u0118\u0119", "⠐⠑⠐⠑"]
+ - ["\u011a\u011b", "⠐⠑⠐⠑"]
+ - ["\u011c\u011d", "⠐⠛⠐⠛"]
+ - ["\u011e\u011f", "⠐⠛⠐⠛"]
+ - ["\u0120\u0121", "⠐⠛⠐⠛"]
+ - ["\u0122\u0123", "⠐⠛⠐⠛"]
+ - ["\u0124\u0125", "⠐⠓⠐⠓"]
+ - ["\u0126\u0127", "⠐⠓⠐⠓"]
+ - ["\u0128\u0129", "⠐⠊⠐⠊"]
+ - ["\u012a\u012b", "⠐⠊⠐⠊"]
+ - ["\u012c\u012d", "⠐⠊⠐⠊"]
+ - ["\u012e\u012f", "⠐⠊⠐⠊"]
+ - ["\u0130\u0131", "⠐⠊⠐⠊"]
+ - ["\u0132\u0133", "⠊⠚⠊⠚"]
+ - ["\u0134\u0135", "⠐⠚⠐⠚"]
+ - ["\u0136\u0137", "⠐⠅⠐⠅"]
+ - ["\u0138", "⠐⠟"]
+ - ["\u0139\u013a", "⠐⠇⠐⠇"]
+ - ["\u013b\u013c", "⠐⠇⠐⠇"]
+ - ["\u013d\u013e", "⠐⠇⠐⠇"]
+ - ["\u013f\u0140", "⠐⠇⠐⠇"]
+ - ["\u0141\u0142", "⠐⠇⠐⠇"]
+ - ["\u0143\u0144", "⠐⠝⠐⠝"]
+ - ["\u0145\u0146", "⠐⠝⠐⠝"]
+ - ["\u0147\u0148", "⠐⠝⠐⠝"]
+ - ["\u0149", "⠈⠝"]
+ - ["\u014a\u014b", "⠐⠝⠐⠝"]
+ - ["\u014c\u014d", "⠐⠕⠐⠕"]
+ - ["\u014e\u014f", "⠐⠕⠐⠕"]
+ - ["\u0150\u0151", "⠐⠕⠐⠕"]
+ - ["\u0152\u0153", "⠕⠑⠕⠑"]
+ - ["\u0154\u0155", "⠐⠗⠐⠗"]
+ - ["\u0156\u0157", "⠐⠗⠐⠗"]
+ - ["\u0158\u0159", "⠐⠗⠐⠗"]
+ - ["\u015a\u015b", "⠐⠎⠐⠎"]
+ - ["\u015c\u015d", "⠐⠎⠐⠎"]
+ - ["\u015e\u015f", "⠐⠎⠐⠎"]
+ - ["\u0160\u0161", "⠐⠎⠐⠎"]
+ - ["\u0162\u0163", "⠐⠞⠐⠞"]
+ - ["\u0164\u0165", "⠐⠞⠐⠞"]
+ - ["\u0166\u0167", "⠐⠞⠐⠞"]
+ - ["\u0168\u0169", "⠐⠥⠐⠥"]
+ - ["\u016a\u016b", "⠐⠥⠐⠥"]
+ - ["\u016c\u016d", "⠐⠥⠐⠥"]
+ - ["\u016e\u016f", "⠐⠥⠐⠥"]
+ - ["\u0170\u0171", "⠐⠥⠐⠥"]
+ - ["\u0172\u0173", "⠐⠥⠐⠥"]
+ - ["\u0174\u0175", "⠐⠺⠐⠺"]
+ - ["\u0176\u0177", "⠐⠽⠐⠽"]
+ - ["\u0178\u00ff", "⠐⠽⠐⠽"]
+ - ["\u0179\u017a", "⠐⠵⠐⠵"]
+ - ["\u017b\u017c", "⠐⠵⠐⠵"]
+ - ["\u017d\u017e", "⠐⠵⠐⠵"]
+ - ["\u017f", "⠐⠎"]
+
+# Latin Extended-B
+
+ - ["\u0192", "⠘⠋"]
+ - ["\u02dc", "⠘⠠"]
+
+# Greek letters (with dot 5 as prefix)
+
+ - ["\u0386\u03ac", "⠐⠁⠐⠁"]
+ - ["\u0388\u03ad", "⠐⠑⠐⠑"]
+ - ["\u0389\u03ae", "⠐⠱⠐⠱"]
+ - ["\u038a\u03af", "⠐⠊⠐⠊"]
+ - ["\u038c\u03cc", "⠐⠕⠐⠕"]
+ - ["\u038e\u03cd", "⠐⠥⠐⠥"]
+ - ["\u038f\u03ce", "⠐⠺⠐⠺"]
+ - ["\u0391\u03b1", "⠐⠁⠐⠁"]
+ - ["\u0392\u03b2", "⠐⠃⠐⠃"]
+ - ["\u0393\u03b3", "⠐⠛⠐⠛"]
+ - ["\u0394\u03b4", "⠐⠙⠐⠙"]
+ - ["\u0395\u03b5", "⠐⠑⠐⠑"]
+ - ["\u0396\u03b6", "⠐⠵⠐⠵"]
+ - ["\u0397\u03b7", "⠐⠱⠐⠱"]
+ - ["\u0398\u03b8", "⠐⠹⠐⠹"]
+ - ["\u0399\u03b9", "⠐⠊⠐⠊"]
+ - ["\u039a\u03ba", "⠐⠅⠐⠅"]
+ - ["\u039b\u03bb", "⠐⠇⠐⠇"]
+ - ["\u039c\u03bc", "⠐⠍⠐⠍"]
+ - ["\u039d\u03bd", "⠐⠝⠐⠝"]
+ - ["\u039e\u03be", "⠐⠭⠐⠭"]
+ - ["\u039f\u03bf", "⠐⠕⠐⠕"]
+ - ["\u03a0\u03c0", "⠐⠏⠐⠏"]
+ - ["\u03a1\u03c1", "⠐⠗⠐⠗"]
+ - ["\u03a3\u03c3", "⠐⠎⠐⠎"]
+ - ["\u03a4\u03c4", "⠐⠞⠐⠞"]
+ - ["\u03a5\u03c5", "⠐⠥⠐⠥"]
+ - ["\u03a6\u03c6", "⠐⠋⠐⠋"]
+ - ["\u03a7\u03c7", "⠐⠓⠐⠓"]
+ - ["\u03a8\u03c8", "⠐⠽⠐⠽"]
+ - ["\u03a9\u03c9", "⠐⠺⠐⠺"]
+
+# Punctuation and bullits
+
+ - ["\u2000", " "]
+ - ["\u2001", " "]
+ - ["\u2002", " "]
+ - ["\u2003", " "]
+ - ["\u2004", " "]
+ - ["\u2005", " "]
+ - ["\u2006", " "]
+ - ["\u2007", " "]
+ - ["\u2008", " "]
+ - ["\u2009", " "]
+ - ["\u200a", " "]
+ - ["\u2010", "⠤"]
+ - ["\u2011", "⠤"]
+ - ["\u2012", "⠤"]
+ - ["\u2013", "⠤⠤"]
+ - ["\u2014", "⠤⠤"]
+ - ["\u2018", "⠈"]
+ - ["\u2019", "⠈"]
+ - ["\u201a", "⠈"]
+ - ["\u201b", "⠈"]
+ - ["\u201c", "⠶"]
+ - ["\u201d", "⠶"]
+ - ["\u201e", "⠶"]
+ - ["\u201f", "⠶"]
+ - ["\u2023", "⠘⠄"]
+ - ["\u2026", "⠄⠄⠄"]
+ - ["\u202f", " "]
+ - ["\u2030", "⠚⠴⠴"]
+ - ["\u2039", "⠈"]
+ - ["\u203a", "⠈"]
+ - ["\u203c", "⠖⠖"]
+ - ["\u203d", "⠢⠖"]
+ - ["\u2043", "⠘⠄"]
+ - ["\u2047", "⠢⠢"]
+ - ["\u2048", "⠢⠖"]
+ - ["\u2049", "⠖⠢"]
+ - ["\u204c", "⠘⠄"]
+ - ["\u204d", "⠘⠄"]
+ - ["\u20ac", "⠘⠑"]
+ - ["\u2122", "⠘⠞"]
+
+# Arrows (only a few in 6 dots)
+
+ - ["\u2190", "⠘⠺"]
+ - ["\u2191", "⠘⠷"]
+ - ["\u2192", "⠘⠗"]
+ - ["\u2193", "⠘⠟"]
+
+# Geometrical shapes
+
+ - ["\u25e6", "⠘⠄"]
+
+# Pangram
+
+ - - "Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Walther spillede på xylofon."
+ - "⠟⠥⠊⠵⠙⠑⠇⠞⠁⠛⠑⠗⠝⠑ ⠎⠏⠊⠎⠞⠑ ⠚⠕⠗⠙⠃⠜⠗ ⠍⠑⠙ ⠋⠇⠪⠙⠑⠂ ⠍⠑⠝⠎ ⠉⠊⠗⠅⠥⠎⠅⠇⠕⠧⠝⠑⠝ ⠺⠁⠇⠞⠓⠑⠗ ⠎⠏⠊⠇⠇⠑⠙⠑ ⠏⠡ ⠭⠽⠇⠕⠋⠕⠝⠄"
+
+# Emphasis
+
+ - # Bold line
+ - En linje med fed.
+ - ⠰⠑⠝ ⠇⠊⠝⠚⠑ ⠍⠑⠙ ⠋⠑⠙⠄⠰
+ - typeform:
+ bold: '+++++++++++++++++'
+ - # Bold word
+ - Et ord med fed.
+ - ⠑⠞ ⠰⠕⠗⠙⠰ ⠍⠑⠙ ⠋⠑⠙⠄
+ - typeform:
+ bold: ' +++ '
+ - # Bold letter
+ - Et bogstav med fed.
+ - ⠑⠞ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍⠑⠙ ⠋⠑⠙⠄
+ - typeform:
+ bold: ' + '
+
+ - # Italic line
+ - En linje med kursiv.
+ - ⠰⠑⠝ ⠇⠊⠝⠚⠑ ⠍⠑⠙ ⠅⠥⠗⠎⠊⠧⠄⠰
+ - typeform:
+ italic: '++++++++++++++++++++'
+ - # Italic word
+ - Et ord med kursiv.
+ - ⠑⠞ ⠰⠕⠗⠙⠰ ⠍⠑⠙ ⠅⠥⠗⠎⠊⠧⠄
+ - typeform:
+ italic: ' +++ '
+ - # Italic letter
+ - Et bogstav med kursiv.
+ - ⠑⠞ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍⠑⠙ ⠅⠥⠗⠎⠊⠧⠄
+ - typeform:
+ italic: ' + '
+
+ - # Underlined line
+ - En linje med understreget.
+ - ⠰⠑⠝ ⠇⠊⠝⠚⠑ ⠍⠑⠙ ⠥⠝⠙⠑⠗⠎⠞⠗⠑⠛⠑⠞⠄⠰
+ - typeform:
+ underline: '++++++++++++++++++++++++++'
+ - # Underlined word
+ - Et ord med understreget.
+ - ⠑⠞ ⠰⠕⠗⠙⠰ ⠍⠑⠙ ⠥⠝⠙⠑⠗⠎⠞⠗⠑⠛⠑⠞⠄
+ - typeform:
+ underline: ' +++ '
+ - # Underlined letter
+ - Et bogstav med understreget.
+ - ⠑⠞ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍⠑⠙ ⠥⠝⠙⠑⠗⠎⠞⠗⠑⠛⠑⠞⠄
+ - typeform:
+ underline: ' + '
+
+ - # Bold, italic and underlined line
+ - En linje med alt.
+ - ⠰⠑⠝ ⠇⠊⠝⠚⠑ ⠍⠑⠙ ⠁⠇⠞⠄⠰
+ - typeform:
+ bold: '+++++++++++++++++'
+ italic: '+++++++++++++++++'
+ underline: '+++++++++++++++++'
+ - # Bold, italic and underlined word
+ - Et ord med alt.
+ - ⠑⠞ ⠰⠕⠗⠙⠰ ⠍⠑⠙ ⠁⠇⠞⠄
+ - typeform:
+ bold: ' +++ '
+ italic: ' +++ '
+ underline: ' +++ '
+ - # Bold, italic and underlined letter
+ - Et bogstav med alt.
+ - ⠑⠞ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍⠑⠙ ⠁⠇⠞⠄
+ - typeform:
+ bold: ' + '
+ italic: ' + '
+ underline: ' + '
+
+# Caps and mixed case
+
+ - ["Foobar", "⠋⠕⠕⠃⠁⠗"]
+ - ["FOOBAR", "⠸⠋⠕⠕⠃⠁⠗"]
+ - ["FOObar", "⠸⠋⠕⠕⠠⠃⠁⠗"]
+ - ["FOO-barfOObar", "⠸⠋⠕⠕⠤⠃⠁⠗⠋⠸⠕⠕⠠⠃⠁⠗"]
+
+# Extra digits
+
+ - ["1\u00bc + 1\u00bd = 2\u00be", "⠼⠁⠼⠁⠌⠙ ⠖⠼⠁⠼⠁⠌⠃ ⠶⠼⠃⠼⠉⠌⠙"]
+
+# Dashes
+
+ - ["\u2014 \u0096 \u0097 \u00ad", "⠤⠤ ⠤⠤ ⠤⠤ ⠤⠤"]
+
+# Quotes
+
+ - ["\u201e \u0084 \u201c \u0093 \u201d \u0094 \u00ab \u00bb", "⠶ ⠶ ⠶ ⠶ ⠶ ⠶ ⠶ ⠶"]
+
+# Apostrophes
+
+ - ["` \u201a \u0082 \u2039 \u008b \u2018 \u0091 \u2019 \u0092 \u203a \u009b \u00b4", "⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈"]
+
+# Times vs. bullit
+
+ - ["\u2022Bullit", "⠘⠄⠃⠥⠇⠇⠊⠞"]
+ - ["2 \u00d7 2 = 4", "⠼⠃ ⠄⠼⠃ ⠶⠼⠙"]
+
+# Section sign
+
+ - ["§ 3", "⠬⠼⠉"]
+ - ["§ 3:", "⠬⠼⠉⠒"]
+
+# Numbers and punctuation
+
+ - ["1,2", "⠼⠁⠂⠃"]
+ - ["123.456", "⠼⠁⠃⠉⠄⠙⠑⠋"]
+ - ["3-4", "⠼⠉⠤⠼⠙"]
+ - ["56-", "⠼⠑⠋⠤"]
+ - ["1/2", "⠼⠁⠌⠃"]
+ - ["12:34", "⠼⠁⠃⠒⠉⠙"]
+ - ["2^10", "⠼⠃⠘⠬⠁⠚"]
+ - ["2\u00d72", "⠼⠃⠘⠄⠼⠃"]
+
+ - ["\"quotes\"", "⠶⠟⠥⠕⠞⠑⠎⠶"]
+ - ["-dashes-", "⠤⠙⠁⠎⠓⠑⠎⠤"]
+ - [":-) :-(", "⠒⠤⠴ ⠒⠤⠦"]
+ - [";-) ;-(", "⠆⠤⠴ ⠆⠤⠦"]
+ - ["---", "⠤⠤⠤"]
+ - ["-", "⠤⠤"]
+ - [" -", " ⠤⠤"]
+ - [" a-", " ⠁⠤"]
+ - [" - ", " ⠤⠤ "]
+ - [" -a-", " ⠤⠁⠤"]
+ - [" ", " "]
+ - ["(parentheses)", "⠦⠏⠁⠗⠑⠝⠞⠓⠑⠎⠑⠎⠴"]
+ - ["J) j) %) ') \u2030) \u0089) \u201a) \u0082) \u2039) \u009b) \u2018) \u0091) \u2019) \u0092) \u203a) \u009b)", "⠨⠚⠠⠴ ⠚⠠⠴ ⠚⠴⠠⠴ ⠈⠠⠴ ⠚⠴⠴⠠⠴ ⠚⠴⠴⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴"]
+
+# Digits and letters
+
+ - ["1a", "⠼⠁⠠⠁"]
+ - ["1.,-a", "⠼⠁⠄⠂⠤⠠⠁"]
+
+# Multi-pass tests
+
+ - ["~x |z", "⠘⠠⠭ ⠘⠸⠵"]
+ - ["~X |Z", "⠘⠠⠨⠭ ⠘⠸⠨⠵"]
+ - ["5É", "⠼⠑⠨⠐⠑"]
+
+# -------------------
+# Grade 1.5 (regular)
+# -------------------
+
+# Round trip tests
+# Commented tests currently fail backwards but should be fixed.
+
+table: {language: da, grade: 1.5, dots: 6, direction: both, version: 1993, __assert-match: da-dk-g26l_1993.ctb}
+flags: {testmode: bothDirections}
+tests:
+
+# Characters
+
+ - [" ", " "]
+ - ["\"", "⠶"]
+ - ["\u0023", "⠘⠼"]
+ - ["$", "⠘⠲"]
+ - ["%", "⠚⠴"]
+ - ["&", "⠠⠯"]
+ - ["'", "⠈"]
+ - ["(", "⠠⠦"]
+ - [")", "⠠⠴"]
+ - ["*", "⠠⠔"]
+ - ["+", "⠘⠖"]
+ - [",", "⠂"]
+ - ["-", "⠤⠤"]
+ - [".", "⠄"]
+# - ["/", "⠌"]
+ - ["0", "⠼⠚"]
+ - ["1", "⠼⠁"]
+ - ["2", "⠼⠃"]
+ - ["3", "⠼⠉"]
+ - ["4", "⠼⠙"]
+ - ["5", "⠼⠑"]
+ - ["6", "⠼⠋"]
+ - ["7", "⠼⠛"]
+ - ["8", "⠼⠓"]
+ - ["9", "⠼⠊"]
+ - [":", "⠒"]
+ - [";", "⠆"]
+ - ["<", "⠘⠍"]
+ - ["=", "⠘⠶"]
+ - [">", "⠘⠎"]
+ - ["?", "⠢"]
+ - ["@", "⠘⠁"]
+ - ["A", "⠨⠠⠁"]
+ - ["B", "⠨⠠⠃"]
+ - ["C", "⠨⠠⠉"]
+ - ["D", "⠨⠠⠙"]
+ - ["E", "⠨⠠⠑"]
+ - ["F", "⠨⠠⠋"]
+ - ["G", "⠨⠠⠛"]
+ - ["H", "⠨⠠⠓"]
+ - ["I", "⠨⠊"]
+ - ["J", "⠨⠠⠚"]
+ - ["K", "⠨⠠⠅"]
+ - ["L", "⠨⠠⠇"]
+ - ["M", "⠨⠠⠍"]
+ - ["N", "⠨⠠⠝"]
+ - ["O", "⠨⠠⠕"]
+ - ["P", "⠨⠠⠏"]
+ - ["Q", "⠨⠠⠟"]
+ - ["R", "⠨⠠⠗"]
+ - ["S", "⠨⠠⠎"]
+ - ["T", "⠨⠠⠞"]
+ - ["U", "⠨⠠⠥"]
+ - ["V", "⠨⠠⠧"]
+ - ["W", "⠨⠠⠺"]
+ - ["X", "⠨⠠⠭"]
+ - ["Y", "⠨⠠⠽"]
+ - ["Z", "⠨⠠⠵"]
+ - ["[", "⠐⠦"]
+ - ["\u005c\u005c", "⠘⠡"]
+ - ["]", "⠐⠴"]
+ - ["^", "⠘⠬"]
+ - ["_", "⠘⠤"]
+ - ["a", "⠠⠁"]
+ - ["b", "⠠⠃"]
+ - ["c", "⠠⠉"]
+ - ["d", "⠠⠙"]
+ - ["e", "⠠⠑"]
+ - ["f", "⠠⠋"]
+ - ["g", "⠠⠛"]
+ - ["h", "⠠⠓"]
+ - ["i", "⠊"]
+ - ["j", "⠠⠚"]
+ - ["k", "⠠⠅"]
+ - ["l", "⠠⠇"]
+ - ["m", "⠠⠍"]
+ - ["n", "⠠⠝"]
+ - ["o", "⠠⠕"]
+ - ["p", "⠠⠏"]
+ - ["q", "⠠⠟"]
+ - ["r", "⠠⠗"]
+ - ["s", "⠠⠎"]
+ - ["t", "⠠⠞"]
+ - ["u", "⠠⠥"]
+ - ["v", "⠠⠧"]
+ - ["w", "⠠⠺"]
+ - ["x", "⠠⠭"]
+ - ["y", "⠠⠽"]
+ - ["z", "⠠⠵"]
+ - ["{", "⠘⠪"]
+ - ["|", "⠘⠸"]
+ - ["}", "⠘⠕"]
+ - ["~", "⠘⠠"]
+ - ["€", "⠘⠑"]
+ - ["ƒ", "⠘⠋"]
+ - ["‰", "⠚⠴⠴"]
+ - ["Š", "⠨⠐⠎"]
+ - ["Ž", "⠨⠐⠵"]
+ - ["•", "⠘⠄"]
+ - ["™", "⠘⠞"]
+ - ["š", "⠐⠎"]
+ - ["ž", "⠐⠵"]
+ - ["¡", "⠠⠲"]
+ - ["¢", "⠘⠒"]
+ - ["£", "⠘⠇"]
+ - ["¥", "⠘⠽"]
+ - ["©", "⠘⠉"]
+ - ["®", "⠘⠗"]
+ - ["°", "⠈⠴"]
+ - ["µ", "⠐⠍"]
+ - ["À", "⠨⠐⠁"]
+ - ["Å", "⠨⠠⠡"]
+ - ["Æ", "⠨⠠⠜"]
+ - ["Ç", "⠨⠐⠉"]
+ - ["É", "⠨⠐⠑"]
+ - ["Î", "⠨⠐⠊"]
+ - ["Ð", "⠨⠐⠙"]
+ - ["Ñ", "⠨⠐⠝"]
+ - ["Ô", "⠨⠐⠕"]
+ - ["Ø", "⠨⠠⠪"]
+ - ["Û", "⠨⠐⠥"]
+ - ["Ü", "⠨⠠⠳"]
+ - ["Ý", "⠨⠐⠽"]
+ - ["Þ", "⠨⠐⠞"]
+ - ["à", "⠐⠁"]
+ - ["å", "⠠⠡"]
+ - ["æ", "⠠⠜"]
+ - ["ç", "⠐⠉"]
+ - ["é", "⠐⠑"]
+ - ["î", "⠐⠊"]
+ - ["ð", "⠐⠙"]
+ - ["ñ", "⠐⠝"]
+ - ["ô", "⠐⠕"]
+ - ["ø", "⠠⠪"]
+ - ["û", "⠐⠥"]
+ - ["ü", "⠠⠳"]
+ - ["ý", "⠐⠽"]
+ - ["þ", "⠐⠞"]
+
+# Misc. Unicode (most cannot be back-translated)
+# Some tests may be repetitions of tests above, since
+# some characters can occur both inside and outside the 8 bit range.
+# for accented letters in the range u+0080 - u+00ff: the letters
+# that are thought to occur most frequently in Danish texts are used
+# for back-translation.
+# For all accented letters above u+00ff, the first occurring instance is chosen for back-translation.
+# There are no rules about this in the specs of Danish Braille,
+# So the choice is arbitrary and may change over time.
+
+ - ["\u0134\u0135", "⠨⠐⠚⠐⠚"]
+ - ["\u0138", "⠐⠟"]
+ - ["\u0192", "⠘⠋"]
+
+# Greek letters (with dot 5 as prefix)
+
+ - ["\u0392\u03b2", "⠨⠐⠃⠐⠃"]
+ - ["\u0393\u03b3", "⠨⠐⠛⠐⠛"]
+ - ["\u0397\u03b7", "⠨⠐⠱⠐⠱"]
+ - ["\u0398\u03b8", "⠨⠐⠹⠐⠹"]
+ - ["\u039a\u03ba", "⠨⠐⠅⠐⠅"]
+ - ["\u039b\u03bb", "⠨⠐⠇⠐⠇"]
+ - ["\u039e\u03be", "⠨⠐⠭⠐⠭"]
+ - ["\u03a0\u03c0", "⠨⠐⠏⠐⠏"]
+ - ["\u03a1\u03c1", "⠨⠐⠗⠐⠗"]
+ - ["\u03a6\u03c6", "⠨⠐⠋⠐⠋"]
+ - ["\u03a7\u03c7", "⠨⠐⠓⠐⠓"]
+ - ["\u03a9\u03c9", "⠨⠐⠺⠐⠺"]
+
+# Arrows (only a few in 6 dots)
+
+ - ["\u2190", "⠘⠺"]
+ - ["\u2191", "⠘⠷"]
+ - ["\u2193", "⠘⠟"]
+
+# Pangram
+
+ - - "Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Walther spillede på xylofon."
+ - "⠨⠠⠟⠥⠊⠠⠵⠙⠑⠇⠞⠁⠛⠑⠗⠝⠑ ⠎⠏⠊⠎⠞⠑ ⠚⠕⠗⠙⠃⠜⠗ ⠍ ⠋⠇⠪⠙⠑⠂ ⠍⠑⠝⠎ ⠉⠊⠗⠅⠥⠎⠅⠇⠕⠧⠝⠑⠝ ⠨⠠⠺⠁⠇⠞⠓⠑⠗ ⠎⠏⠊⠇⠇⠑⠙⠑ ⠏ ⠠⠭⠽⠇⠕⠋⠕⠝⠄"
+
+# Caps and mixed case
+
+ - ["Foobar", "⠨⠋⠕⠕⠃⠁⠗"]
+ - ["FOOBAR", "⠸⠋⠕⠕⠃⠁⠗"]
+ - ["FOObar", "⠸⠋⠕⠕⠠⠃⠁⠗"]
+ - ["FOO-barfOObar", "⠸⠋⠕⠕⠤⠃⠁⠗⠋⠸⠕⠕⠠⠃⠁⠗"]
+
+# Percent and permille
+
+ - ["1%", "⠼⠁ ⠚⠴"]
+
+# Times vs. bullit
+
+ - ["\u2022Bullit", "⠘⠄⠨⠃⠥⠇⠇⠊⠞"]
+# - ["2 \u00d7 2 = 4", "⠼⠃ ⠘⠄ ⠼⠃ ⠘⠶ ⠼⠙"]
+
+# Section sign
+
+ - ["§ 3", "⠬⠼⠉"]
+ - ["§ 3:", "⠬⠼⠉⠒"]
+
+# Numbers and punctuation
+
+ - ["1,2", "⠼⠁⠂⠃"]
+ - ["123.456", "⠼⠁⠃⠉⠄⠙⠑⠋"]
+ - ["3-4", "⠼⠉⠤⠼⠙"]
+ - ["56-", "⠼⠑⠋⠤"]
+ - ["1/2", "⠼⠁⠌⠃"]
+ - ["12:34", "⠼⠁⠃⠒⠉⠙"]
+ - ["2^10", "⠼⠃⠘⠬⠁⠚"]
+# - ["2\u00d72", "⠼⠃⠘⠄⠼⠃"]
+
+ - ["\"quotes\"", "⠶⠠⠟⠥⠕⠞⠑⠎⠶"]
+ - ["-dashes-", "⠤⠙⠁⠎⠓⠑⠎⠤"]
+ - [":-) :-(", "⠒⠤⠠⠴ ⠒⠤⠠⠦"]
+ - [";-) ;-(", "⠆⠤⠠⠴ ⠆⠤⠠⠦"]
+ - ["---", "⠤⠤⠤"]
+ - ["-", "⠤⠤"]
+# - [" -", " ⠤⠤"]
+ - [" a-", " ⠠⠁⠤"]
+ - [" - ", " ⠤⠤ "]
+ - [" -a-", " ⠤⠠⠁⠤"]
+ - [" ", " "]
+ - ["(parentheses)", "⠦⠏⠁⠗⠑⠝⠞⠓⠑⠎⠑⠎⠴"]
+
+# Exclamation
+
+ - ["\u00a1Que lastima!", "⠠⠲⠨⠠⠟⠥⠑ ⠇⠁⠎⠞⠊⠍⠁⠖"]
+
+# Digits and letters
+
+ - ["1a", "⠼⠁⠠⠁"]
+ - ["1.,-a", "⠼⠁⠄⠂⠤⠠⠁"]
+
+# URLs emails and file names
+
+ - ["$at", "⠘⠲⠁⠞"]
+ - ["\u005c\u005cat\u005c\u005cbliver", "⠘⠡⠁⠞⠘⠡⠃⠇⠊⠧⠑⠗"]
+ - ["at@bliver.og", "⠁⠞⠘⠁⠃⠇⠊⠧⠑⠗⠄⠕⠛"]
+ - ["http://at.bliver.og", "⠓⠞⠞⠏⠒⠌⠌⠁⠞⠄⠃⠇⠊⠧⠑⠗⠄⠕⠛"]
+ - ["www.at.bliver.og", "⠠⠺⠠⠺⠠⠺⠄⠁⠞⠄⠃⠇⠊⠧⠑⠗⠄⠕⠛"]
+ - ["www.at.bliver.com", "⠠⠺⠠⠺⠠⠺⠄⠁⠞⠄⠃⠇⠊⠧⠑⠗⠄⠉⠕⠍"]
+ - ["www.a.b.c", "⠠⠺⠠⠺⠠⠺⠄⠠⠁⠄⠠⠃⠄⠠⠉"]
+ - ["test.txt", "⠞⠑⠎⠞⠄⠞⠠⠭⠞"]
+
+# Word contractions
+
+ - ["At", "⠨⠁"]
+ - ["at", "⠁"]
+ - ["Bliver", "⠨⠃"]
+ - ["bliver", "⠃"]
+ - ["Og", "⠨⠉"]
+ - ["og", "⠉"]
+ - ["Du", "⠨⠙"]
+ - ["du", "⠙"]
+ - ["Eller", "⠨⠑"]
+ - ["eller", "⠑"]
+ - ["For", "⠨⠋"]
+ - ["for", "⠋"]
+ - ["Gør", "⠨⠛"]
+ - ["gør", "⠛"]
+ - ["Har", "⠨⠓"]
+ - ["har", "⠓"]
+ - ["Jeg", "⠨⠚"]
+ - ["jeg", "⠚"]
+ - ["Kan", "⠨⠅"]
+ - ["kan", "⠅"]
+ - ["Lige", "⠨⠇"]
+ - ["lige", "⠇"]
+ - ["Med", "⠨⠍"]
+ - ["med", "⠍"]
+ - ["Når", "⠨⠝"]
+ - ["når", "⠝"]
+ - ["Op", "⠨⠕"]
+ - ["op", "⠕"]
+ - ["På", "⠨⠏"]
+ - ["på", "⠏"]
+ - ["Under", "⠨⠟"]
+ - ["under", "⠟"]
+ - ["Rigtig", "⠨⠗"]
+ - ["rigtig", "⠗"]
+ - ["Som", "⠨⠎"]
+ - ["som", "⠎"]
+ - ["Til", "⠨⠞"]
+ - ["til", "⠞"]
+ - ["Hun", "⠨⠥"]
+ - ["hun", "⠥"]
+ - ["Ved", "⠨⠧"]
+ - ["ved", "⠧"]
+ - ["Hvad", "⠨⠺"]
+ - ["hvad", "⠺"]
+ - ["Over", "⠨⠭"]
+ - ["over", "⠭"]
+ - ["Han", "⠨⠽"]
+ - ["han", "⠽"]
+ - ["Efter", "⠨⠵"]
+ - ["efter", "⠵"]
+ - ["Være", "⠨⠜"]
+ - ["være", "⠜"]
+ - ["Før", "⠨⠪"]
+ - ["før", "⠪"]
+ - ["Så", "⠨⠡"]
+ - ["så", "⠡"]
+ - ["Den", "⠨⠯"]
+ - ["den", "⠯"]
+ - ["Der", "⠨⠾"]
+ - ["der", "⠾"]
+ - ["Det", "⠨⠮"]
+ - ["det", "⠮"]
+ - ["De", "⠨⠹"]
+ - ["de", "⠹"]
+ - ["En", "⠨⠣"]
+ - ["en", "⠣"]
+ - ["Er", "⠨⠱"]
+ - ["er", "⠱"]
+ - ["Et", "⠨⠬"]
+ - ["et", "⠬"]
+ - ["Gennem", "⠨⠻"]
+ - ["gennem", "⠻"]
+ - ["Hvor", "⠨⠌"]
+ - ["hvor", "⠌"]
+ - ["Men", "⠨⠩"]
+ - ["men", "⠩"]
+ - ["Ned", "⠨⠫"]
+ - ["ned", "⠫"]
+ - ["Ret", "⠨⠷"]
+ - ["ret", "⠷"]
+ - ["Skal", "⠨⠿"]
+ - ["skal", "⠿"]
+ - ["Te", "⠨⠳"]
+ - ["te", "⠳"]
+ - ["Ve", "⠨⠼"]
+ - ["ve", "⠼"]
+
+# No single cell contractions before or after dashes
+
+ - ["at-bliver", "⠁⠞⠤⠃"]
+ - ["d-d-du", "⠠⠙⠤⠠⠙⠤⠙⠥"]
+
+# Combinations with slashes and other punctuation signs
+
+ - ["Han/hun", "⠨⠽⠌⠥"]
+ - ["han/hun", "⠽⠌⠥"]
+ - ["Over/under", "⠨⠭⠌⠟"]
+ - ["over/under", "⠭⠌⠟"]
+ - ["Til/fra", "⠨⠞⠌⠖"]
+ - ["til/fra", "⠞⠌⠖"]
+
+# Combinations which require letsign
+
+ - ["1st", "⠼⠁⠠⠎⠞"]
+ - ["2nd", "⠼⠃⠠⠝⠙"]
+ - ["1A", "⠼⠁⠨⠠⠁", {xfail: {forward: true}}] # unclear spec
+ - ["1a", "⠼⠁⠠⠁"]
+ - ["2B", "⠼⠃⠨⠠⠃", {xfail: {forward: true}}] # unclear spec
+ - ["2b", "⠼⠃⠠⠃"]
+
+# Multi-pass tests
+
+ - ["~x |z", "⠘⠠⠠⠭ ⠘⠸⠠⠵"]
+ - ["~X |Z", "⠘⠠⠨⠠⠭ ⠘⠸⠨⠠⠵"]
+ - ["5É", "⠼⠑⠨⠐⠑"]
+
+# Characters and constructs which cannot be properly back-translated
+
+flags: {testmode: forward}
+tests:
+ - ["`", "⠈"]
+ - ["‚", "⠈"]
+ - ["„", "⠶"]
+ - ["…", "⠄⠄⠄"]
+ - ["‹", "⠈"]
+ - ["Œ", "⠨⠕⠑"]
+ - ["‘", "⠈"]
+ - ["’", "⠈"]
+ - ["“", "⠶"]
+ - ["”", "⠶"]
+ - ["–", "⠤⠤"]
+ - ["—", "⠤⠤"]
+ - ["˜", "⠘⠠"]
+ - ["›", "⠈"]
+ - ["œ", "⠕⠑"]
+ - ["Ÿ", "⠨⠐⠽"]
+ - ["§", "⠬"]
+ - ["«", "⠶"]
+ - ["±", "⠘⠖⠤"]
+ - ["²", "⠼⠬⠃"]
+ - ["³", "⠼⠬⠉"]
+ - ["´", "⠈"]
+ - ["¹", "⠼⠬⠁"]
+ - ["»", "⠶"]
+ - ["¼", "⠼⠁⠌⠙"]
+ - ["½", "⠼⠁⠌⠃"]
+ - ["¾", "⠼⠉⠌⠙"]
+ - ["Á", "⠨⠐⠁"]
+ - ["Â", "⠨⠐⠁"]
+ - ["Ã", "⠨⠐⠁"]
+ - ["Ä", "⠨⠠⠜"]
+ - ["È", "⠨⠐⠑"]
+ - ["Ê", "⠨⠐⠑"]
+ - ["Ë", "⠨⠐⠑"]
+ - ["Ì", "⠨⠐⠊"]
+ - ["Í", "⠨⠐⠊"]
+ - ["Ï", "⠨⠐⠊"]
+ - ["Ò", "⠨⠐⠕"]
+ - ["Ó", "⠨⠐⠕"]
+ - ["Õ", "⠨⠐⠕"]
+ - ["Ö", "⠨⠠⠪"]
+ - ["×", "⠘⠄"]
+ - ["Ù", "⠨⠐⠥"]
+ - ["Ú", "⠨⠐⠥"]
+ - ["ß", "⠎⠎"]
+ - ["á", "⠐⠁"]
+ - ["â", "⠐⠁"]
+ - ["ã", "⠐⠁"]
+ - ["ä", "⠠⠜"]
+ - ["è", "⠐⠑"]
+ - ["ê", "⠐⠑"]
+ - ["ë", "⠐⠑"]
+ - ["ì", "⠐⠊"]
+ - ["í", "⠐⠊"]
+ - ["ï", "⠐⠊"]
+ - ["ò", "⠐⠕"]
+ - ["ó", "⠐⠕"]
+ - ["õ", "⠐⠕"]
+ - ["ö", "⠠⠪"]
+ - ["÷", "⠘⠲"]
+ - ["ù", "⠐⠥"]
+ - ["ú", "⠐⠥"]
+ - ["ÿ", "⠐⠽"]
+
+# Latin Extended-A
+
+ - ["\u0100\u0101", "⠨⠐⠁⠐⠁"]
+ - ["\u0102\u0103", "⠨⠐⠁⠐⠁"]
+ - ["\u0104\u0105", "⠨⠐⠁⠐⠁"]
+ - ["\u0106\u0107", "⠨⠐⠉⠐⠉"]
+ - ["\u0108\u0109", "⠨⠐⠉⠐⠉"]
+ - ["\u010a\u010b", "⠨⠐⠉⠐⠉"]
+ - ["\u010c\u010d", "⠨⠐⠉⠐⠉"]
+ - ["\u010e\u010f", "⠨⠐⠙⠐⠙"]
+ - ["\u0110\u0111", "⠨⠐⠙⠐⠙"]
+ - ["\u0112\u0113", "⠨⠐⠑⠐⠑"]
+ - ["\u0114\u0115", "⠨⠐⠑⠐⠑"]
+ - ["\u0116\u0117", "⠨⠐⠑⠐⠑"]
+ - ["\u0118\u0119", "⠨⠐⠑⠐⠑"]
+ - ["\u011a\u011b", "⠨⠐⠑⠐⠑"]
+ - ["\u011c\u011d", "⠨⠐⠛⠐⠛"]
+ - ["\u011e\u011f", "⠨⠐⠛⠐⠛"]
+ - ["\u0120\u0121", "⠨⠐⠛⠐⠛"]
+ - ["\u0122\u0123", "⠨⠐⠛⠐⠛"]
+ - ["\u0124\u0125", "⠨⠐⠓⠐⠓"]
+ - ["\u0126\u0127", "⠨⠐⠓⠐⠓"]
+ - ["\u0128\u0129", "⠨⠐⠊⠐⠊"]
+ - ["\u012a\u012b", "⠨⠐⠊⠐⠊"]
+ - ["\u012c\u012d", "⠨⠐⠊⠐⠊"]
+ - ["\u012e\u012f", "⠨⠐⠊⠐⠊"]
+ - ["\u0130\u0131", "⠨⠐⠊⠐⠊"]
+ - ["\u0132\u0133", "⠨⠊⠚⠊⠚"]
+ - ["\u0136\u0137", "⠨⠐⠅⠐⠅"]
+ - ["\u0139\u013a", "⠨⠐⠇⠐⠇"]
+ - ["\u013b\u013c", "⠨⠐⠇⠐⠇"]
+ - ["\u013d\u013e", "⠨⠐⠇⠐⠇"]
+ - ["\u013f\u0140", "⠨⠐⠇⠐⠇"]
+ - ["\u0141\u0142", "⠨⠐⠇⠐⠇"]
+ - ["\u0143\u0144", "⠨⠐⠝⠐⠝"]
+ - ["\u0145\u0146", "⠨⠐⠝⠐⠝"]
+ - ["\u0147\u0148", "⠨⠐⠝⠐⠝"]
+ - ["\u0149", "⠈⠝"]
+ - ["\u014a\u014b", "⠨⠐⠝⠐⠝"]
+ - ["\u014c\u014d", "⠨⠐⠕⠐⠕"]
+ - ["\u014e\u014f", "⠨⠐⠕⠐⠕"]
+ - ["\u0150\u0151", "⠨⠐⠕⠐⠕"]
+ - ["\u0152\u0153", "⠨⠕⠑⠕⠑"]
+ - ["\u0154\u0155", "⠨⠐⠗⠐⠗"]
+ - ["\u0156\u0157", "⠨⠐⠗⠐⠗"]
+ - ["\u0158\u0159", "⠨⠐⠗⠐⠗"]
+ - ["\u015a\u015b", "⠨⠐⠎⠐⠎"]
+ - ["\u015c\u015d", "⠨⠐⠎⠐⠎"]
+ - ["\u015e\u015f", "⠨⠐⠎⠐⠎"]
+ - ["\u0160\u0161", "⠨⠐⠎⠐⠎"]
+ - ["\u0162\u0163", "⠨⠐⠞⠐⠞"]
+ - ["\u0164\u0165", "⠨⠐⠞⠐⠞"]
+ - ["\u0166\u0167", "⠨⠐⠞⠐⠞"]
+ - ["\u0168\u0169", "⠨⠐⠥⠐⠥"]
+ - ["\u016a\u016b", "⠨⠐⠥⠐⠥"]
+ - ["\u016c\u016d", "⠨⠐⠥⠐⠥"]
+ - ["\u016e\u016f", "⠨⠐⠥⠐⠥"]
+ - ["\u0170\u0171", "⠨⠐⠥⠐⠥"]
+ - ["\u0172\u0173", "⠨⠐⠥⠐⠥"]
+ - ["\u0174\u0175", "⠨⠐⠺⠐⠺"]
+ - ["\u0176\u0177", "⠨⠐⠽⠐⠽"]
+ - ["\u0178\u00ff", "⠨⠐⠽⠐⠽"]
+ - ["\u0179\u017a", "⠨⠐⠵⠐⠵"]
+ - ["\u017b\u017c", "⠨⠐⠵⠐⠵"]
+ - ["\u017d\u017e", "⠨⠐⠵⠐⠵"]
+ - ["\u017f", "⠐⠎"]
+
+# Latin Extended-B
+
+ - ["\u02dc", "⠘⠠"]
+
+# Greek letters (with dot 5 as prefix)
+
+ - ["\u0386\u03ac", "⠨⠐⠁⠐⠁"]
+ - ["\u0388\u03ad", "⠨⠐⠑⠐⠑"]
+ - ["\u0389\u03ae", "⠨⠐⠱⠐⠱"]
+ - ["\u038a\u03af", "⠨⠐⠊⠐⠊"]
+ - ["\u038c\u03cc", "⠨⠐⠕⠐⠕"]
+ - ["\u038e\u03cd", "⠨⠐⠥⠐⠥"]
+ - ["\u038f\u03ce", "⠨⠐⠺⠐⠺"]
+ - ["\u0391\u03b1", "⠨⠐⠁⠐⠁"]
+ - ["\u0394\u03b4", "⠨⠐⠙⠐⠙"]
+ - ["\u0395\u03b5", "⠨⠐⠑⠐⠑"]
+ - ["\u0396\u03b6", "⠨⠐⠵⠐⠵"]
+ - ["\u0399\u03b9", "⠨⠐⠊⠐⠊"]
+ - ["\u039c\u03bc", "⠨⠐⠍⠐⠍"]
+ - ["\u039d\u03bd", "⠨⠐⠝⠐⠝"]
+ - ["\u039f\u03bf", "⠨⠐⠕⠐⠕"]
+ - ["\u03a3\u03c3", "⠨⠐⠎⠐⠎"]
+ - ["\u03a4\u03c4", "⠨⠐⠞⠐⠞"]
+ - ["\u03a5\u03c5", "⠨⠐⠥⠐⠥"]
+ - ["\u03a8\u03c8", "⠨⠐⠽⠐⠽"]
+
+# Punctuation and bullits
+
+ - ["\u2000", " "]
+ - ["\u2001", " "]
+ - ["\u2002", " "]
+ - ["\u2003", " "]
+ - ["\u2004", " "]
+ - ["\u2005", " "]
+ - ["\u2006", " "]
+ - ["\u2007", " "]
+ - ["\u2008", " "]
+ - ["\u2009", " "]
+ - ["\u200a", " "]
+ - ["\u2010", "⠤"]
+ - ["\u2011", "⠤"]
+ - ["\u2012", "⠤"]
+ - ["\u2013", "⠤⠤"]
+ - ["\u2014", "⠤⠤"]
+ - ["\u2018", "⠈"]
+ - ["\u2019", "⠈"]
+ - ["\u201a", "⠈"]
+ - ["\u201b", "⠈"]
+ - ["\u201c", "⠶"]
+ - ["\u201d", "⠶"]
+ - ["\u201e", "⠶"]
+ - ["\u201f", "⠶"]
+ - ["\u2023", "⠘⠄"]
+ - ["\u2026", "⠄⠄⠄"]
+ - ["\u202f", " "]
+ - ["\u2030", "⠚⠴⠴"]
+ - ["\u2039", "⠈"]
+ - ["\u203a", "⠈"]
+ - ["\u203c", "⠖⠖"]
+ - ["\u203d", "⠢⠖"]
+ - ["\u2043", "⠘⠄"]
+ - ["\u2047", "⠢⠢"]
+ - ["\u2048", "⠢⠖"]
+ - ["\u2049", "⠖⠢"]
+ - ["\u204c", "⠘⠄"]
+ - ["\u204d", "⠘⠄"]
+ - ["\u20ac", "⠘⠑"]
+ - ["\u2122", "⠘⠞"]
+
+# Arrows (only a few in 6 dots)
+
+ - ["\u2192", "⠘⠗"] # back-translates as "registered".
+
+# Geometrical shapes
+
+ - ["\u25e6", "⠘⠄"]
+
+# Extra digits
+
+ - ["1\u00bc + 1\u00bd = 2\u00be", "⠼⠁⠼⠁⠌⠙ ⠘⠖ ⠼⠁⠼⠁⠌⠃ ⠘⠶ ⠼⠃⠼⠉⠌⠙"]
+
+# Dashes
+
+ - ["\u2014 \u0096 \u0097 \u00ad", "⠤⠤ ⠤⠤ ⠤⠤ ⠤⠤"]
+
+# Quotes
+
+ - ["\u201e \u0084 \u201c \u0093 \u201d \u0094 \u00ab \u00bb", "⠶ ⠶ ⠶ ⠶ ⠶ ⠶ ⠶ ⠶"]
+
+# Apostrophes
+
+ - ["` \u201a \u0082 \u2039 \u008b \u2018 \u0091 \u2019 \u0092 \u203a \u009b \u00b4", "⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈"]
+ - ["J) j) %) ') \u2030) \u0089) \u201a) \u0082) \u2039) \u009b) \u2018) \u0091) \u2019) \u0092) \u203a) \u009b)", "⠨⠠⠚⠠⠴ ⠠⠚⠠⠴ ⠚⠴⠠⠴ ⠈⠠⠴ ⠚⠴⠴⠠⠴ ⠚⠴⠴⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴"]
+
+# Emphasis
+
+ - # Bold line
+ - En linje med fed.
+ - ⠰⠨⠣ ⠇⠊⠝⠚⠑ ⠍ ⠋⠑⠙⠄⠰
+ - typeform:
+ bold: '+++++++++++++++++'
+ - # Bold word
+ - Et ord med fed.
+ - ⠨⠬ ⠰⠕⠗⠙⠰ ⠍ ⠋⠑⠙⠄
+ - typeform:
+ bold: ' +++ '
+ - # Bold letter
+ - Et bogstav med fed.
+ - ⠨⠬ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍ ⠋⠑⠙⠄
+ - typeform:
+ bold: ' + '
+
+ - # Italic line
+ - En linje med kursiv.
+ - ⠰⠨⠣ ⠇⠊⠝⠚⠑ ⠍ ⠅⠥⠗⠎⠊⠧⠄⠰
+ - typeform:
+ italic: '++++++++++++++++++++'
+ - # Italic word
+ - Et ord med kursiv.
+ - ⠨⠬ ⠰⠕⠗⠙⠰ ⠍ ⠅⠥⠗⠎⠊⠧⠄
+ - typeform:
+ italic: ' +++ '
+ - # Italic letter
+ - Et bogstav med kursiv.
+ - ⠨⠬ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍ ⠅⠥⠗⠎⠊⠧⠄
+ - typeform:
+ italic: ' + '
+
+ - # Underlined line
+ - En linje med understreget.
+ - ⠰⠨⠣ ⠇⠊⠝⠚⠑ ⠍ ⠥⠝⠙⠑⠗⠎⠞⠗⠑⠛⠑⠞⠄⠰
+ - typeform:
+ underline: '++++++++++++++++++++++++++'
+ - # Underlined word
+ - Et ord med understreget.
+ - ⠨⠬ ⠰⠕⠗⠙⠰ ⠍ ⠥⠝⠙⠑⠗⠎⠞⠗⠑⠛⠑⠞⠄
+ - typeform:
+ underline: ' +++ '
+ - # Underlined letter
+ - Et bogstav med understreget.
+ - ⠨⠬ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍ ⠥⠝⠙⠑⠗⠎⠞⠗⠑⠛⠑⠞⠄
+ - typeform:
+ underline: ' + '
+
+ - # Bold, italic and underlined line
+ - En linje med alt.
+ - ⠰⠨⠣ ⠇⠊⠝⠚⠑ ⠍ ⠁⠇⠞⠄⠰
+ - typeform:
+ bold: '+++++++++++++++++'
+ italic: '+++++++++++++++++'
+ underline: '+++++++++++++++++'
+ - # Bold, italic and underlined word
+ - Et ord med alt.
+ - ⠨⠬ ⠰⠕⠗⠙⠰ ⠍ ⠁⠇⠞⠄
+ - typeform:
+ bold: ' +++ '
+ italic: ' +++ '
+ underline: ' +++ '
+ - # Bold, italic and underlined letter
+ - Et bogstav med alt.
+ - ⠨⠬ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍ ⠁⠇⠞⠄
+ - typeform:
+ bold: ' + '
+ italic: ' + '
+ underline: ' + '
+
+flags: {testmode: backward}
+tests:
+
+# Characters
+
+ - ["⠄⠄⠄", "..."]
+ - ["⠨⠕⠑", "Oe"]
+ - ["⠕⠑", "oe"]
+ - ["⠘⠖⠤", "±", {xfail: true}]
+ - ["⠼⠁⠌⠙", "1/4"]
+ - ["⠼⠁⠌⠃", "1/2"]
+ - ["⠼⠉⠌⠙", "3/4"]
+
+# Extra digits
+
+ - ["⠼⠁⠼⠁⠌⠙ ⠘⠖ ⠼⠁⠼⠁⠌⠃ ⠘⠶ ⠼⠃⠼⠉⠌⠙", "1\u00bc + 1\u00bd = 2\u00be", {xfail: true}]
+
+# ---------------------------------
+# Grade 1.5 literary (forward only)
+# ---------------------------------
+
+table: {language: da, grade: 1.5, dots: 6, direction: forward, version: 1993, __assert-match: da-dk-g26l-lit_1993.ctb}
+flags: {testmode: forward}
+tests:
+
+# Characters
+
+ - [" ", " "]
+ - ["\"", "⠶"]
+ - ["\u0023", "⠘⠼"]
+ - ["$", "⠘⠲"]
+ - ["%", "⠚⠴"]
+ - ["&", "⠠⠯"]
+ - ["'", "⠈"]
+ - ["(", "⠠⠦"]
+ - [")", "⠠⠴"]
+ - ["*", "⠠⠔"]
+ - ["+", "⠘⠖"]
+ - [",", "⠂"]
+ - ["-", "⠤⠤"]
+ - [".", "⠄"]
+ - ["/", "⠌"]
+ - ["0", "⠼⠚"]
+ - ["1", "⠼⠁"]
+ - ["2", "⠼⠃"]
+ - ["3", "⠼⠉"]
+ - ["4", "⠼⠙"]
+ - ["5", "⠼⠑"]
+ - ["6", "⠼⠋"]
+ - ["7", "⠼⠛"]
+ - ["8", "⠼⠓"]
+ - ["9", "⠼⠊"]
+ - [":", "⠒"]
+ - [";", "⠆"]
+ - ["<", "⠘⠍"]
+ - ["=", "⠘⠶"]
+ - [">", "⠘⠎"]
+ - ["?", "⠢"]
+ - ["@", "⠘⠁"]
+ - ["A", "⠨⠠⠁"]
+ - ["B", "⠨⠠⠃"]
+ - ["C", "⠨⠠⠉"]
+ - ["D", "⠨⠠⠙"]
+ - ["E", "⠨⠠⠑"]
+ - ["F", "⠨⠠⠋"]
+ - ["G", "⠨⠠⠛"]
+ - ["H", "⠨⠠⠓"]
+ - ["I", "⠨⠊"]
+ - ["J", "⠨⠠⠚"]
+ - ["K", "⠨⠠⠅"]
+ - ["L", "⠨⠠⠇"]
+ - ["M", "⠨⠠⠍"]
+ - ["N", "⠨⠠⠝"]
+ - ["O", "⠨⠠⠕"]
+ - ["P", "⠨⠠⠏"]
+ - ["Q", "⠨⠠⠟"]
+ - ["R", "⠨⠠⠗"]
+ - ["S", "⠨⠠⠎"]
+ - ["T", "⠨⠠⠞"]
+ - ["U", "⠨⠠⠥"]
+ - ["V", "⠨⠠⠧"]
+ - ["W", "⠨⠠⠺"]
+ - ["X", "⠨⠠⠭"]
+ - ["Y", "⠨⠠⠽"]
+ - ["Z", "⠨⠠⠵"]
+ - ["[", "⠐⠦"]
+ - ["\u005c\u005c", "⠘⠡"]
+ - ["]", "⠐⠴"]
+ - ["^", "⠘⠬"]
+ - ["_", "⠘⠤"]
+ - ["`", "⠈"]
+ - ["a", "⠠⠁"]
+ - ["b", "⠠⠃"]
+ - ["c", "⠠⠉"]
+ - ["d", "⠠⠙"]
+ - ["e", "⠠⠑"]
+ - ["f", "⠠⠋"]
+ - ["g", "⠠⠛"]
+ - ["h", "⠠⠓"]
+ - ["i", "⠊"]
+ - ["j", "⠠⠚"]
+ - ["k", "⠠⠅"]
+ - ["l", "⠠⠇"]
+ - ["m", "⠠⠍"]
+ - ["n", "⠠⠝"]
+ - ["o", "⠠⠕"]
+ - ["p", "⠠⠏"]
+ - ["q", "⠠⠟"]
+ - ["r", "⠠⠗"]
+ - ["s", "⠠⠎"]
+ - ["t", "⠠⠞"]
+ - ["u", "⠠⠥"]
+ - ["v", "⠠⠧"]
+ - ["w", "⠠⠺"]
+ - ["x", "⠠⠭"]
+ - ["y", "⠠⠽"]
+ - ["z", "⠠⠵"]
+ - ["{", "⠘⠪"]
+ - ["|", "⠘⠸"]
+ - ["}", "⠘⠕"]
+ - ["~", "⠘⠠"]
+ - ["€", "⠘⠑"]
+ - ["‚", "⠈"]
+ - ["ƒ", "⠘⠋"]
+ - ["„", "⠶"]
+ - ["…", "⠄⠄⠄"]
+ - ["‰", "⠚⠴⠴"]
+ - ["Š", "⠨⠐⠎"]
+ - ["‹", "⠈"]
+ - ["Œ", "⠨⠕⠑"]
+ - ["Ž", "⠨⠐⠵"]
+ - ["‘", "⠈"]
+ - ["’", "⠈"]
+ - ["“", "⠶"]
+ - ["”", "⠶"]
+ - ["•", "⠘⠄"]
+ - ["–", "⠤⠤"]
+ - ["—", "⠤⠤"]
+ - ["˜", "⠘⠠"]
+ - ["™", "⠘⠞"]
+ - ["š", "⠐⠎"]
+ - ["›", "⠈"]
+ - ["œ", "⠕⠑"]
+ - ["ž", "⠐⠵"]
+ - ["Ÿ", "⠨⠐⠽"]
+ - ["¡", "⠠⠲"]
+ - ["¢", "⠘⠒"]
+ - ["£", "⠘⠇"]
+ - ["¥", "⠘⠽"]
+ - ["§", "⠬"]
+ - ["©", "⠘⠉"]
+ - ["«", "⠶"]
+ - ["®", "⠘⠗"]
+ - ["°", "⠈⠴"]
+ - ["±", "⠘⠖⠤"]
+ - ["²", "⠼⠬⠃"]
+ - ["³", "⠼⠬⠉"]
+ - ["´", "⠈"]
+ - ["µ", "⠐⠍"]
+ - ["¹", "⠼⠬⠁"]
+ - ["»", "⠶"]
+ - ["¼", "⠼⠁⠌⠙"]
+ - ["½", "⠼⠁⠌⠃"]
+ - ["¾", "⠼⠉⠌⠙"]
+ - ["À", "⠨⠐⠁"]
+ - ["Á", "⠨⠐⠁"]
+ - ["Â", "⠨⠐⠁"]
+ - ["Ã", "⠨⠐⠁"]
+ - ["Ä", "⠨⠠⠜"]
+ - ["Å", "⠨⠠⠡"]
+ - ["Æ", "⠨⠠⠜"]
+ - ["Ç", "⠨⠐⠉"]
+ - ["È", "⠨⠐⠑"]
+ - ["É", "⠨⠐⠑"]
+ - ["Ê", "⠨⠐⠑"]
+ - ["Ë", "⠨⠐⠑"]
+ - ["Ì", "⠨⠐⠊"]
+ - ["Í", "⠨⠐⠊"]
+ - ["Î", "⠨⠐⠊"]
+ - ["Ï", "⠨⠐⠊"]
+ - ["Ð", "⠨⠐⠙"]
+ - ["Ñ", "⠨⠐⠝"]
+ - ["Ò", "⠨⠐⠕"]
+ - ["Ó", "⠨⠐⠕"]
+ - ["Ô", "⠨⠐⠕"]
+ - ["Õ", "⠨⠐⠕"]
+ - ["Ö", "⠨⠠⠪"]
+ - ["×", "⠘⠄"]
+ - ["Ø", "⠨⠠⠪"]
+ - ["Ù", "⠨⠐⠥"]
+ - ["Ú", "⠨⠐⠥"]
+ - ["Û", "⠨⠐⠥"]
+ - ["Ü", "⠨⠠⠳"]
+ - ["Ý", "⠨⠐⠽"]
+ - ["Þ", "⠨⠐⠞"]
+ - ["ß", "⠎⠎"]
+ - ["à", "⠐⠁"]
+ - ["á", "⠐⠁"]
+ - ["â", "⠐⠁"]
+ - ["ã", "⠐⠁"]
+ - ["ä", "⠠⠜"]
+ - ["å", "⠠⠡"]
+ - ["æ", "⠠⠜"]
+ - ["ç", "⠐⠉"]
+ - ["è", "⠐⠑"]
+ - ["é", "⠐⠑"]
+ - ["ê", "⠐⠑"]
+ - ["ë", "⠐⠑"]
+ - ["ì", "⠐⠊"]
+ - ["í", "⠐⠊"]
+ - ["î", "⠐⠊"]
+ - ["ï", "⠐⠊"]
+ - ["ð", "⠐⠙"]
+ - ["ñ", "⠐⠝"]
+ - ["ò", "⠐⠕"]
+ - ["ó", "⠐⠕"]
+ - ["ô", "⠐⠕"]
+ - ["õ", "⠐⠕"]
+ - ["ö", "⠠⠪"]
+ - ["÷", "⠘⠲"]
+ - ["ø", "⠠⠪"]
+ - ["ù", "⠐⠥"]
+ - ["ú", "⠐⠥"]
+ - ["û", "⠐⠥"]
+ - ["ü", "⠠⠳"]
+ - ["ý", "⠐⠽"]
+ - ["þ", "⠐⠞"]
+ - ["ÿ", "⠐⠽"]
+
+# Latin Extended-A
+
+ - ["\u0100\u0101", "⠐⠁⠐⠁"]
+ - ["\u0102\u0103", "⠐⠁⠐⠁"]
+ - ["\u0104\u0105", "⠐⠁⠐⠁"]
+ - ["\u0106\u0107", "⠐⠉⠐⠉"]
+ - ["\u0108\u0109", "⠐⠉⠐⠉"]
+ - ["\u010a\u010b", "⠐⠉⠐⠉"]
+ - ["\u010c\u010d", "⠐⠉⠐⠉"]
+ - ["\u010e\u010f", "⠐⠙⠐⠙"]
+ - ["\u0110\u0111", "⠐⠙⠐⠙"]
+ - ["\u0112\u0113", "⠐⠑⠐⠑"]
+ - ["\u0114\u0115", "⠐⠑⠐⠑"]
+ - ["\u0116\u0117", "⠐⠑⠐⠑"]
+ - ["\u0118\u0119", "⠐⠑⠐⠑"]
+ - ["\u011a\u011b", "⠐⠑⠐⠑"]
+ - ["\u011c\u011d", "⠐⠛⠐⠛"]
+ - ["\u011e\u011f", "⠐⠛⠐⠛"]
+ - ["\u0120\u0121", "⠐⠛⠐⠛"]
+ - ["\u0122\u0123", "⠐⠛⠐⠛"]
+ - ["\u0124\u0125", "⠐⠓⠐⠓"]
+ - ["\u0126\u0127", "⠐⠓⠐⠓"]
+ - ["\u0128\u0129", "⠐⠊⠐⠊"]
+ - ["\u012a\u012b", "⠐⠊⠐⠊"]
+ - ["\u012c\u012d", "⠐⠊⠐⠊"]
+ - ["\u012e\u012f", "⠐⠊⠐⠊"]
+ - ["\u0130\u0131", "⠐⠊⠐⠊"]
+ - ["\u0132\u0133", "⠊⠚⠊⠚"]
+ - ["\u0134\u0135", "⠐⠚⠐⠚"]
+ - ["\u0136\u0137", "⠐⠅⠐⠅"]
+ - ["\u0138", "⠐⠟"]
+ - ["\u0139\u013a", "⠐⠇⠐⠇"]
+ - ["\u013b\u013c", "⠐⠇⠐⠇"]
+ - ["\u013d\u013e", "⠐⠇⠐⠇"]
+ - ["\u013f\u0140", "⠐⠇⠐⠇"]
+ - ["\u0141\u0142", "⠐⠇⠐⠇"]
+ - ["\u0143\u0144", "⠐⠝⠐⠝"]
+ - ["\u0145\u0146", "⠐⠝⠐⠝"]
+ - ["\u0147\u0148", "⠐⠝⠐⠝"]
+ - ["\u0149", "⠈⠝"]
+ - ["\u014a\u014b", "⠐⠝⠐⠝"]
+ - ["\u014c\u014d", "⠐⠕⠐⠕"]
+ - ["\u014e\u014f", "⠐⠕⠐⠕"]
+ - ["\u0150\u0151", "⠐⠕⠐⠕"]
+ - ["\u0152\u0153", "⠕⠑⠕⠑"]
+ - ["\u0154\u0155", "⠐⠗⠐⠗"]
+ - ["\u0156\u0157", "⠐⠗⠐⠗"]
+ - ["\u0158\u0159", "⠐⠗⠐⠗"]
+ - ["\u015a\u015b", "⠐⠎⠐⠎"]
+ - ["\u015c\u015d", "⠐⠎⠐⠎"]
+ - ["\u015e\u015f", "⠐⠎⠐⠎"]
+ - ["\u0160\u0161", "⠐⠎⠐⠎"]
+ - ["\u0162\u0163", "⠐⠞⠐⠞"]
+ - ["\u0164\u0165", "⠐⠞⠐⠞"]
+ - ["\u0166\u0167", "⠐⠞⠐⠞"]
+ - ["\u0168\u0169", "⠐⠥⠐⠥"]
+ - ["\u016a\u016b", "⠐⠥⠐⠥"]
+ - ["\u016c\u016d", "⠐⠥⠐⠥"]
+ - ["\u016e\u016f", "⠐⠥⠐⠥"]
+ - ["\u0170\u0171", "⠐⠥⠐⠥"]
+ - ["\u0172\u0173", "⠐⠥⠐⠥"]
+ - ["\u0174\u0175", "⠐⠺⠐⠺"]
+ - ["\u0176\u0177", "⠐⠽⠐⠽"]
+ - ["\u0178\u00ff", "⠐⠽⠐⠽"]
+ - ["\u0179\u017a", "⠐⠵⠐⠵"]
+ - ["\u017b\u017c", "⠐⠵⠐⠵"]
+ - ["\u017d\u017e", "⠐⠵⠐⠵"]
+ - ["\u017f", "⠐⠎"]
+
+# Latin Extended-B
+
+ - ["\u0192", "⠘⠋"]
+ - ["\u02dc", "⠘⠠"]
+
+# Greek letters (with dot 5 as prefix)
+
+ - ["\u0386\u03ac", "⠐⠁⠐⠁"]
+ - ["\u0388\u03ad", "⠐⠑⠐⠑"]
+ - ["\u0389\u03ae", "⠐⠱⠐⠱"]
+ - ["\u038a\u03af", "⠐⠊⠐⠊"]
+ - ["\u038c\u03cc", "⠐⠕⠐⠕"]
+ - ["\u038e\u03cd", "⠐⠥⠐⠥"]
+ - ["\u038f\u03ce", "⠐⠺⠐⠺"]
+ - ["\u0391\u03b1", "⠐⠁⠐⠁"]
+ - ["\u0392\u03b2", "⠐⠃⠐⠃"]
+ - ["\u0393\u03b3", "⠐⠛⠐⠛"]
+ - ["\u0394\u03b4", "⠐⠙⠐⠙"]
+ - ["\u0395\u03b5", "⠐⠑⠐⠑"]
+ - ["\u0396\u03b6", "⠐⠵⠐⠵"]
+ - ["\u0397\u03b7", "⠐⠱⠐⠱"]
+ - ["\u0398\u03b8", "⠐⠹⠐⠹"]
+ - ["\u0399\u03b9", "⠐⠊⠐⠊"]
+ - ["\u039a\u03ba", "⠐⠅⠐⠅"]
+ - ["\u039b\u03bb", "⠐⠇⠐⠇"]
+ - ["\u039c\u03bc", "⠐⠍⠐⠍"]
+ - ["\u039d\u03bd", "⠐⠝⠐⠝"]
+ - ["\u039e\u03be", "⠐⠭⠐⠭"]
+ - ["\u039f\u03bf", "⠐⠕⠐⠕"]
+ - ["\u03a0\u03c0", "⠐⠏⠐⠏"]
+ - ["\u03a1\u03c1", "⠐⠗⠐⠗"]
+ - ["\u03a3\u03c3", "⠐⠎⠐⠎"]
+ - ["\u03a4\u03c4", "⠐⠞⠐⠞"]
+ - ["\u03a5\u03c5", "⠐⠥⠐⠥"]
+ - ["\u03a6\u03c6", "⠐⠋⠐⠋"]
+ - ["\u03a7\u03c7", "⠐⠓⠐⠓"]
+ - ["\u03a8\u03c8", "⠐⠽⠐⠽"]
+ - ["\u03a9\u03c9", "⠐⠺⠐⠺"]
+
+# Punctuation and bullits
+
+ - ["\u2000", " "]
+ - ["\u2001", " "]
+ - ["\u2002", " "]
+ - ["\u2003", " "]
+ - ["\u2004", " "]
+ - ["\u2005", " "]
+ - ["\u2006", " "]
+ - ["\u2007", " "]
+ - ["\u2008", " "]
+ - ["\u2009", " "]
+ - ["\u200a", " "]
+ - ["\u2010", "⠤"]
+ - ["\u2011", "⠤"]
+ - ["\u2012", "⠤"]
+ - ["\u2013", "⠤⠤"]
+ - ["\u2014", "⠤⠤"]
+ - ["\u2018", "⠈"]
+ - ["\u2019", "⠈"]
+ - ["\u201a", "⠈"]
+ - ["\u201b", "⠈"]
+ - ["\u201c", "⠶"]
+ - ["\u201d", "⠶"]
+ - ["\u201e", "⠶"]
+ - ["\u201f", "⠶"]
+ - ["\u2023", "⠘⠄"]
+ - ["\u2026", "⠄⠄⠄"]
+ - ["\u202f", " "]
+ - ["\u2030", "⠚⠴⠴"]
+ - ["\u2039", "⠈"]
+ - ["\u203a", "⠈"]
+ - ["\u203c", "⠖⠖"]
+ - ["\u203d", "⠢⠖"]
+ - ["\u2043", "⠘⠄"]
+ - ["\u2047", "⠢⠢"]
+ - ["\u2048", "⠢⠖"]
+ - ["\u2049", "⠖⠢"]
+ - ["\u204c", "⠘⠄"]
+ - ["\u204d", "⠘⠄"]
+ - ["\u20ac", "⠘⠑"]
+ - ["\u2122", "⠘⠞"]
+
+# Arrows (only a few in 6 dots)
+
+ - ["\u2190", "⠘⠺"]
+ - ["\u2191", "⠘⠷"]
+ - ["\u2192", "⠘⠗"]
+ - ["\u2193", "⠘⠟"]
+
+# Geometrical shapes
+
+ - ["\u25e6", "⠘⠄"]
+
+# Pangram
+
+ - - "Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Walther spillede på xylofon."
+ - "⠠⠟⠥⠊⠠⠵⠙⠑⠇⠞⠁⠛⠑⠗⠝⠑ ⠎⠏⠊⠎⠞⠑ ⠚⠕⠗⠙⠃⠜⠗ ⠍ ⠋⠇⠪⠙⠑⠂ ⠍⠑⠝⠎ ⠉⠊⠗⠅⠥⠎⠅⠇⠕⠧⠝⠑⠝ ⠠⠺⠁⠇⠞⠓⠑⠗ ⠎⠏⠊⠇⠇⠑⠙⠑ ⠏ ⠠⠭⠽⠇⠕⠋⠕⠝⠄"
+
+# Emphasis
+
+ - # Bold line
+ - En linje med fed.
+ - ⠰⠣ ⠇⠊⠝⠚⠑ ⠍ ⠋⠑⠙⠄⠰
+ - typeform:
+ bold: '+++++++++++++++++'
+ - # Bold word
+ - Et ord med fed.
+ - ⠬ ⠰⠕⠗⠙⠰ ⠍ ⠋⠑⠙⠄
+ - typeform:
+ bold: ' +++ '
+ - # Bold letter
+ - Et bogstav med fed.
+ - ⠬ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍ ⠋⠑⠙⠄
+ - typeform:
+ bold: ' + '
+
+ - # Italic line
+ - En linje med kursiv.
+ - ⠰⠣ ⠇⠊⠝⠚⠑ ⠍ ⠅⠥⠗⠎⠊⠧⠄⠰
+ - typeform:
+ italic: '++++++++++++++++++++'
+ - # Italic word
+ - Et ord med kursiv.
+ - ⠬ ⠰⠕⠗⠙⠰ ⠍ ⠅⠥⠗⠎⠊⠧⠄
+ - typeform:
+ italic: ' +++ '
+ - # Italic letter
+ - Et bogstav med kursiv.
+ - ⠬ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍ ⠅⠥⠗⠎⠊⠧⠄
+ - typeform:
+ italic: ' + '
+
+ - # Underlined line
+ - En linje med understreget.
+ - ⠰⠣ ⠇⠊⠝⠚⠑ ⠍ ⠥⠝⠙⠑⠗⠎⠞⠗⠑⠛⠑⠞⠄⠰
+ - typeform:
+ underline: '++++++++++++++++++++++++++'
+ - # Underlined word
+ - Et ord med understreget.
+ - ⠬ ⠰⠕⠗⠙⠰ ⠍ ⠥⠝⠙⠑⠗⠎⠞⠗⠑⠛⠑⠞⠄
+ - typeform:
+ underline: ' +++ '
+ - # Underlined letter
+ - Et bogstav med understreget.
+ - ⠬ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍ ⠥⠝⠙⠑⠗⠎⠞⠗⠑⠛⠑⠞⠄
+ - typeform:
+ underline: ' + '
+
+ - # Bold, italic and underlined line
+ - En linje med alt.
+ - ⠰⠣ ⠇⠊⠝⠚⠑ ⠍ ⠁⠇⠞⠄⠰
+ - typeform:
+ bold: '+++++++++++++++++'
+ italic: '+++++++++++++++++'
+ underline: '+++++++++++++++++'
+ - # Bold, italic and underlined word
+ - Et ord med alt.
+ - ⠬ ⠰⠕⠗⠙⠰ ⠍ ⠁⠇⠞⠄
+ - typeform:
+ bold: ' +++ '
+ italic: ' +++ '
+ underline: ' +++ '
+ - # Bold, italic and underlined letter
+ - Et bogstav med alt.
+ - ⠬ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍ ⠁⠇⠞⠄
+ - typeform:
+ bold: ' + '
+ italic: ' + '
+ underline: ' + '
+
+#caps and mixed case
+ - ["Foobar", "⠋⠕⠕⠃⠁⠗"]
+ - ["FOOBAR", "⠸⠋⠕⠕⠃⠁⠗"]
+ - ["FOObar", "⠸⠋⠕⠕⠠⠃⠁⠗"]
+ - ["FOO-barfOObar", "⠸⠋⠕⠕⠤⠃⠁⠗⠋⠸⠕⠕⠠⠃⠁⠗"]
+
+# Percent and permille
+ - ["1%", "⠼⠁ ⠚⠴"]
+
+# Extra digits
+ - ["1\u00bc + 1\u00bd = 2\u00be", "⠼⠁⠼⠁⠌⠙ ⠖⠼⠁⠼⠁⠌⠃ ⠶⠼⠃⠼⠉⠌⠙"]
+
+# Dashes
+ - ["\u2014 \u0096 \u0097 \u00ad", "⠤⠤ ⠤⠤ ⠤⠤ ⠤⠤"]
+
+# Quotes
+ - ["\u201e \u0084 \u201c \u0093 \u201d \u0094 \u00ab \u00bb", "⠶ ⠶ ⠶ ⠶ ⠶ ⠶ ⠶ ⠶"]
+
+# Apostrophes
+ - ["` \u201a \u0082 \u2039 \u008b \u2018 \u0091 \u2019 \u0092 \u203a \u009b \u00b4", "⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈"]
+
+#Times vs. bullit
+ - ["\u2022Bullit", "⠘⠄⠃⠥⠇⠇⠊⠞"]
+ - ["2 \u00d7 2 = 4", "⠼⠃ ⠄⠼⠃ ⠶⠼⠙"]
+
+# Section sign
+ - ["§ 3", "⠬⠼⠉"]
+ - ["§ 3:", "⠬⠼⠉⠒"]
+
+# numbers and punctuation
+ - ["1,2", "⠼⠁⠂⠃"]
+ - ["123.456", "⠼⠁⠃⠉⠄⠙⠑⠋"]
+ - ["3-4", "⠼⠉⠤⠼⠙"]
+ - ["56-", "⠼⠑⠋⠤"]
+ - ["1/2", "⠼⠁⠌⠃"]
+ - ["12:34", "⠼⠁⠃⠒⠉⠙"]
+ - ["2^10", "⠼⠃⠘⠬⠁⠚"]
+ - ["2\u00d72", "⠼⠃⠘⠄⠼⠃"]
+
+ - ["\"quotes\"", "⠶⠠⠟⠥⠕⠞⠑⠎⠶"]
+ - ["-dashes-", "⠤⠙⠁⠎⠓⠑⠎⠤"]
+ - [":-) :-(", "⠒⠤⠠⠴ ⠒⠤⠠⠦"]
+ - [";-) ;-(", "⠆⠤⠠⠴ ⠆⠤⠠⠦"]
+ - ["---", "⠤⠤⠤"]
+ - ["-", "⠤⠤"]
+ - [" -", " ⠤⠤"]
+ - [" a-", " ⠠⠁⠤"]
+ - [" - ", " ⠤⠤ "]
+ - [" -a-", " ⠤⠠⠁⠤"]
+ - [" ", " "]
+ - ["(parentheses)", "⠦⠏⠁⠗⠑⠝⠞⠓⠑⠎⠑⠎⠴"]
+ - ["J) j) %) ') \u2030) \u0089) \u201a) \u0082) \u2039) \u009b) \u2018) \u0091) \u2019) \u0092) \u203a) \u009b)", "⠨⠠⠚⠠⠴ ⠠⠚⠠⠴ ⠚⠴⠠⠴ ⠈⠠⠴ ⠚⠴⠴⠠⠴ ⠚⠴⠴⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴"]
+
+ # Exclamation
+ - ["\u00a1Que lastima!", "⠠⠲⠠⠟⠥⠑ ⠇⠁⠎⠞⠊⠍⠁⠖"]
+
+# digits and letters
+ - ["1a", "⠼⠁⠠⠁"]
+ - ["1.,-a", "⠼⠁⠄⠂⠤⠠⠁"]
+
+# URLs emails and file names
+
+ - ["$at", "⠘⠲⠁⠞"]
+ - ["\u005c\u005cat\u005c\u005cbliver", "⠘⠡⠁⠞⠘⠡⠃⠇⠊⠧⠑⠗"]
+ - ["at@bliver.og", "⠁⠞⠘⠁⠃⠇⠊⠧⠑⠗⠄⠕⠛"]
+ - ["http://at.bliver.og", "⠓⠞⠞⠏⠒⠌⠌⠁⠞⠄⠃⠇⠊⠧⠑⠗⠄⠕⠛"]
+ - ["www.at.bliver.og", "⠠⠺⠠⠺⠠⠺⠄⠁⠞⠄⠃⠇⠊⠧⠑⠗⠄⠕⠛"]
+ - ["www.at.bliver.com", "⠠⠺⠠⠺⠠⠺⠄⠁⠞⠄⠃⠇⠊⠧⠑⠗⠄⠉⠕⠍"]
+ - ["www.a.b.c", "⠠⠺⠠⠺⠠⠺⠄⠠⠁⠄⠠⠃⠄⠠⠉"]
+ - ["test.txt", "⠞⠑⠎⠞⠄⠞⠠⠭⠞"]
+
+# word contractions
+
+ - ["At", "⠁"]
+ - ["at", "⠁"]
+ - ["Bliver", "⠃"]
+ - ["bliver", "⠃"]
+ - ["Og", "⠉"]
+ - ["og", "⠉"]
+ - ["Du", "⠙"]
+ - ["du", "⠙"]
+ - ["Eller", "⠑"]
+ - ["eller", "⠑"]
+ - ["For", "⠋"]
+ - ["for", "⠋"]
+ - ["Gør", "⠛"]
+ - ["gør", "⠛"]
+ - ["Har", "⠓"]
+ - ["har", "⠓"]
+ - ["Jeg", "⠚"]
+ - ["jeg", "⠚"]
+ - ["Kan", "⠅"]
+ - ["kan", "⠅"]
+ - ["Lige", "⠇"]
+ - ["lige", "⠇"]
+ - ["Med", "⠍"]
+ - ["med", "⠍"]
+ - ["Når", "⠝"]
+ - ["når", "⠝"]
+ - ["Op", "⠕"]
+ - ["op", "⠕"]
+ - ["På", "⠏"]
+ - ["på", "⠏"]
+ - ["Under", "⠟"]
+ - ["under", "⠟"]
+ - ["Rigtig", "⠗"]
+ - ["rigtig", "⠗"]
+ - ["Som", "⠎"]
+ - ["som", "⠎"]
+ - ["Til", "⠞"]
+ - ["til", "⠞"]
+ - ["Hun", "⠥"]
+ - ["hun", "⠥"]
+ - ["Ved", "⠧"]
+ - ["ved", "⠧"]
+ - ["Hvad", "⠺"]
+ - ["hvad", "⠺"]
+ - ["Over", "⠭"]
+ - ["over", "⠭"]
+ - ["Han", "⠽"]
+ - ["han", "⠽"]
+ - ["Efter", "⠵"]
+ - ["efter", "⠵"]
+ - ["Være", "⠜"]
+ - ["være", "⠜"]
+ - ["Før", "⠪"]
+ - ["før", "⠪"]
+ - ["Så", "⠡"]
+ - ["så", "⠡"]
+ - ["Den", "⠯"]
+ - ["den", "⠯"]
+ - ["Der", "⠾"]
+ - ["der", "⠾"]
+ - ["Det", "⠮"]
+ - ["det", "⠮"]
+ - ["De", "⠹"]
+ - ["de", "⠹"]
+ - ["En", "⠣"]
+ - ["en", "⠣"]
+ - ["Er", "⠱"]
+ - ["er", "⠱"]
+ - ["Et", "⠬"]
+ - ["et", "⠬"]
+ - ["Gennem", "⠻"]
+ - ["gennem", "⠻"]
+ - ["Hvor", "⠌"]
+ - ["hvor", "⠌"]
+ - ["Men", "⠩"]
+ - ["men", "⠩"]
+ - ["Ned", "⠫"]
+ - ["ned", "⠫"]
+ - ["Ret", "⠷"]
+ - ["ret", "⠷"]
+ - ["Skal", "⠿"]
+ - ["skal", "⠿"]
+ - ["Te", "⠳"]
+ - ["te", "⠳"]
+ - ["Ve", "⠼"]
+ - ["ve", "⠼"]
+
+# No single cell contractions before or after dashes
+
+ - ["at-bliver", "⠁⠞⠤⠃"]
+ - ["d-d-du", "⠠⠙⠤⠠⠙⠤⠙⠥"]
+
+# combinations with slashes and other punctuation signs
+
+ - ["at!", "⠁⠖"]
+ - ["bliver!", "⠃⠖"]
+ - ["og!", "⠉⠖"]
+ - ["Han/hun", "⠽⠌⠥"]
+ - ["han/hun", "⠽⠌⠥"]
+ - ["Over/under", "⠭⠌⠟"]
+ - ["over/under", "⠭⠌⠟"]
+ - ["Til/fra", "⠞⠌⠖"]
+ - ["til/fra", "⠞⠌⠖"]
+
+# Combinations which require letsign
+
+ - ["1st", "⠼⠁⠠⠎⠞"]
+ - ["2nd", "⠼⠃⠠⠝⠙"]
+ - ["1A", "⠼⠁⠨⠠⠁", {xfail: true}] # unclear spec
+ - ["1a", "⠼⠁⠠⠁"]
+ - ["2B", "⠼⠃⠨⠠⠃", {xfail: true}] # unclear spec
+ - ["2b", "⠼⠃⠠⠃"]
+
+# Multi-pass tests
+ - ["~x |z", "⠘⠠⠠⠭ ⠘⠸⠠⠵"]
+ - ["~X |Z", "⠘⠠⠨⠠⠭ ⠘⠸⠨⠠⠵"]
+ - ["5É", "⠼⠑⠨⠐⠑"]
+
+# -----------------
+# Grade 2 (regular)
+# -----------------
+
+# Round trip tests
+# Commented tests currently fail backwards but should be fixed.
+
+table: {language: da, grade: 2, dots: 6, direction: both, version: 1993, __assert-match: da-dk-g26_1993.ctb}
+flags: {testmode: bothDirections}
+tests:
+
+# Characters
+
+ - [" ", " "]
+ - ["\"", "⠶"]
+ - ["\u0023", "⠘⠼"]
+ - ["$", "⠘⠲"]
+ - ["%", "⠚⠴"]
+ - ["&", "⠠⠯"]
+ - ["'", "⠈"]
+ - ["(", "⠠⠦"]
+ - [")", "⠠⠴"]
+ - ["*", "⠠⠔"]
+ - ["+", "⠘⠖"]
+ - [",", "⠂"]
+ - ["-", "⠤⠤"]
+ - [".", "⠄"]
+ - ["/", "⠠⠌", {xfail: {forward: true}}]
+ - ["0", "⠼⠚"]
+ - ["1", "⠼⠁"]
+ - ["2", "⠼⠃"]
+ - ["3", "⠼⠉"]
+ - ["4", "⠼⠙"]
+ - ["5", "⠼⠑"]
+ - ["6", "⠼⠋"]
+ - ["7", "⠼⠛"]
+ - ["8", "⠼⠓"]
+ - ["9", "⠼⠊"]
+ - [":", "⠒"]
+ - [";", "⠆"]
+ - ["<", "⠘⠍"]
+ - ["=", "⠘⠶"]
+ - [">", "⠘⠎"]
+ - ["?", "⠢"]
+ - ["@", "⠘⠁"]
+ - ["A", "⠨⠠⠁"]
+ - ["B", "⠨⠠⠃"]
+ - ["C", "⠨⠠⠉"]
+ - ["D", "⠨⠠⠙"]
+ - ["E", "⠨⠠⠑"]
+ - ["F", "⠨⠠⠋"]
+ - ["G", "⠨⠠⠛"]
+ - ["H", "⠨⠠⠓"]
+ - ["I", "⠨⠊"]
+ - ["J", "⠨⠠⠚"]
+ - ["K", "⠨⠠⠅"]
+ - ["L", "⠨⠠⠇"]
+ - ["M", "⠨⠠⠍"]
+ - ["N", "⠨⠠⠝"]
+ - ["O", "⠨⠠⠕"]
+ - ["P", "⠨⠠⠏"]
+ - ["Q", "⠨⠠⠟"]
+ - ["R", "⠨⠠⠗"]
+ - ["S", "⠨⠠⠎"]
+ - ["T", "⠨⠠⠞"]
+ - ["U", "⠨⠠⠥"]
+ - ["V", "⠨⠠⠧"]
+ - ["W", "⠨⠠⠺"]
+ - ["X", "⠨⠠⠭"]
+ - ["Y", "⠨⠠⠽"]
+ - ["Z", "⠨⠠⠵"]
+ - ["[", "⠐⠦"]
+ - ["\u005c\u005c", "⠘⠡"]
+ - ["]", "⠐⠴"]
+ - ["^", "⠘⠬"]
+ - ["_", "⠘⠤"]
+ - ["a", "⠠⠁"]
+ - ["b", "⠠⠃"]
+ - ["c", "⠠⠉"]
+ - ["d", "⠠⠙"]
+ - ["e", "⠠⠑"]
+ - ["f", "⠠⠋"]
+ - ["g", "⠠⠛"]
+ - ["h", "⠠⠓"]
+ - ["i", "⠊"]
+ - ["j", "⠠⠚"]
+ - ["k", "⠠⠅"]
+ - ["l", "⠠⠇"]
+ - ["m", "⠠⠍"]
+ - ["n", "⠠⠝"]
+ - ["o", "⠠⠕"]
+ - ["p", "⠠⠏"]
+ - ["q", "⠠⠟"]
+ - ["r", "⠠⠗"]
+ - ["s", "⠠⠎"]
+ - ["t", "⠠⠞"]
+ - ["u", "⠠⠥"]
+ - ["v", "⠠⠧"]
+ - ["w", "⠠⠺"]
+ - ["x", "⠠⠭"]
+ - ["y", "⠠⠽"]
+ - ["z", "⠠⠵"]
+ - ["{", "⠘⠪"]
+ - ["|", "⠘⠸"]
+ - ["}", "⠘⠕"]
+ - ["~", "⠘⠠"]
+ - ["€", "⠘⠑"]
+ - ["ƒ", "⠘⠋"]
+ - ["‰", "⠚⠴⠴"]
+ - ["Š", "⠨⠐⠎"]
+ - ["Ž", "⠨⠐⠵"]
+ - ["•", "⠘⠄"]
+ - ["™", "⠘⠞"]
+ - ["š", "⠐⠎"]
+ - ["ž", "⠐⠵"]
+ - ["¡", "⠠⠲"]
+ - ["¢", "⠘⠒"]
+ - ["£", "⠘⠇"]
+ - ["¥", "⠘⠽"]
+ - ["©", "⠘⠉"]
+ - ["®", "⠘⠗"]
+ - ["°", "⠈⠴"]
+ - ["µ", "⠐⠍"]
+ - ["À", "⠨⠐⠁"]
+ - ["Å", "⠨⠠⠡"]
+ - ["Æ", "⠨⠠⠜"]
+ - ["Ç", "⠨⠐⠉"]
+ - ["É", "⠨⠐⠑"]
+ - ["Î", "⠨⠐⠊"]
+ - ["Ð", "⠨⠐⠙"]
+ - ["Ñ", "⠨⠐⠝"]
+ - ["Ô", "⠨⠐⠕"]
+ - ["Ø", "⠨⠠⠪"]
+ - ["Û", "⠨⠐⠥"]
+ - ["Ü", "⠨⠠⠳"]
+ - ["Ý", "⠨⠐⠽"]
+ - ["Þ", "⠨⠐⠞"]
+ - ["à", "⠐⠁"]
+ - ["å", "⠠⠡"]
+ - ["æ", "⠠⠜"]
+ - ["ç", "⠐⠉"]
+ - ["é", "⠐⠑"]
+ - ["î", "⠐⠊"]
+ - ["ð", "⠐⠙"]
+ - ["ñ", "⠐⠝"]
+ - ["ô", "⠐⠕"]
+ - ["ø", "⠠⠪"]
+ - ["û", "⠐⠥"]
+ - ["ü", "⠠⠳"]
+ - ["ý", "⠐⠽"]
+ - ["þ", "⠐⠞"]
+
+# Misc. Unicode (most cannot be back-translated)
+# Some tests may be repetitions of tests above, since
+# some characters can occur both inside and outside the 8 bit range.
+# for accented letters in the range u+0080 - u+00ff: the letters
+# that are thought to occur most frequently in Danish texts are used
+# for back-translation.
+# For all accented letters above u+00ff, the first occurring instance is chosen for back-translation.
+# There are no rules about this in the specs of Danish Braille,
+# So the choice is arbitrary and may change over time.
+
+ - ["\u0134\u0135", "⠨⠐⠚⠐⠚"]
+ - ["\u0138", "⠐⠟"]
+ - ["\u0192", "⠘⠋"]
+
+# Greek letters (with dot 5 as prefix)
+
+ - ["\u0392\u03b2", "⠨⠐⠃⠐⠃"]
+ - ["\u0393\u03b3", "⠨⠐⠛⠐⠛"]
+ - ["\u0397\u03b7", "⠨⠐⠱⠐⠱"]
+ - ["\u0398\u03b8", "⠨⠐⠹⠐⠹"]
+ - ["\u039a\u03ba", "⠨⠐⠅⠐⠅"]
+ - ["\u039b\u03bb", "⠨⠐⠇⠐⠇"]
+ - ["\u039e\u03be", "⠨⠐⠭⠐⠭"]
+ - ["\u03a0\u03c0", "⠨⠐⠏⠐⠏"]
+ - ["\u03a1\u03c1", "⠨⠐⠗⠐⠗"]
+ - ["\u03a6\u03c6", "⠨⠐⠋⠐⠋"]
+ - ["\u03a7\u03c7", "⠨⠐⠓⠐⠓"]
+ - ["\u03a9\u03c9", "⠨⠐⠺⠐⠺"]
+
+# Arrows (only a few in 6 dots)
+
+ - ["\u2190", "⠘⠺"]
+ - ["\u2191", "⠘⠷"]
+ - ["\u2193", "⠘⠟"]
+
+# Pangram
+
+ - - "Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Walther spillede på xylofon."
+ - "⠨⠠⠟⠥⠊⠠⠵⠹⠇⠞⠁⠛⠱⠫ ⠎⠏⠊⠵⠑ ⠚⠭⠙⠃⠜⠗ ⠍ ⠋⠇⠪⠹⠂ ⠍⠣⠎ ⠉⠊⠗⠅⠥⠎⠅⠇⠕⠧⠝⠣ ⠨⠠⠺⠁⠇⠞⠓⠱ ⠎⠏⠊⠇⠇⠑⠹ ⠏ ⠠⠭⠽⠇⠕⠋⠕⠝⠄"
+
+# Caps and mixed case
+
+ - ["Foobar", "⠨⠋⠕⠕⠃⠁⠗"]
+ - ["FOOBAR", "⠸⠋⠕⠕⠃⠁⠗"]
+ - ["FOObar", "⠸⠋⠕⠕⠠⠃⠁⠗"]
+ - ["FOO-barfOObar", "⠸⠋⠕⠕⠤⠃⠁⠗⠋⠸⠕⠕⠠⠃⠁⠗"]
+
+# Percent and permille
+
+ - ["1%", "⠼⠁ ⠚⠴"]
+
+# Times vs. bullit
+
+ - ["\u2022Bullit", "⠘⠄⠨⠃⠥⠇⠇⠊⠞"]
+# - ["2 \u00d7 2 = 4", "⠼⠃ ⠘⠄ ⠼⠃ ⠘⠶ ⠼⠙"]
+
+# Section sign
+
+ - ["§ 3", "⠬⠼⠉"]
+ - ["§ 3:", "⠬⠼⠉⠒"]
+
+# Numbers and punctuation
+
+ - ["1,2", "⠼⠁⠂⠃"]
+ - ["123.456", "⠼⠁⠃⠉⠄⠙⠑⠋"]
+ - ["3-4", "⠼⠉⠤⠼⠙"]
+ - ["56-", "⠼⠑⠋⠤"]
+ - ["1/2", "⠼⠁⠌⠃"]
+ - ["12:34", "⠼⠁⠃⠒⠉⠙"]
+ - ["2^10", "⠼⠃⠘⠬⠁⠚"]
+# - ["2\u00d72", "⠼⠃⠘⠄⠼⠃"]
+
+ - ["\"quotes\"", "⠶⠠⠟⠥⠕⠳⠎⠶"]
+ - ["-dashes-", "⠤⠙⠁⠎⠓⠑⠎⠤"]
+ - [":-) :-(", "⠒⠤⠠⠴ ⠒⠤⠠⠦"]
+ - [";-) ;-(", "⠆⠤⠠⠴ ⠆⠤⠠⠦"]
+ - ["---", "⠤⠤⠤"]
+ - ["-", "⠤⠤"]
+# - [" -", " ⠤⠤"]
+ - [" a-", " ⠠⠁⠤"]
+ - [" - ", " ⠤⠤ "]
+ - [" -a-", " ⠤⠠⠁⠤"]
+ - [" ", " "]
+ - ["(parentheses)", "⠦⠏⠁⠗⠣⠞⠓⠑⠎⠑⠎⠴"]
+
+# Exclamation
+
+ - ["\u00a1Que lastima!", "⠠⠲⠨⠠⠟⠥⠑ ⠇⠁⠵⠊⠍⠁⠖"]
+
+# Digits and letters
+
+ - ["1a", "⠼⠁⠠⠁"]
+ - ["1.,-a", "⠼⠁⠄⠂⠤⠠⠁"]
+
+# URLs emails and file names
+
+ - ["$at", "⠘⠲⠁⠞"]
+ - ["\u005c\u005cat\u005c\u005cbliver", "⠘⠡⠁⠞⠘⠡⠃⠇⠊⠧⠑⠗"]
+ - ["at@bliver.og", "⠁⠞⠘⠁⠃⠇⠊⠧⠑⠗⠄⠕⠛"]
+ - ["http://at.bliver.og", "⠓⠞⠞⠏⠒⠌⠌⠁⠞⠄⠃⠇⠊⠧⠑⠗⠄⠕⠛"]
+ - ["www.at.bliver.og", "⠠⠺⠠⠺⠠⠺⠄⠁⠞⠄⠃⠇⠊⠧⠑⠗⠄⠕⠛"]
+ - ["www.at.bliver.com", "⠠⠺⠠⠺⠠⠺⠄⠁⠞⠄⠃⠇⠊⠧⠑⠗⠄⠉⠕⠍"]
+ - ["www.a.b.c", "⠠⠺⠠⠺⠠⠺⠄⠠⠁⠄⠠⠃⠄⠠⠉"]
+ - ["test.txt", "⠳⠵⠄⠞⠠⠭⠞"]
+
+# Word contractions
+
+ - ["At", "⠨⠁"]
+ - ["at", "⠁"]
+ - ["Aldrig", "⠨⠁⠔"]
+ - ["aldrig", "⠁⠔"]
+ - ["aig", "⠁⠊⠛"]
+ - ["Alle", "⠨⠁⠑"]
+ - ["alle", "⠁⠑"]
+ - ["ae", "⠠⠁⠑"]
+ - ["Allerede", "⠨⠁⠇⠗"]
+ - ["allerede", "⠁⠇⠗"]
+ - ["alr", "⠠⠁⠇⠗"]
+ - ["Alligevel", "⠨⠁⠇⠧"]
+ - ["alligevel", "⠁⠇⠧"]
+ - ["alv", "⠠⠁⠇⠧"]
+ - ["Altid", "⠨⠁⠞⠙"]
+ - ["altid", "⠁⠞⠙"]
+ - ["atd", "⠠⠁⠞⠙"]
+ - ["Altså", "⠨⠁⠡"]
+ - ["altså", "⠁⠡"]
+ - ["aå", "⠠⠁⠡"]
+ - ["Bliver", "⠨⠃"]
+ - ["bliver", "⠃"]
+ - ["Og", "⠨⠉"]
+ - ["og", "⠉"]
+ - ["Deres", "⠨⠲"]
+ - ["deres", "⠲"]
+ - ["Du", "⠨⠙"]
+ - ["du", "⠙"]
+ - ["Eller", "⠨⠑"]
+ - ["eller", "⠑"]
+ - ["For", "⠨⠋"]
+ - ["for", "⠋"]
+ - ["Gør", "⠨⠛"]
+ - ["gør", "⠛"]
+ - ["Har", "⠨⠓"]
+ - ["har", "⠓"]
+ - ["Jeg", "⠨⠚"]
+ - ["jeg", "⠚"]
+ - ["Kan", "⠨⠅"]
+ - ["kan", "⠅"]
+ - ["Lige", "⠨⠇"]
+ - ["lige", "⠇"]
+ - ["Med", "⠨⠍"]
+ - ["med", "⠍"]
+ - ["Når", "⠨⠝"]
+ - ["når", "⠝"]
+ - ["Op", "⠨⠕"]
+ - ["op", "⠕"]
+ - ["På", "⠨⠏"]
+ - ["på", "⠏"]
+ - ["Under", "⠨⠟"]
+ - ["under", "⠟"]
+ - ["Rigtig", "⠨⠗"]
+ - ["rigtig", "⠗"]
+ - ["Som", "⠨⠎"]
+ - ["som", "⠎"]
+ - ["Til", "⠨⠞"]
+ - ["til", "⠞"]
+ - ["Hun", "⠨⠥"]
+ - ["hun", "⠥"]
+ - ["Ved", "⠨⠧"]
+ - ["ved", "⠧"]
+ - ["Hvad", "⠨⠺"]
+ - ["hvad", "⠺"]
+ - ["Over", "⠨⠭"]
+ - ["over", "⠭"]
+ - ["Han", "⠨⠽"]
+ - ["han", "⠽"]
+ - ["Efter", "⠨⠵"]
+ - ["efter", "⠵"]
+ - ["Være", "⠨⠜"]
+ - ["være", "⠜"]
+ - ["Før", "⠨⠪"]
+ - ["før", "⠪"]
+ - ["Så", "⠨⠡"]
+ - ["så", "⠡"]
+ - ["Den", "⠨⠯"]
+ - ["den", "⠯"]
+ - ["Der", "⠨⠾"]
+ - ["der", "⠾"]
+ - ["Det", "⠨⠮"]
+ - ["det", "⠮"]
+ - ["De", "⠨⠹"]
+ - ["de", "⠹"]
+ - ["En", "⠨⠣"]
+ - ["en", "⠣"]
+ - ["Er", "⠨⠱"]
+ - ["er", "⠱"]
+ - ["Et", "⠨⠬"]
+ - ["et", "⠬"]
+ - ["Gennem", "⠨⠻"]
+ - ["gennem", "⠻"]
+ - ["Hvor", "⠨⠌"]
+ - ["hvor", "⠌"]
+ - ["Men", "⠨⠩"]
+ - ["men", "⠩"]
+ - ["Ned", "⠨⠫"]
+ - ["ned", "⠫"]
+ - ["Ret", "⠨⠷"]
+ - ["ret", "⠷"]
+ - ["Skal", "⠨⠿"]
+ - ["skal", "⠿"]
+ - ["Te", "⠨⠳"]
+ - ["te", "⠳"]
+ - ["Ve", "⠨⠼"]
+ - ["ve", "⠼"]
+
+# Partword/nocross
+
+ - ["Denne", "⠨⠯⠫"]
+ - ["denne", "⠯⠫"]
+ - ["Mændene", "⠨⠍⠜⠝⠹⠫"]
+ - ["mændene", "⠍⠜⠝⠹⠫"]
+ - ["Derhos", "⠨⠾⠓⠕⠎"]
+ - ["derhos", "⠾⠓⠕⠎"]
+ - ["Hunderace", "⠨⠓⠥⠝⠹⠗⠁⠉⠑"]
+ - ["hunderace", "⠓⠥⠝⠹⠗⠁⠉⠑"]
+ - ["Dette", "⠨⠮⠳"]
+ - ["dette", "⠮⠳"]
+ - ["Detalje", "⠨⠹⠞⠁⠇⠚⠑"]
+ - ["detalje", "⠹⠞⠁⠇⠚⠑"]
+
+# Nocross multiple cells
+
+ - ["Endda", "⠨⠑⠟⠙⠁"]
+ - ["endda", "⠑⠟⠙⠁"]
+ - ["Morgendag", "⠨⠍⠭⠛⠣⠙⠁⠛"]
+ - ["morgendag", "⠍⠭⠛⠣⠙⠁⠛"]
+ - ["Gendanne", "⠨⠛⠣⠙⠁⠝⠫"]
+ - ["gendanne", "⠛⠣⠙⠁⠝⠫"]
+ - ["Generelt", "⠨⠻⠫⠷⠇⠞"]
+ - ["generelt", "⠻⠫⠷⠇⠞"]
+
+ - ["Fra!", "⠨⠋⠗⠁⠖"]
+ - ["fra!", "⠋⠗⠁⠖"]
+ - ["!Fra", "⠠⠖⠨⠖"]
+ - ["!fra", "⠖⠋⠗⠁"]
+ - ["'Af", "⠈⠨⠴"]
+ - ["'af", "⠈⠁⠋"]
+
+# No single cell contractions before or after dashes
+
+ - ["at-bliver", "⠁⠞⠤⠃"]
+ - ["d-d-du", "⠠⠙⠤⠠⠙⠤⠙⠥"]
+
+# Combinations with slashes and other punctuation signs
+
+ - ["at!", "⠁⠖"]
+ - ["bliver!", "⠃⠖"]
+ - ["og!", "⠉⠖"]
+ - ["Han/hun", "⠨⠽⠌⠥"]
+ - ["han/hun", "⠽⠌⠥"]
+ - ["Over/under", "⠨⠭⠌⠟"]
+ - ["over/under", "⠭⠌⠟"]
+ - ["Til/fra", "⠨⠞⠌⠖"]
+ - ["til/fra", "⠞⠌⠖"]
+
+# Combinations which require letsign
+
+ - ["1st", "⠼⠁⠠⠎⠞"]
+ - ["2nd", "⠼⠃⠠⠝⠙"]
+ - ["1A", "⠼⠁⠨⠠⠁", {xfail: {forward: true}}] # unclear spec
+ - ["1a", "⠼⠁⠠⠁"]
+ - ["2B", "⠼⠃⠨⠠⠃", {xfail: {forward: true}}] # unclear spec
+ - ["2b", "⠼⠃⠠⠃"]
+
+# Multi-pass tests
+
+ - ["~x |z", "⠘⠠⠠⠭ ⠘⠸⠠⠵"]
+ - ["~X |Z", "⠘⠠⠨⠠⠭ ⠘⠸⠨⠠⠵"]
+ - ["5É", "⠼⠑⠨⠐⠑"]
+
+# Characters and constructs which cannot be properly back-translated
+
+flags: {testmode: forward}
+tests:
+
+ - ["`", "⠈"]
+ - ["‚", "⠈"]
+ - ["„", "⠶"]
+ - ["…", "⠄⠄⠄"]
+ - ["‹", "⠈"]
+ - ["‘", "⠈"]
+ - ["’", "⠈"]
+ - ["“", "⠶"]
+ - ["”", "⠶"]
+ - ["Œ", "⠨⠕⠑"]
+ - ["–", "⠤⠤"]
+ - ["—", "⠤⠤"]
+ - ["˜", "⠘⠠"]
+ - ["›", "⠈"]
+ - ["œ", "⠕⠑"]
+ - ["Ÿ", "⠨⠐⠽"]
+ - ["§", "⠬"]
+ - ["«", "⠶"]
+ - ["±", "⠘⠖⠤"]
+ - ["²", "⠼⠬⠃"]
+ - ["³", "⠼⠬⠉"]
+ - ["´", "⠈"]
+ - ["¹", "⠼⠬⠁"]
+ - ["»", "⠶"]
+ - ["¼", "⠼⠁⠌⠙"]
+ - ["½", "⠼⠁⠌⠃"]
+ - ["¾", "⠼⠉⠌⠙"]
+ - ["Á", "⠨⠐⠁"]
+ - ["Â", "⠨⠐⠁"]
+ - ["Ã", "⠨⠐⠁"]
+ - ["Ä", "⠨⠠⠜"]
+ - ["È", "⠨⠐⠑"]
+ - ["Ê", "⠨⠐⠑"]
+ - ["Ë", "⠨⠐⠑"]
+ - ["Ì", "⠨⠐⠊"]
+ - ["Í", "⠨⠐⠊"]
+ - ["Ï", "⠨⠐⠊"]
+ - ["Ò", "⠨⠐⠕"]
+ - ["Ó", "⠨⠐⠕"]
+ - ["Õ", "⠨⠐⠕"]
+ - ["Ö", "⠨⠠⠪"]
+ - ["×", "⠘⠄"]
+ - ["Ù", "⠨⠐⠥"]
+ - ["Ú", "⠨⠐⠥"]
+ - ["ß", "⠎⠎"]
+ - ["á", "⠐⠁"]
+ - ["â", "⠐⠁"]
+ - ["ã", "⠐⠁"]
+ - ["ä", "⠠⠜"]
+ - ["è", "⠐⠑"]
+ - ["ê", "⠐⠑"]
+ - ["ë", "⠐⠑"]
+ - ["ì", "⠐⠊"]
+ - ["í", "⠐⠊"]
+ - ["ï", "⠐⠊"]
+ - ["ò", "⠐⠕"]
+ - ["ó", "⠐⠕"]
+ - ["õ", "⠐⠕"]
+ - ["ö", "⠠⠪"]
+ - ["÷", "⠘⠲"]
+ - ["ù", "⠐⠥"]
+ - ["ú", "⠐⠥"]
+ - ["ÿ", "⠐⠽"]
+
+# Latin Extended-A
+
+ - ["\u0100\u0101", "⠨⠐⠁⠐⠁"]
+ - ["\u0102\u0103", "⠨⠐⠁⠐⠁"]
+ - ["\u0104\u0105", "⠨⠐⠁⠐⠁"]
+ - ["\u0106\u0107", "⠨⠐⠉⠐⠉"]
+ - ["\u0108\u0109", "⠨⠐⠉⠐⠉"]
+ - ["\u010a\u010b", "⠨⠐⠉⠐⠉"]
+ - ["\u010c\u010d", "⠨⠐⠉⠐⠉"]
+ - ["\u010e\u010f", "⠨⠐⠙⠐⠙"]
+ - ["\u0110\u0111", "⠨⠐⠙⠐⠙"]
+ - ["\u0112\u0113", "⠨⠐⠑⠐⠑"]
+ - ["\u0114\u0115", "⠨⠐⠑⠐⠑"]
+ - ["\u0116\u0117", "⠨⠐⠑⠐⠑"]
+ - ["\u0118\u0119", "⠨⠐⠑⠐⠑"]
+ - ["\u011a\u011b", "⠨⠐⠑⠐⠑"]
+ - ["\u011c\u011d", "⠨⠐⠛⠐⠛"]
+ - ["\u011e\u011f", "⠨⠐⠛⠐⠛"]
+ - ["\u0120\u0121", "⠨⠐⠛⠐⠛"]
+ - ["\u0122\u0123", "⠨⠐⠛⠐⠛"]
+ - ["\u0124\u0125", "⠨⠐⠓⠐⠓"]
+ - ["\u0126\u0127", "⠨⠐⠓⠐⠓"]
+ - ["\u0128\u0129", "⠨⠐⠊⠐⠊"]
+ - ["\u012a\u012b", "⠨⠐⠊⠐⠊"]
+ - ["\u012c\u012d", "⠨⠐⠊⠐⠊"]
+ - ["\u012e\u012f", "⠨⠐⠊⠐⠊"]
+ - ["\u0130\u0131", "⠨⠐⠊⠐⠊"]
+ - ["\u0132\u0133", "⠨⠊⠚⠊⠚"]
+ - ["\u0136\u0137", "⠨⠐⠅⠐⠅"]
+ - ["\u0139\u013a", "⠨⠐⠇⠐⠇"]
+ - ["\u013b\u013c", "⠨⠐⠇⠐⠇"]
+ - ["\u013d\u013e", "⠨⠐⠇⠐⠇"]
+ - ["\u013f\u0140", "⠨⠐⠇⠐⠇"]
+ - ["\u0141\u0142", "⠨⠐⠇⠐⠇"]
+ - ["\u0143\u0144", "⠨⠐⠝⠐⠝"]
+ - ["\u0145\u0146", "⠨⠐⠝⠐⠝"]
+ - ["\u0147\u0148", "⠨⠐⠝⠐⠝"]
+ - ["\u0149", "⠈⠝"]
+ - ["\u014a\u014b", "⠨⠐⠝⠐⠝"]
+ - ["\u014c\u014d", "⠨⠐⠕⠐⠕"]
+ - ["\u014e\u014f", "⠨⠐⠕⠐⠕"]
+ - ["\u0150\u0151", "⠨⠐⠕⠐⠕"]
+ - ["\u0152\u0153", "⠨⠕⠑⠕⠑"]
+ - ["\u0154\u0155", "⠨⠐⠗⠐⠗"]
+ - ["\u0156\u0157", "⠨⠐⠗⠐⠗"]
+ - ["\u0158\u0159", "⠨⠐⠗⠐⠗"]
+ - ["\u015a\u015b", "⠨⠐⠎⠐⠎"]
+ - ["\u015c\u015d", "⠨⠐⠎⠐⠎"]
+ - ["\u015e\u015f", "⠨⠐⠎⠐⠎"]
+ - ["\u0160\u0161", "⠨⠐⠎⠐⠎"]
+ - ["\u0162\u0163", "⠨⠐⠞⠐⠞"]
+ - ["\u0164\u0165", "⠨⠐⠞⠐⠞"]
+ - ["\u0166\u0167", "⠨⠐⠞⠐⠞"]
+ - ["\u0168\u0169", "⠨⠐⠥⠐⠥"]
+ - ["\u016a\u016b", "⠨⠐⠥⠐⠥"]
+ - ["\u016c\u016d", "⠨⠐⠥⠐⠥"]
+ - ["\u016e\u016f", "⠨⠐⠥⠐⠥"]
+ - ["\u0170\u0171", "⠨⠐⠥⠐⠥"]
+ - ["\u0172\u0173", "⠨⠐⠥⠐⠥"]
+ - ["\u0174\u0175", "⠨⠐⠺⠐⠺"]
+ - ["\u0176\u0177", "⠨⠐⠽⠐⠽"]
+ - ["\u0178\u00ff", "⠨⠐⠽⠐⠽"]
+ - ["\u0179\u017a", "⠨⠐⠵⠐⠵"]
+ - ["\u017b\u017c", "⠨⠐⠵⠐⠵"]
+ - ["\u017d\u017e", "⠨⠐⠵⠐⠵"]
+ - ["\u017f", "⠐⠎"]
+
+# Latin Extended-B
+
+ - ["\u02dc", "⠘⠠"]
+
+# Greek letters (with dot 5 as prefix)
+
+ - ["\u0386\u03ac", "⠨⠐⠁⠐⠁"]
+ - ["\u0388\u03ad", "⠨⠐⠑⠐⠑"]
+ - ["\u0389\u03ae", "⠨⠐⠱⠐⠱"]
+ - ["\u038a\u03af", "⠨⠐⠊⠐⠊"]
+ - ["\u038c\u03cc", "⠨⠐⠕⠐⠕"]
+ - ["\u038e\u03cd", "⠨⠐⠥⠐⠥"]
+ - ["\u038f\u03ce", "⠨⠐⠺⠐⠺"]
+ - ["\u0391\u03b1", "⠨⠐⠁⠐⠁"]
+ - ["\u0394\u03b4", "⠨⠐⠙⠐⠙"]
+ - ["\u0395\u03b5", "⠨⠐⠑⠐⠑"]
+ - ["\u0396\u03b6", "⠨⠐⠵⠐⠵"]
+ - ["\u0399\u03b9", "⠨⠐⠊⠐⠊"]
+ - ["\u039c\u03bc", "⠨⠐⠍⠐⠍"]
+ - ["\u039d\u03bd", "⠨⠐⠝⠐⠝"]
+ - ["\u039f\u03bf", "⠨⠐⠕⠐⠕"]
+ - ["\u03a3\u03c3", "⠨⠐⠎⠐⠎"]
+ - ["\u03a4\u03c4", "⠨⠐⠞⠐⠞"]
+ - ["\u03a5\u03c5", "⠨⠐⠥⠐⠥"]
+ - ["\u03a8\u03c8", "⠨⠐⠽⠐⠽"]
+
+# Punctuation and bullits
+
+ - ["\u2000", " "]
+ - ["\u2001", " "]
+ - ["\u2002", " "]
+ - ["\u2003", " "]
+ - ["\u2004", " "]
+ - ["\u2005", " "]
+ - ["\u2006", " "]
+ - ["\u2007", " "]
+ - ["\u2008", " "]
+ - ["\u2009", " "]
+ - ["\u200a", " "]
+ - ["\u2010", "⠤"]
+ - ["\u2011", "⠤"]
+ - ["\u2012", "⠤"]
+ - ["\u2013", "⠤⠤"]
+ - ["\u2014", "⠤⠤"]
+ - ["\u2018", "⠈"]
+ - ["\u2019", "⠈"]
+ - ["\u201a", "⠈"]
+ - ["\u201b", "⠈"]
+ - ["\u201c", "⠶"]
+ - ["\u201d", "⠶"]
+ - ["\u201e", "⠶"]
+ - ["\u201f", "⠶"]
+ - ["\u2023", "⠘⠄"]
+ - ["\u2026", "⠄⠄⠄"]
+ - ["\u202f", " "]
+ - ["\u2030", "⠚⠴⠴"]
+ - ["\u2039", "⠈"]
+ - ["\u203a", "⠈"]
+ - ["\u203c", "⠖⠖"]
+ - ["\u203d", "⠢⠖"]
+ - ["\u2043", "⠘⠄"]
+ - ["\u2047", "⠢⠢"]
+ - ["\u2048", "⠢⠖"]
+ - ["\u2049", "⠖⠢"]
+ - ["\u204c", "⠘⠄"]
+ - ["\u204d", "⠘⠄"]
+ - ["\u20ac", "⠘⠑"]
+ - ["\u2122", "⠘⠞"]
+
+# Arrows (only a few in 6 dots)
+
+ - ["\u2192", "⠘⠗"] # back-translates as "registered".
+
+# Geometrical shapes
+
+ - ["\u25e6", "⠘⠄"]
+
+# Extra digits
+
+ - ["1\u00bc + 1\u00bd = 2\u00be", "⠼⠁⠼⠁⠌⠙ ⠘⠖ ⠼⠁⠼⠁⠌⠃ ⠘⠶ ⠼⠃⠼⠉⠌⠙"]
+
+# Dashes
+
+ - ["\u2014 \u0096 \u0097 \u00ad", "⠤⠤ ⠤⠤ ⠤⠤ ⠤⠤"]
+
+# Quotes
+
+ - ["\u201e \u0084 \u201c \u0093 \u201d \u0094 \u00ab \u00bb", "⠶ ⠶ ⠶ ⠶ ⠶ ⠶ ⠶ ⠶"]
+
+# Apostrophes
+
+ - ["` \u201a \u0082 \u2039 \u008b \u2018 \u0091 \u2019 \u0092 \u203a \u009b \u00b4", "⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈"]
+
+# Parentheses and misc
+
+ - ["J) j) %) ') \u2030) \u0089) \u201a) \u0082) \u2039) \u009b) \u2018) \u0091) \u2019) \u0092) \u203a) \u009b)", "⠨⠠⠚⠠⠴ ⠠⠚⠠⠴ ⠚⠴⠠⠴ ⠈⠠⠴ ⠚⠴⠴⠠⠴ ⠚⠴⠴⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴"]
+
+# Emphasis
+
+ - # Bold line
+ - En linje med fed.
+ - ⠰⠨⠣ ⠇⠊⠝⠚⠑ ⠍ ⠋⠑⠙⠄⠰
+ - typeform:
+ bold: '+++++++++++++++++'
+ - # Bold word
+ - Et ord med fed.
+ - ⠨⠬ ⠰⠭⠙⠰ ⠍ ⠋⠑⠙⠄
+ - typeform:
+ bold: ' +++ '
+ - # Bold letter
+ - Et bogstav med fed.
+ - ⠨⠬ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍ ⠋⠑⠙⠄
+ - typeform:
+ bold: ' + '
+
+ - # Italic line
+ - En linje med kursiv.
+ - ⠰⠨⠣ ⠇⠊⠝⠚⠑ ⠍ ⠅⠥⠗⠎⠊⠧⠄⠰
+ - typeform:
+ italic: '++++++++++++++++++++'
+ - # Italic word
+ - Et ord med kursiv.
+ - ⠨⠬ ⠰⠭⠙⠰ ⠍ ⠅⠥⠗⠎⠊⠧⠄
+ - typeform:
+ italic: ' +++ '
+ - # Italic letter
+ - Et bogstav med kursiv.
+ - ⠨⠬ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍ ⠅⠥⠗⠎⠊⠧⠄
+ - typeform:
+ italic: ' + '
+
+ - # Underlined line
+ - En linje med understreget.
+ - ⠰⠨⠣ ⠇⠊⠝⠚⠑ ⠍ ⠥⠝⠾⠵⠷⠛⠬⠄⠰
+ - typeform:
+ underline: '++++++++++++++++++++++++++'
+ - # Underlined word
+ - Et ord med understreget.
+ - ⠨⠬ ⠰⠭⠙⠰ ⠍ ⠥⠝⠾⠵⠷⠛⠬⠄
+ - typeform:
+ underline: ' +++ '
+ - # Underlined letter
+ - Et bogstav med understreget.
+ - ⠨⠬ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍ ⠥⠝⠾⠵⠷⠛⠬⠄
+ - typeform:
+ underline: ' + '
+
+ - # Bold, italic and underlined line
+ - En linje med alt.
+ - ⠰⠨⠣ ⠇⠊⠝⠚⠑ ⠍ ⠁⠇⠞⠄⠰
+ - typeform:
+ bold: '+++++++++++++++++'
+ italic: '+++++++++++++++++'
+ underline: '+++++++++++++++++'
+ - # Bold, italic and underlined word
+ - Et ord med alt.
+ - ⠨⠬ ⠰⠭⠙⠰ ⠍ ⠁⠇⠞⠄
+ - typeform:
+ bold: ' +++ '
+ italic: ' +++ '
+ underline: ' +++ '
+ - # Bold, italic and underlined letter
+ - Et bogstav med alt.
+ - ⠨⠬ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍ ⠁⠇⠞⠄
+ - typeform:
+ bold: ' + '
+ italic: ' + '
+ underline: ' + '
+
+# Braille patterns which back-translate to something other than the original
+
+flags: {testmode: backward}
+tests:
+
+# Characters
+
+ - ["⠄⠄⠄", "..."]
+ - ["⠨⠕⠑", "Oe"]
+ - ["⠕⠑", "oe"]
+ - ["⠘⠖⠤", "±", {xfail: true}]
+ - ["⠼⠁⠌⠙", "1/4"]
+ - ["⠼⠁⠌⠃", "1/2"]
+ - ["⠼⠉⠌⠙", "3/4"]
+
+# Extra digits
+
+ - ["⠼⠁⠼⠁⠌⠙ ⠘⠖ ⠼⠁⠼⠁⠌⠃ ⠘⠶ ⠼⠃⠼⠉⠌⠙", "1\u00bc + 1\u00bd = 2\u00be", {xfail: true}]
+
+# -------------------------------
+# Grade 2 literary (forward only)
+# -------------------------------
+
+table: {language: da, grade: 2, dots: 6, direction: forward, version: 1993, __assert-match: da-dk-g26-lit_1993.ctb}
+flags: {testmode: forward}
+tests:
+
+# Characters
+
+ - [" ", " "]
+ - ["\"", "⠶"]
+ - ["\u0023", "⠘⠼"]
+ - ["$", "⠘⠲"]
+ - ["%", "⠚⠴"]
+ - ["&", "⠠⠯"]
+ - ["'", "⠈"]
+ - ["(", "⠠⠦"]
+ - [")", "⠠⠴"]
+ - ["*", "⠠⠔"]
+ - ["+", "⠘⠖"]
+ - [",", "⠂"]
+ - ["-", "⠤⠤"]
+ - [".", "⠄"]
+ - ["/", "⠠⠌", {xfail: true}]
+ - ["0", "⠼⠚"]
+ - ["1", "⠼⠁"]
+ - ["2", "⠼⠃"]
+ - ["3", "⠼⠉"]
+ - ["4", "⠼⠙"]
+ - ["5", "⠼⠑"]
+ - ["6", "⠼⠋"]
+ - ["7", "⠼⠛"]
+ - ["8", "⠼⠓"]
+ - ["9", "⠼⠊"]
+ - [":", "⠒"]
+ - [";", "⠆"]
+ - ["<", "⠘⠍"]
+ - ["=", "⠘⠶"]
+ - [">", "⠘⠎"]
+ - ["?", "⠢"]
+ - ["@", "⠘⠁"]
+ - ["A", "⠨⠠⠁"]
+ - ["B", "⠨⠠⠃"]
+ - ["C", "⠨⠠⠉"]
+ - ["D", "⠨⠠⠙"]
+ - ["E", "⠨⠠⠑"]
+ - ["F", "⠨⠠⠋"]
+ - ["G", "⠨⠠⠛"]
+ - ["H", "⠨⠠⠓"]
+ - ["I", "⠨⠊"]
+ - ["J", "⠨⠠⠚"]
+ - ["K", "⠨⠠⠅"]
+ - ["L", "⠨⠠⠇"]
+ - ["M", "⠨⠠⠍"]
+ - ["N", "⠨⠠⠝"]
+ - ["O", "⠨⠠⠕"]
+ - ["P", "⠨⠠⠏"]
+ - ["Q", "⠨⠠⠟"]
+ - ["R", "⠨⠠⠗"]
+ - ["S", "⠨⠠⠎"]
+ - ["T", "⠨⠠⠞"]
+ - ["U", "⠨⠠⠥"]
+ - ["V", "⠨⠠⠧"]
+ - ["W", "⠨⠠⠺"]
+ - ["X", "⠨⠠⠭"]
+ - ["Y", "⠨⠠⠽"]
+ - ["Z", "⠨⠠⠵"]
+ - ["[", "⠐⠦"]
+ - ["\u005c\u005c", "⠘⠡"]
+ - ["]", "⠐⠴"]
+ - ["^", "⠘⠬"]
+ - ["_", "⠘⠤"]
+ - ["`", "⠈"]
+ - ["a", "⠠⠁"]
+ - ["b", "⠠⠃"]
+ - ["c", "⠠⠉"]
+ - ["d", "⠠⠙"]
+ - ["e", "⠠⠑"]
+ - ["f", "⠠⠋"]
+ - ["g", "⠠⠛"]
+ - ["h", "⠠⠓"]
+ - ["i", "⠊"]
+ - ["j", "⠠⠚"]
+ - ["k", "⠠⠅"]
+ - ["l", "⠠⠇"]
+ - ["m", "⠠⠍"]
+ - ["n", "⠠⠝"]
+ - ["o", "⠠⠕"]
+ - ["p", "⠠⠏"]
+ - ["q", "⠠⠟"]
+ - ["r", "⠠⠗"]
+ - ["s", "⠠⠎"]
+ - ["t", "⠠⠞"]
+ - ["u", "⠠⠥"]
+ - ["v", "⠠⠧"]
+ - ["w", "⠠⠺"]
+ - ["x", "⠠⠭"]
+ - ["y", "⠠⠽"]
+ - ["z", "⠠⠵"]
+ - ["{", "⠘⠪"]
+ - ["|", "⠘⠸"]
+ - ["}", "⠘⠕"]
+ - ["~", "⠘⠠"]
+ - ["€", "⠘⠑"]
+ - ["‚", "⠈"]
+ - ["ƒ", "⠘⠋"]
+ - ["„", "⠶"]
+ - ["…", "⠄⠄⠄"]
+ - ["‰", "⠚⠴⠴"]
+ - ["Š", "⠨⠐⠎"]
+ - ["‹", "⠈"]
+ - ["Œ", "⠨⠕⠑"]
+ - ["Ž", "⠨⠐⠵"]
+ - ["‘", "⠈"]
+ - ["’", "⠈"]
+ - ["“", "⠶"]
+ - ["”", "⠶"]
+ - ["•", "⠘⠄"]
+ - ["–", "⠤⠤"]
+ - ["—", "⠤⠤"]
+ - ["˜", "⠘⠠"]
+ - ["™", "⠘⠞"]
+ - ["š", "⠐⠎"]
+ - ["›", "⠈"]
+ - ["œ", "⠕⠑"]
+ - ["ž", "⠐⠵"]
+ - ["Ÿ", "⠨⠐⠽"]
+ - ["¡", "⠠⠲"]
+ - ["¢", "⠘⠒"]
+ - ["£", "⠘⠇"]
+ - ["¥", "⠘⠽"]
+ - ["§", "⠬"]
+ - ["©", "⠘⠉"]
+ - ["«", "⠶"]
+ - ["®", "⠘⠗"]
+ - ["°", "⠈⠴"]
+ - ["±", "⠘⠖⠤"]
+ - ["²", "⠼⠬⠃"]
+ - ["³", "⠼⠬⠉"]
+ - ["´", "⠈"]
+ - ["µ", "⠐⠍"]
+ - ["¹", "⠼⠬⠁"]
+ - ["»", "⠶"]
+ - ["¼", "⠼⠁⠌⠙"]
+ - ["½", "⠼⠁⠌⠃"]
+ - ["¾", "⠼⠉⠌⠙"]
+ - ["À", "⠨⠐⠁"]
+ - ["Á", "⠨⠐⠁"]
+ - ["Â", "⠨⠐⠁"]
+ - ["Ã", "⠨⠐⠁"]
+ - ["Ä", "⠨⠠⠜"]
+ - ["Å", "⠨⠠⠡"]
+ - ["Æ", "⠨⠠⠜"]
+ - ["Ç", "⠨⠐⠉"]
+ - ["È", "⠨⠐⠑"]
+ - ["É", "⠨⠐⠑"]
+ - ["Ê", "⠨⠐⠑"]
+ - ["Ë", "⠨⠐⠑"]
+ - ["Ì", "⠨⠐⠊"]
+ - ["Í", "⠨⠐⠊"]
+ - ["Î", "⠨⠐⠊"]
+ - ["Ï", "⠨⠐⠊"]
+ - ["Ð", "⠨⠐⠙"]
+ - ["Ñ", "⠨⠐⠝"]
+ - ["Ò", "⠨⠐⠕"]
+ - ["Ó", "⠨⠐⠕"]
+ - ["Ô", "⠨⠐⠕"]
+ - ["Õ", "⠨⠐⠕"]
+ - ["Ö", "⠨⠠⠪"]
+ - ["×", "⠘⠄"]
+ - ["Ø", "⠨⠠⠪"]
+ - ["Ù", "⠨⠐⠥"]
+ - ["Ú", "⠨⠐⠥"]
+ - ["Û", "⠨⠐⠥"]
+ - ["Ü", "⠨⠠⠳"]
+ - ["Ý", "⠨⠐⠽"]
+ - ["Þ", "⠨⠐⠞"]
+ - ["ß", "⠎⠎"]
+ - ["à", "⠐⠁"]
+ - ["á", "⠐⠁"]
+ - ["â", "⠐⠁"]
+ - ["ã", "⠐⠁"]
+ - ["ä", "⠠⠜"]
+ - ["å", "⠠⠡"]
+ - ["æ", "⠠⠜"]
+ - ["ç", "⠐⠉"]
+ - ["è", "⠐⠑"]
+ - ["é", "⠐⠑"]
+ - ["ê", "⠐⠑"]
+ - ["ë", "⠐⠑"]
+ - ["ì", "⠐⠊"]
+ - ["í", "⠐⠊"]
+ - ["î", "⠐⠊"]
+ - ["ï", "⠐⠊"]
+ - ["ð", "⠐⠙"]
+ - ["ñ", "⠐⠝"]
+ - ["ò", "⠐⠕"]
+ - ["ó", "⠐⠕"]
+ - ["ô", "⠐⠕"]
+ - ["õ", "⠐⠕"]
+ - ["ö", "⠠⠪"]
+ - ["÷", "⠘⠲"]
+ - ["ø", "⠠⠪"]
+ - ["ù", "⠐⠥"]
+ - ["ú", "⠐⠥"]
+ - ["û", "⠐⠥"]
+ - ["ü", "⠠⠳"]
+ - ["ý", "⠐⠽"]
+ - ["þ", "⠐⠞"]
+ - ["ÿ", "⠐⠽"]
+
+# Latin Extended-A
+
+ - ["\u0100\u0101", "⠐⠁⠐⠁"]
+ - ["\u0102\u0103", "⠐⠁⠐⠁"]
+ - ["\u0104\u0105", "⠐⠁⠐⠁"]
+ - ["\u0106\u0107", "⠐⠉⠐⠉"]
+ - ["\u0108\u0109", "⠐⠉⠐⠉"]
+ - ["\u010a\u010b", "⠐⠉⠐⠉"]
+ - ["\u010c\u010d", "⠐⠉⠐⠉"]
+ - ["\u010e\u010f", "⠐⠙⠐⠙"]
+ - ["\u0110\u0111", "⠐⠙⠐⠙"]
+ - ["\u0112\u0113", "⠐⠑⠐⠑"]
+ - ["\u0114\u0115", "⠐⠑⠐⠑"]
+ - ["\u0116\u0117", "⠐⠑⠐⠑"]
+ - ["\u0118\u0119", "⠐⠑⠐⠑"]
+ - ["\u011a\u011b", "⠐⠑⠐⠑"]
+ - ["\u011c\u011d", "⠐⠛⠐⠛"]
+ - ["\u011e\u011f", "⠐⠛⠐⠛"]
+ - ["\u0120\u0121", "⠐⠛⠐⠛"]
+ - ["\u0122\u0123", "⠐⠛⠐⠛"]
+ - ["\u0124\u0125", "⠐⠓⠐⠓"]
+ - ["\u0126\u0127", "⠐⠓⠐⠓"]
+ - ["\u0128\u0129", "⠐⠊⠐⠊"]
+ - ["\u012a\u012b", "⠐⠊⠐⠊"]
+ - ["\u012c\u012d", "⠐⠊⠐⠊"]
+ - ["\u012e\u012f", "⠐⠊⠐⠊"]
+ - ["\u0130\u0131", "⠐⠊⠐⠊"]
+ - ["\u0132\u0133", "⠊⠚⠊⠚"]
+ - ["\u0134\u0135", "⠐⠚⠐⠚"]
+ - ["\u0136\u0137", "⠐⠅⠐⠅"]
+ - ["\u0138", "⠐⠟"]
+ - ["\u0139\u013a", "⠐⠇⠐⠇"]
+ - ["\u013b\u013c", "⠐⠇⠐⠇"]
+ - ["\u013d\u013e", "⠐⠇⠐⠇"]
+ - ["\u013f\u0140", "⠐⠇⠐⠇"]
+ - ["\u0141\u0142", "⠐⠇⠐⠇"]
+ - ["\u0143\u0144", "⠐⠝⠐⠝"]
+ - ["\u0145\u0146", "⠐⠝⠐⠝"]
+ - ["\u0147\u0148", "⠐⠝⠐⠝"]
+ - ["\u0149", "⠈⠝"]
+ - ["\u014a\u014b", "⠐⠝⠐⠝"]
+ - ["\u014c\u014d", "⠐⠕⠐⠕"]
+ - ["\u014e\u014f", "⠐⠕⠐⠕"]
+ - ["\u0150\u0151", "⠐⠕⠐⠕"]
+ - ["\u0152\u0153", "⠕⠑⠕⠑"]
+ - ["\u0154\u0155", "⠐⠗⠐⠗"]
+ - ["\u0156\u0157", "⠐⠗⠐⠗"]
+ - ["\u0158\u0159", "⠐⠗⠐⠗"]
+ - ["\u015a\u015b", "⠐⠎⠐⠎"]
+ - ["\u015c\u015d", "⠐⠎⠐⠎"]
+ - ["\u015e\u015f", "⠐⠎⠐⠎"]
+ - ["\u0160\u0161", "⠐⠎⠐⠎"]
+ - ["\u0162\u0163", "⠐⠞⠐⠞"]
+ - ["\u0164\u0165", "⠐⠞⠐⠞"]
+ - ["\u0166\u0167", "⠐⠞⠐⠞"]
+ - ["\u0168\u0169", "⠐⠥⠐⠥"]
+ - ["\u016a\u016b", "⠐⠥⠐⠥"]
+ - ["\u016c\u016d", "⠐⠥⠐⠥"]
+ - ["\u016e\u016f", "⠐⠥⠐⠥"]
+ - ["\u0170\u0171", "⠐⠥⠐⠥"]
+ - ["\u0172\u0173", "⠐⠥⠐⠥"]
+ - ["\u0174\u0175", "⠐⠺⠐⠺"]
+ - ["\u0176\u0177", "⠐⠽⠐⠽"]
+ - ["\u0178\u00ff", "⠐⠽⠐⠽"]
+ - ["\u0179\u017a", "⠐⠵⠐⠵"]
+ - ["\u017b\u017c", "⠐⠵⠐⠵"]
+ - ["\u017d\u017e", "⠐⠵⠐⠵"]
+ - ["\u017f", "⠐⠎"]
+
+# Latin Extended-B
+
+ - ["\u0192", "⠘⠋"]
+ - ["\u02dc", "⠘⠠"]
+
+# Greek letters (with dot 5 as prefix)
+
+ - ["\u0386\u03ac", "⠐⠁⠐⠁"]
+ - ["\u0388\u03ad", "⠐⠑⠐⠑"]
+ - ["\u0389\u03ae", "⠐⠱⠐⠱"]
+ - ["\u038a\u03af", "⠐⠊⠐⠊"]
+ - ["\u038c\u03cc", "⠐⠕⠐⠕"]
+ - ["\u038e\u03cd", "⠐⠥⠐⠥"]
+ - ["\u038f\u03ce", "⠐⠺⠐⠺"]
+ - ["\u0391\u03b1", "⠐⠁⠐⠁"]
+ - ["\u0392\u03b2", "⠐⠃⠐⠃"]
+ - ["\u0393\u03b3", "⠐⠛⠐⠛"]
+ - ["\u0394\u03b4", "⠐⠙⠐⠙"]
+ - ["\u0395\u03b5", "⠐⠑⠐⠑"]
+ - ["\u0396\u03b6", "⠐⠵⠐⠵"]
+ - ["\u0397\u03b7", "⠐⠱⠐⠱"]
+ - ["\u0398\u03b8", "⠐⠹⠐⠹"]
+ - ["\u0399\u03b9", "⠐⠊⠐⠊"]
+ - ["\u039a\u03ba", "⠐⠅⠐⠅"]
+ - ["\u039b\u03bb", "⠐⠇⠐⠇"]
+ - ["\u039c\u03bc", "⠐⠍⠐⠍"]
+ - ["\u039d\u03bd", "⠐⠝⠐⠝"]
+ - ["\u039e\u03be", "⠐⠭⠐⠭"]
+ - ["\u039f\u03bf", "⠐⠕⠐⠕"]
+ - ["\u03a0\u03c0", "⠐⠏⠐⠏"]
+ - ["\u03a1\u03c1", "⠐⠗⠐⠗"]
+ - ["\u03a3\u03c3", "⠐⠎⠐⠎"]
+ - ["\u03a4\u03c4", "⠐⠞⠐⠞"]
+ - ["\u03a5\u03c5", "⠐⠥⠐⠥"]
+ - ["\u03a6\u03c6", "⠐⠋⠐⠋"]
+ - ["\u03a7\u03c7", "⠐⠓⠐⠓"]
+ - ["\u03a8\u03c8", "⠐⠽⠐⠽"]
+ - ["\u03a9\u03c9", "⠐⠺⠐⠺"]
+
+# Punctuation and bullits
+
+ - ["\u2000", " "]
+ - ["\u2001", " "]
+ - ["\u2002", " "]
+ - ["\u2003", " "]
+ - ["\u2004", " "]
+ - ["\u2005", " "]
+ - ["\u2006", " "]
+ - ["\u2007", " "]
+ - ["\u2008", " "]
+ - ["\u2009", " "]
+ - ["\u200a", " "]
+ - ["\u2010", "⠤"]
+ - ["\u2011", "⠤"]
+ - ["\u2012", "⠤"]
+ - ["\u2013", "⠤⠤"]
+ - ["\u2014", "⠤⠤"]
+ - ["\u2018", "⠈"]
+ - ["\u2019", "⠈"]
+ - ["\u201a", "⠈"]
+ - ["\u201b", "⠈"]
+ - ["\u201c", "⠶"]
+ - ["\u201d", "⠶"]
+ - ["\u201e", "⠶"]
+ - ["\u201f", "⠶"]
+ - ["\u2023", "⠘⠄"]
+ - ["\u2026", "⠄⠄⠄"]
+ - ["\u202f", " "]
+ - ["\u2030", "⠚⠴⠴"]
+ - ["\u2039", "⠈"]
+ - ["\u203a", "⠈"]
+ - ["\u203c", "⠖⠖"]
+ - ["\u203d", "⠢⠖"]
+ - ["\u2043", "⠘⠄"]
+ - ["\u2047", "⠢⠢"]
+ - ["\u2048", "⠢⠖"]
+ - ["\u2049", "⠖⠢"]
+ - ["\u204c", "⠘⠄"]
+ - ["\u204d", "⠘⠄"]
+ - ["\u20ac", "⠘⠑"]
+ - ["\u2122", "⠘⠞"]
+
+# Arrows (only a few in 6 dots)
+
+ - ["\u2190", "⠘⠺"]
+ - ["\u2191", "⠘⠷"]
+ - ["\u2192", "⠘⠗"]
+ - ["\u2193", "⠘⠟"]
+
+# Geometrical shapes
+
+ - ["\u25e6", "⠘⠄"]
+
+# Pangram
+
+ - - "Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Walther spillede på xylofon."
+ - "⠠⠟⠥⠊⠠⠵⠹⠇⠞⠁⠛⠱⠫ ⠎⠏⠊⠵⠑ ⠚⠭⠙⠃⠜⠗ ⠍ ⠋⠇⠪⠹⠂ ⠍⠣⠎ ⠉⠊⠗⠅⠥⠎⠅⠇⠕⠧⠝⠣ ⠠⠺⠁⠇⠞⠓⠱ ⠎⠏⠊⠇⠇⠑⠹ ⠏ ⠠⠭⠽⠇⠕⠋⠕⠝⠄"
+
+# Emphasis
+
+ - # Bold line
+ - En linje med fed.
+ - ⠰⠣ ⠇⠊⠝⠚⠑ ⠍ ⠋⠑⠙⠄⠰
+ - typeform:
+ bold: '+++++++++++++++++'
+ - # Bold word
+ - Et ord med fed.
+ - ⠬ ⠰⠭⠙⠰ ⠍ ⠋⠑⠙⠄
+ - typeform:
+ bold: ' +++ '
+ - # Bold letter
+ - Et bogstav med fed.
+ - ⠬ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍ ⠋⠑⠙⠄
+ - typeform:
+ bold: ' + '
+
+ - # Italic line
+ - En linje med kursiv.
+ - ⠰⠣ ⠇⠊⠝⠚⠑ ⠍ ⠅⠥⠗⠎⠊⠧⠄⠰
+ - typeform:
+ italic: '++++++++++++++++++++'
+ - # Italic word
+ - Et ord med kursiv.
+ - ⠬ ⠰⠭⠙⠰ ⠍ ⠅⠥⠗⠎⠊⠧⠄
+ - typeform:
+ italic: ' +++ '
+ - # Italic letter
+ - Et bogstav med kursiv.
+ - ⠬ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍ ⠅⠥⠗⠎⠊⠧⠄
+ - typeform:
+ italic: ' + '
+
+ - # Underlined line
+ - En linje med understreget.
+ - ⠰⠣ ⠇⠊⠝⠚⠑ ⠍ ⠥⠝⠾⠵⠷⠛⠬⠄⠰
+ - typeform:
+ underline: '++++++++++++++++++++++++++'
+ - # Underlined word
+ - Et ord med understreget.
+ - ⠬ ⠰⠭⠙⠰ ⠍ ⠥⠝⠾⠵⠷⠛⠬⠄
+ - typeform:
+ underline: ' +++ '
+ - # Underlined letter
+ - Et bogstav med understreget.
+ - ⠬ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍ ⠥⠝⠾⠵⠷⠛⠬⠄
+ - typeform:
+ underline: ' + '
+
+ - # Bold, italic and underlined line
+ - En linje med alt.
+ - ⠰⠣ ⠇⠊⠝⠚⠑ ⠍ ⠁⠇⠞⠄⠰
+ - typeform:
+ bold: '+++++++++++++++++'
+ italic: '+++++++++++++++++'
+ underline: '+++++++++++++++++'
+ - # Bold, italic and underlined word
+ - Et ord med alt.
+ - ⠬ ⠰⠭⠙⠰ ⠍ ⠁⠇⠞⠄
+ - typeform:
+ bold: ' +++ '
+ italic: ' +++ '
+ underline: ' +++ '
+ - # Bold, italic and underlined letter
+ - Et bogstav med alt.
+ - ⠬ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍ ⠁⠇⠞⠄
+ - typeform:
+ bold: ' + '
+ italic: ' + '
+ underline: ' + '
+
+# Caps and mixed case
+
+ - ["Foobar", "⠋⠕⠕⠃⠁⠗"]
+ - ["FOOBAR", "⠸⠋⠕⠕⠃⠁⠗"]
+ - ["FOObar", "⠸⠋⠕⠕⠠⠃⠁⠗"]
+ - ["FOO-barfOObar", "⠸⠋⠕⠕⠤⠃⠁⠗⠋⠸⠕⠕⠠⠃⠁⠗"]
+
+# Percent and permille
+
+ - ["1%", "⠼⠁ ⠚⠴"]
+
+# Extra digits
+
+ - ["1\u00bc + 1\u00bd = 2\u00be", "⠼⠁⠼⠁⠌⠙ ⠖⠼⠁⠼⠁⠌⠃ ⠶⠼⠃⠼⠉⠌⠙"]
+
+# Dashes
+
+ - ["\u2014 \u0096 \u0097 \u00ad", "⠤⠤ ⠤⠤ ⠤⠤ ⠤⠤"]
+
+# Quotes
+
+ - ["\u201e \u0084 \u201c \u0093 \u201d \u0094 \u00ab \u00bb", "⠶ ⠶ ⠶ ⠶ ⠶ ⠶ ⠶ ⠶"]
+
+# Apostrophes
+
+ - ["` \u201a \u0082 \u2039 \u008b \u2018 \u0091 \u2019 \u0092 \u203a \u009b \u00b4", "⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈ ⠈"]
+
+# Times vs. bullit
+
+ - ["\u2022Bullit", "⠘⠄⠃⠥⠇⠇⠊⠞"]
+ - ["2 \u00d7 2 = 4", "⠼⠃ ⠄⠼⠃ ⠶⠼⠙"]
+
+# Section sign
+ - ["§ 3", "⠬⠼⠉"]
+ - ["§ 3:", "⠬⠼⠉⠒"]
+
+# Numbers and punctuation
+
+ - ["1,2", "⠼⠁⠂⠃"]
+ - ["123.456", "⠼⠁⠃⠉⠄⠙⠑⠋"]
+ - ["3-4", "⠼⠉⠤⠼⠙"]
+ - ["56-", "⠼⠑⠋⠤"]
+ - ["1/2", "⠼⠁⠌⠃"]
+ - ["12:34", "⠼⠁⠃⠒⠉⠙"]
+ - ["2^10", "⠼⠃⠘⠬⠁⠚"]
+ - ["2\u00d72", "⠼⠃⠘⠄⠼⠃"]
+
+ - ["\"quotes\"", "⠶⠠⠟⠥⠕⠳⠎⠶"]
+ - ["-dashes-", "⠤⠙⠁⠎⠓⠑⠎⠤"]
+ - [":-) :-(", "⠒⠤⠠⠴ ⠒⠤⠠⠦"]
+ - [";-) ;-(", "⠆⠤⠠⠴ ⠆⠤⠠⠦"]
+ - ["---", "⠤⠤⠤"]
+ - ["-", "⠤⠤"]
+ - [" -", " ⠤⠤"]
+ - [" a-", " ⠠⠁⠤"]
+ - [" - ", " ⠤⠤ "]
+ - [" -a-", " ⠤⠠⠁⠤"]
+ - [" ", " "]
+ - ["(parentheses)", "⠦⠏⠁⠗⠣⠞⠓⠑⠎⠑⠎⠴"]
+ - ["J) j) %) ') \u2030) \u0089) \u201a) \u0082) \u2039) \u009b) \u2018) \u0091) \u2019) \u0092) \u203a) \u009b)", "⠨⠠⠚⠠⠴ ⠠⠚⠠⠴ ⠚⠴⠠⠴ ⠈⠠⠴ ⠚⠴⠴⠠⠴ ⠚⠴⠴⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴ ⠈⠠⠴"]
+
+# Exclamation
+
+ - ["\u00a1Que lastima!", "⠠⠲⠠⠟⠥⠑ ⠇⠁⠵⠊⠍⠁⠖"]
+
+# Digits and letters
+
+ - ["1a", "⠼⠁⠠⠁"]
+ - ["1.,-a", "⠼⠁⠄⠂⠤⠠⠁"]
+
+# URLs emails and file names
+
+ - ["$at", "⠘⠲⠁⠞"]
+ - ["\u005c\u005cat\u005c\u005cbliver", "⠘⠡⠁⠞⠘⠡⠃⠇⠊⠧⠑⠗"]
+ - ["at@bliver.og", "⠁⠞⠘⠁⠃⠇⠊⠧⠑⠗⠄⠕⠛"]
+ - ["http://at.bliver.og", "⠓⠞⠞⠏⠒⠌⠌⠁⠞⠄⠃⠇⠊⠧⠑⠗⠄⠕⠛"]
+ - ["www.at.bliver.og", "⠠⠺⠠⠺⠠⠺⠄⠁⠞⠄⠃⠇⠊⠧⠑⠗⠄⠕⠛"]
+ - ["www.at.bliver.com", "⠠⠺⠠⠺⠠⠺⠄⠁⠞⠄⠃⠇⠊⠧⠑⠗⠄⠉⠕⠍"]
+ - ["www.a.b.c", "⠠⠺⠠⠺⠠⠺⠄⠠⠁⠄⠠⠃⠄⠠⠉"]
+ - ["test.txt", "⠳⠵⠄⠞⠠⠭⠞"]
+
+# Word contractions
+
+ - ["At", "⠁"]
+ - ["at", "⠁"]
+ - ["Aldrig", "⠁⠔"]
+ - ["aldrig", "⠁⠔"]
+ - ["aig", "⠁⠊⠛"]
+ - ["Alle", "⠁⠑"]
+ - ["alle", "⠁⠑"]
+ - ["ae", "⠠⠁⠑"]
+ - ["Allerede", "⠁⠇⠗"]
+ - ["allerede", "⠁⠇⠗"]
+ - ["alr", "⠠⠁⠇⠗"]
+ - ["Alligevel", "⠁⠇⠧"]
+ - ["alligevel", "⠁⠇⠧"]
+ - ["alv", "⠠⠁⠇⠧"]
+ - ["Altid", "⠁⠞⠙"]
+ - ["altid", "⠁⠞⠙"]
+ - ["atd", "⠠⠁⠞⠙"]
+ - ["Altså", "⠁⠡"]
+ - ["altså", "⠁⠡"]
+ - ["aå", "⠠⠁⠡"]
+ - ["Bliver", "⠃"]
+ - ["bliver", "⠃"]
+ - ["Og", "⠉"]
+ - ["og", "⠉"]
+ - ["Deres", "⠲"]
+ - ["deres", "⠲"]
+ - ["Du", "⠙"]
+ - ["du", "⠙"]
+ - ["Eller", "⠑"]
+ - ["eller", "⠑"]
+ - ["For", "⠋"]
+ - ["for", "⠋"]
+ - ["Gør", "⠛"]
+ - ["gør", "⠛"]
+ - ["Har", "⠓"]
+ - ["har", "⠓"]
+ - ["Jeg", "⠚"]
+ - ["jeg", "⠚"]
+ - ["Kan", "⠅"]
+ - ["kan", "⠅"]
+ - ["Lige", "⠇"]
+ - ["lige", "⠇"]
+ - ["Med", "⠍"]
+ - ["med", "⠍"]
+ - ["Når", "⠝"]
+ - ["når", "⠝"]
+ - ["Op", "⠕"]
+ - ["op", "⠕"]
+ - ["På", "⠏"]
+ - ["på", "⠏"]
+ - ["Under", "⠟"]
+ - ["under", "⠟"]
+ - ["Rigtig", "⠗"]
+ - ["rigtig", "⠗"]
+ - ["Som", "⠎"]
+ - ["som", "⠎"]
+ - ["Til", "⠞"]
+ - ["til", "⠞"]
+ - ["Hun", "⠥"]
+ - ["hun", "⠥"]
+ - ["Ved", "⠧"]
+ - ["ved", "⠧"]
+ - ["Hvad", "⠺"]
+ - ["hvad", "⠺"]
+ - ["Over", "⠭"]
+ - ["over", "⠭"]
+ - ["Han", "⠽"]
+ - ["han", "⠽"]
+ - ["Efter", "⠵"]
+ - ["efter", "⠵"]
+ - ["Være", "⠜"]
+ - ["være", "⠜"]
+ - ["Før", "⠪"]
+ - ["før", "⠪"]
+ - ["Så", "⠡"]
+ - ["så", "⠡"]
+ - ["Den", "⠯"]
+ - ["den", "⠯"]
+ - ["Der", "⠾"]
+ - ["der", "⠾"]
+ - ["Det", "⠮"]
+ - ["det", "⠮"]
+ - ["De", "⠹"]
+ - ["de", "⠹"]
+ - ["En", "⠣"]
+ - ["en", "⠣"]
+ - ["Er", "⠱"]
+ - ["er", "⠱"]
+ - ["Et", "⠬"]
+ - ["et", "⠬"]
+ - ["Gennem", "⠻"]
+ - ["gennem", "⠻"]
+ - ["Hvor", "⠌"]
+ - ["hvor", "⠌"]
+ - ["Men", "⠩"]
+ - ["men", "⠩"]
+ - ["Ned", "⠫"]
+ - ["ned", "⠫"]
+ - ["Ret", "⠷"]
+ - ["ret", "⠷"]
+ - ["Skal", "⠿"]
+ - ["skal", "⠿"]
+ - ["Te", "⠳"]
+ - ["te", "⠳"]
+ - ["Ve", "⠼"]
+ - ["ve", "⠼"]
+
+# Partword/nocross
+
+ - ["Denne", "⠯⠫"]
+ - ["denne", "⠯⠫"]
+ - ["Mændene", "⠍⠜⠝⠹⠫"]
+ - ["mændene", "⠍⠜⠝⠹⠫"]
+ - ["Derhos", "⠾⠓⠕⠎"]
+ - ["derhos", "⠾⠓⠕⠎"]
+ - ["Hunderace", "⠓⠥⠝⠹⠗⠁⠉⠑"]
+ - ["hunderace", "⠓⠥⠝⠹⠗⠁⠉⠑"]
+ - ["Dette", "⠮⠳"]
+ - ["dette", "⠮⠳"]
+ - ["Detalje", "⠹⠞⠁⠇⠚⠑"]
+ - ["detalje", "⠹⠞⠁⠇⠚⠑"]
+
+# Nocross multiple cells
+
+ - ["Endda", "⠑⠟⠙⠁"]
+ - ["endda", "⠑⠟⠙⠁"]
+ - ["Morgendag", "⠍⠭⠛⠣⠙⠁⠛"]
+ - ["morgendag", "⠍⠭⠛⠣⠙⠁⠛"]
+ - ["Gendanne", "⠛⠣⠙⠁⠝⠫"]
+ - ["gendanne", "⠛⠣⠙⠁⠝⠫"]
+ - ["Generelt", "⠻⠫⠷⠇⠞"]
+ - ["generelt", "⠻⠫⠷⠇⠞"]
+
+ - ["Fra!", "⠋⠗⠁⠖"]
+ - ["fra!", "⠋⠗⠁⠖"]
+ - ["!Fra", "⠖⠋⠗⠁"]
+ - ["!fra", "⠖⠋⠗⠁"]
+ - ["'Af", "⠈⠁⠋"]
+ - ["'af", "⠈⠁⠋"]
+
+
+# No single cell contractions before or after dashes
+
+ - ["at-bliver", "⠁⠞⠤⠃"]
+ - ["d-d-du", "⠠⠙⠤⠠⠙⠤⠙⠥"]
+
+# Combinations with slashes and other punctuation signs
+
+ - ["Han/hun", "⠽⠌⠥"]
+ - ["han/hun", "⠽⠌⠥"]
+ - ["Over/under", "⠭⠌⠟"]
+ - ["over/under", "⠭⠌⠟"]
+ - ["Til/fra", "⠞⠌⠖"]
+ - ["til/fra", "⠞⠌⠖"]
+
+# Combinations which require letsign
+
+ - ["1st", "⠼⠁⠠⠎⠞"]
+ - ["2nd", "⠼⠃⠠⠝⠙"]
+ - ["1A", "⠼⠁⠨⠠⠁", {xfail: true}] # unclear spec
+ - ["1a", "⠼⠁⠠⠁"]
+ - ["2B", "⠼⠃⠨⠠⠃", {xfail: true}] # unclear spec
+ - ["2b", "⠼⠃⠠⠃"]
+
+# Multi-pass tests
+
+ - ["~x |z", "⠘⠠⠠⠭ ⠘⠸⠠⠵"]
+ - ["~X |Z", "⠘⠠⠨⠠⠭ ⠘⠸⠨⠠⠵"]
+ - ["5É", "⠼⠑⠨⠐⠑"]
+
+#############
+### 8-DOT ###
+#############
+
+# -------
+# Grade 0
+# -------
+
+table: {language: da, grade: 0, dots: 8, version: 1993, __assert-match: da-dk-g08_1993.ctb}
+flags: {testmode: bothDirections}
+tests:
+
+# Characters from 0x21 to 0xff
+
+ - [' ', ' ']
+ - ['"', '⠶']
+ - ['$', '⣲']
+ - ['%', '⣚']
+ - ['&', '⢯']
+ - ['''', '⠈']
+ - ['(', '⢦']
+ - [')', '⢴']
+ - ['*', '⠔']
+ - ['+', '⢖']
+ - [',', '⠂']
+ - ['-', '⢤']
+ - ['.', '⠄']
+ - ['/', '⢌']
+ - ['0', '⢚']
+ - ['1', '⢁']
+ - ['2', '⢃']
+ - ['3', '⢉']
+ - ['4', '⢙']
+ - ['5', '⢑']
+ - ['6', '⢋']
+ - ['7', '⢛']
+ - ['8', '⢓']
+ - ['9', '⢊']
+ - [':', '⠒']
+ - [';', '⠆']
+ - ['<', '⢔']
+ - ['=', '⢶']
+ - ['>', '⡢']
+ - ['?', '⠢']
+ - ['@', '⣈']
+ - ['A', '⡁']
+ - ['B', '⡃']
+ - ['C', '⡉']
+ - ['D', '⡙']
+ - ['E', '⡑']
+ - ['F', '⡋']
+ - ['G', '⡛']
+ - ['H', '⡓']
+ - ['I', '⡊']
+ - ['J', '⡚']
+ - ['K', '⡅']
+ - ['L', '⡇']
+ - ['M', '⡍']
+ - ['N', '⡝']
+ - ['O', '⡕']
+ - ['P', '⡏']
+ - ['Q', '⡟']
+ - ['R', '⡗']
+ - ['S', '⡎']
+ - ['T', '⡞']
+ - ['U', '⡥']
+ - ['V', '⡧']
+ - ['W', '⡺']
+ - ['X', '⡭']
+ - ['Y', '⡽']
+ - ['Z', '⡵']
+ - ['[', '⣦']
+ - ['\\', '⡌']
+ - [']', '⣴']
+ - ['^', '⢏']
+ - ['_', '⣤']
+ - ['`', '⠐']
+ - ['a', '⠁']
+ - ['b', '⠃']
+ - ['c', '⠉']
+ - ['d', '⠙']
+ - ['e', '⠑']
+ - ['f', '⠋']
+ - ['g', '⠛']
+ - ['h', '⠓']
+ - ['i', '⠊']
+ - ['j', '⠚']
+ - ['k', '⠅']
+ - ['l', '⠇']
+ - ['m', '⠍']
+ - ['n', '⠝']
+ - ['o', '⠕']
+ - ['p', '⠏']
+ - ['q', '⠟']
+ - ['r', '⠗']
+ - ['s', '⠎']
+ - ['t', '⠞']
+ - ['u', '⠥']
+ - ['v', '⠧']
+ - ['w', '⠺']
+ - ['x', '⠭']
+ - ['y', '⠽']
+ - ['z', '⠵']
+ - ['{', '⣧']
+ - ['|', '⢸']
+ - ['}', '⣼']
+ - ['~', '⡨']
+ - ['€', '⣑']
+ - ['‚', '⡘']
+ - ['ƒ', '⢐']
+ - ['„', '⣆']
+ - ['…', '⠠']
+ - ['†', '⡖']
+ - ['‡', '⣖']
+ - ['ˆ', '⣰']
+ - ['‰', '⣺']
+ - ['Š', '⣎']
+ - ['‹', '⠸']
+ - ['Œ', '⣕']
+ - ['Ž', '⡬']
+ - ['‘', '⡈']
+ - ['’', '⢈']
+ - ['“', '⡆']
+ - ['”', '⢰']
+ - ['•', '⡄']
+ - ['–', '⠤']
+ - ['—', '⡤']
+ - ['˜', '⠨']
+ - ['™', '⣞']
+ - ['š', '⢎']
+ - ['›', '⡸']
+ - ['œ', '⢕']
+ - ['ž', '⠬']
+ - ['Ÿ', '⣾']
+ - [' ', '⢞']
+ - ['¡', '⠲']
+ - ['¢', '⣒']
+ - ['£', '⢇']
+ - ['¤', '⡦']
+ - ['¥', '⡠']
+ - ['¦', '⣌']
+ - ['§', '⣐']
+ - ['¨', '⠰']
+ - ['©', '⣭']
+ - ['ª', '⣮']
+ - ['«', '⡐']
+ - ['¬', '⡼']
+ - ['', '⣄']
+ - ['®', '⣗']
+ - ['¯', '⡶']
+ - ['°', '⠴']
+ - ['±', '⢟']
+ - ['²', '⢆']
+ - ['³', '⢒']
+ - ['´', '⢨']
+ - ['µ', '⠦']
+ - ['¶', '⢿']
+ - ['·', '⢄']
+ - ['¸', '⣨']
+ - ['¹', '⢂']
+ - ['º', '⣿']
+ - ['»', '⡰']
+ - ['¼', '⢝']
+ - ['½', '⢘']
+ - ['¾', '⠼']
+ - ['À', '⡷']
+ - ['Á', '⣷']
+ - ['Â', '⣡']
+ - ['Ã', '⣩']
+ - ['Ä', '⣜']
+ - ['Å', '⡡']
+ - ['Æ', '⡜']
+ - ['Ç', '⡯']
+ - ['È', '⡮']
+ - ['É', '⡿']
+ - ['Ê', '⡣']
+ - ['Ë', '⡫']
+ - ['Ì', '⣱']
+ - ['Í', '⣣']
+ - ['Î', '⡩']
+ - ['Ï', '⡻']
+ - ['Ð', '⣽']
+ - ['Ñ', '⣻']
+ - ['Ò', '⣫']
+ - ['Ó', '⣬']
+ - ['Ô', '⡹']
+ - ['Õ', '⣹']
+ - ['Ö', '⣪']
+ - ['×', '⢭']
+ - ['Ø', '⡪']
+ - ['Ù', '⡾']
+ - ['Ú', '⣳']
+ - ['Û', '⡱']
+ - ['Ü', '⡳']
+ - ['Ý', '⣍']
+ - ['Þ', '⣅']
+ - ['ß', '⢮']
+ - ['à', '⠷']
+ - ['á', '⢷']
+ - ['â', '⢡']
+ - ['ã', '⢩']
+ - ['ä', '⢜']
+ - ['å', '⠡']
+ - ['æ', '⠜']
+ - ['ç', '⠯']
+ - ['è', '⠮']
+ - ['é', '⠿']
+ - ['ê', '⠣']
+ - ['ë', '⠫']
+ - ['ì', '⢱']
+ - ['í', '⢣']
+ - ['î', '⠩']
+ - ['ï', '⠻']
+ - ['ð', '⢽']
+ - ['ñ', '⢻']
+ - ['ò', '⢫']
+ - ['ó', '⢬']
+ - ['ô', '⠹']
+ - ['õ', '⢹']
+ - ['ö', '⢪']
+ - ['÷', '⢲']
+ - ['ø', '⠪']
+ - ['ù', '⠾']
+ - ['ú', '⢳']
+ - ['û', '⠱']
+ - ['ü', '⠳']
+ - ['ý', '⢍']
+ - ['þ', '⢅']
+ - ['ÿ', '⢾']
+
+# Pangram
+
+ - - 'Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Walther spillede på xylofon.'
+ - '⡟⠥⠊⠵⠙⠑⠇⠞⠁⠛⠑⠗⠝⠑ ⠎⠏⠊⠎⠞⠑ ⠚⠕⠗⠙⠃⠜⠗ ⠍⠑⠙ ⠋⠇⠪⠙⠑⠂ ⠍⠑⠝⠎ ⠉⠊⠗⠅⠥⠎⠅⠇⠕⠧⠝⠑⠝ ⡺⠁⠇⠞⠓⠑⠗ ⠎⠏⠊⠇⠇⠑⠙⠑ ⠏⠡ ⠭⠽⠇⠕⠋⠕⠝⠄'
+
+# -------
+# Grade 1
+# -------
+
+table: {language: da, grade: 1, dots: 8, version: 1993, __assert-match: da-dk-g18_1993.ctb}
+flags: {testmode: bothDirections}
+tests:
+
+# Characters from 0x21 to 0xff
+
+ - [' ', ' ']
+ - ['"', '⠶']
+ - ['$', '⣲']
+ - ['%', '⣚']
+ - ['&', '⢯']
+ - ['''', '⠈']
+ - ['(', '⢦']
+ - [')', '⢴']
+ - ['*', '⠔']
+ - ['+', '⢖']
+ - [',', '⠂']
+ - ['-', '⢤']
+ - ['.', '⠄']
+ - ['/', '⢌']
+ - ['0', '⢚']
+ - ['1', '⢁']
+ - ['2', '⢃']
+ - ['3', '⢉']
+ - ['4', '⢙']
+ - ['5', '⢑']
+ - ['6', '⢋']
+ - ['7', '⢛']
+ - ['8', '⢓']
+ - ['9', '⢊']
+ - [':', '⠒']
+ - [';', '⠆']
+ - ['<', '⢔']
+ - ['=', '⢶']
+ - ['>', '⡢']
+ - ['?', '⠢']
+ - ['@', '⣈']
+ - ['A', '⡁']
+ - ['B', '⡃']
+ - ['C', '⡉']
+ - ['D', '⡙']
+ - ['E', '⡑']
+ - ['F', '⡋']
+ - ['G', '⡛']
+ - ['H', '⡓']
+ - ['I', '⡊']
+ - ['J', '⡚']
+ - ['K', '⡅']
+ - ['L', '⡇']
+ - ['M', '⡍']
+ - ['N', '⡝']
+ - ['O', '⡕']
+ - ['P', '⡏']
+ - ['Q', '⡟']
+ - ['R', '⡗']
+ - ['S', '⡎']
+ - ['T', '⡞']
+ - ['U', '⡥']
+ - ['V', '⡧']
+ - ['W', '⡺']
+ - ['X', '⡭']
+ - ['Y', '⡽']
+ - ['Z', '⡵']
+ - ['[', '⣦']
+ - ['\\', '⡌']
+ - [']', '⣴']
+ - ['^', '⢏']
+ - ['_', '⣤']
+ - ['`', '⠐']
+ - ['a', '⠁']
+ - ['b', '⠃']
+ - ['c', '⠉']
+ - ['d', '⠙']
+ - ['e', '⠑']
+ - ['f', '⠋']
+ - ['g', '⠛']
+ - ['h', '⠓']
+ - ['i', '⠊']
+ - ['j', '⠚']
+ - ['k', '⠅']
+ - ['l', '⠇']
+ - ['m', '⠍']
+ - ['n', '⠝']
+ - ['o', '⠕']
+ - ['p', '⠏']
+ - ['q', '⠟']
+ - ['r', '⠗']
+ - ['s', '⠎']
+ - ['t', '⠞']
+ - ['u', '⠥']
+ - ['v', '⠧']
+ - ['w', '⠺']
+ - ['x', '⠭']
+ - ['y', '⠽']
+ - ['z', '⠵']
+ - ['{', '⣧']
+ - ['|', '⢸']
+ - ['}', '⣼']
+ - ['~', '⡨']
+ - ['€', '⣑']
+ - ['‚', '⡘']
+ - ['ƒ', '⢐']
+ - ['„', '⣆']
+ - ['…', '⠠⠄⠄⠄']
+ - ['†', '⡖']
+ - ['‡', '⣖']
+ - ['ˆ', '⣰']
+ - ['‰', '⣺']
+ - ['Š', '⣎']
+ - ['‹', '⠸']
+ - ['Œ', '⣕']
+ - ['Ž', '⡬']
+ - ['‘', '⡈']
+ - ['’', '⢈']
+ - ['“', '⡆']
+ - ['”', '⢰']
+ - ['•', '⡄']
+ - ['–', '⠠⠤']
+ - ['—', '⠠⡤']
+ - ['˜', '⠨']
+ - ['™', '⣞']
+ - ['š', '⢎']
+ - ['›', '⡸']
+ - ['œ', '⢕']
+ - ['ž', '⠬']
+ - ['Ÿ', '⣾']
+ - [' ', '⢞']
+ - ['¡', '⠲']
+ - ['¢', '⣒']
+ - ['£', '⢇']
+ - ['¤', '⡦']
+ - ['¥', '⡠']
+ - ['¦', '⣌']
+ - ['§', '⣐']
+ - ['¨', '⠰']
+ - ['©', '⣭']
+ - ['ª', '⣮']
+ - ['«', '⡐']
+ - ['¬', '⡼']
+ - ['', '⣄']
+ - ['®', '⣗']
+ - ['¯', '⡶']
+ - ['°', '⠴']
+ - ['±', '⢟']
+ - ['²', '⢆']
+ - ['³', '⢒']
+ - ['´', '⢨']
+ - ['µ', '⠦']
+ - ['¶', '⢿']
+ - ['·', '⢄']
+ - ['¸', '⣨']
+ - ['¹', '⢂']
+ - ['º', '⣿']
+ - ['»', '⡰']
+ - ['¼', '⢝']
+ - ['½', '⢘']
+ - ['¾', '⠼']
+ - ['À', '⡷']
+ - ['Á', '⣷']
+ - ['Â', '⣡']
+ - ['Ã', '⣩']
+ - ['Ä', '⣜']
+ - ['Å', '⡡']
+ - ['Æ', '⡜']
+ - ['Ç', '⡯']
+ - ['È', '⡮']
+ - ['É', '⡿']
+ - ['Ê', '⡣']
+ - ['Ë', '⡫']
+ - ['Ì', '⣱']
+ - ['Í', '⣣']
+ - ['Î', '⡩']
+ - ['Ï', '⡻']
+ - ['Ð', '⣽']
+ - ['Ñ', '⣻']
+ - ['Ò', '⣫']
+ - ['Ó', '⣬']
+ - ['Ô', '⡹']
+ - ['Õ', '⣹']
+ - ['Ö', '⣪']
+ - ['×', '⢭']
+ - ['Ø', '⡪']
+ - ['Ù', '⡾']
+ - ['Ú', '⣳']
+ - ['Û', '⡱']
+ - ['Ü', '⡳']
+ - ['Ý', '⣍']
+ - ['Þ', '⣅']
+ - ['ß', '⢮']
+ - ['à', '⠷']
+ - ['á', '⢷']
+ - ['â', '⢡']
+ - ['ã', '⢩']
+ - ['ä', '⢜']
+ - ['å', '⠡']
+ - ['æ', '⠜']
+ - ['ç', '⠯']
+ - ['è', '⠮']
+ - ['é', '⠿']
+ - ['ê', '⠣']
+ - ['ë', '⠫']
+ - ['ì', '⢱']
+ - ['í', '⢣']
+ - ['î', '⠩']
+ - ['ï', '⠻']
+ - ['ð', '⢽']
+ - ['ñ', '⢻']
+ - ['ò', '⢫']
+ - ['ó', '⢬']
+ - ['ô', '⠹']
+ - ['õ', '⢹']
+ - ['ö', '⢪']
+ - ['÷', '⢲']
+ - ['ø', '⠪']
+ - ['ù', '⠾']
+ - ['ú', '⢳']
+ - ['û', '⠱']
+ - ['ü', '⠳']
+ - ['ý', '⢍']
+ - ['þ', '⢅']
+ - ['ÿ', '⢾']
+
+# Misc Unicode chars
+# For each accented letter, the first occurring instance is chosen for back-translation.
+# There are no rules about this in the specs of Danish Braille,
+# So the choice is arbitrary and may change over time.
+
+ - ['\x0100\x0101', '⠐⡁⠐⠁']
+ - ['\x0106\x0107', '⠐⡉⠐⠉']
+ - ['\x010e\x010f', '⠐⡙⠐⠙']
+ - ['\x0112\x0113', '⠐⡑⠐⠑']
+ - ['\x011c\x011d', '⠐⡛⠐⠛']
+ - ['\x0124\x0125', '⠐⡓⠐⠓']
+ - ['\x0128\x0129', '⠐⡊⠐⠊']
+ - ['\x0134\x0135', '⠐⡚⠐⠚']
+ - ['\x0136\x0137', '⠐⡅⠐⠅']
+ - ['\x0138', '⠐⠟']
+ - ['\x0139\x013a', '⠐⡇⠐⠇']
+ - ['\x0143\x0144', '⠐⡝⠐⠝']
+ - ['\x014c\x014d', '⠐⡕⠐⠕']
+ - ['\x0154\x0155', '⠐⡗⠐⠗']
+ - ['\x015a\x015b', '⠐⡎⠐⠎']
+ - ['\x0162\x0163', '⠐⡞⠐⠞']
+ - ['\x0168\x0169', '⠐⡥⠐⠥']
+ - ['\x0174\x0175', '⠐⡺⠐⠺']
+ - ['\x0176\x0177', '⠐⡽⠐⠽']
+ - ['\x0179\x017a', '⠐⡵⠐⠵']
+
+# Greek letters (with dots 458 as prefix)
+
+ - ['\x0386\x03ac', '⢘⠐⡁⢘⠐⠁']
+ - ['\x0388\x03ad', '⢘⠐⡑⢘⠐⠑']
+ - ['\x0389\x03ae', '⢘⠐⡱⢘⠐⠱']
+ - ['\x038a\x03af', '⢘⠐⡊⢘⠐⠊']
+ - ['\x038c\x03cc', '⢘⠐⡕⢘⠐⠕']
+ - ['\x038e\x03cd', '⢘⠐⡥⢘⠐⠥']
+ - ['\x038f\x03ce', '⢘⠐⡺⢘⠐⠺']
+ - ['\x0391\x03b1', '⢘⡁⢘⠁']
+ - ['\x0392\x03b2', '⢘⡃⢘⠃']
+ - ['\x0393\x03b3', '⢘⡛⢘⠛']
+ - ['\x0394\x03b4', '⢘⡙⢘⠙']
+ - ['\x0395\x03b5', '⢘⡑⢘⠑']
+ - ['\x0396\x03b6', '⢘⡵⢘⠵']
+ - ['\x0397\x03b7', '⢘⡱⢘⠱']
+ - ['\x0398\x03b8', '⢘⡹⢘⠹']
+ - ['\x0399\x03b9', '⢘⡊⢘⠊']
+ - ['\x039a\x03ba', '⢘⡅⢘⠅']
+ - ['\x039b\x03bb', '⢘⡇⢘⠇']
+ - ['\x039c\x03bc', '⢘⡍⢘⠍']
+ - ['\x039d\x03bd', '⢘⡝⢘⠝']
+ - ['\x039e\x03be', '⢘⡭⢘⠭']
+ - ['\x039f\x03bf', '⢘⡕⢘⠕']
+ - ['\x03a0\x03c0', '⢘⡏⢘⠏']
+ - ['\x03a1\x03c1', '⢘⡗⢘⠗']
+ - ['\x03a3\x03c3', '⢘⡎⢘⠎']
+ - ['\x03a4\x03c4', '⢘⡞⢘⠞']
+ - ['\x03a5\x03c5', '⢘⡥⢘⠥']
+ - ['\x03a6\x03c6', '⢘⡋⢘⠋']
+ - ['\x03a7\x03c7', '⢘⡯⢘⠯']
+ - ['\x03a8\x03c8', '⢘⡽⢘⠽']
+ - ['\x03a9\x03c9', '⢘⡺⢘⠺']
+
+# Punctuation and bullits
+
+ - ['\x2016', '⠘⢸']
+ - ['\x2017', '⠘⣤']
+
+# Arrows
+
+ - ['\x2190', '⠘⠳⠪']
+ - ['\x2191', '⠘⠳⠬']
+ - ['\x2192', '⠘⠳⠕']
+ - ['\x2193', '⠘⠳⠩']
+ - ['\x2194', '⠘⠳⠺⠗⠕']
+ - ['\x2196', '⠘⠳⠱']
+ - ['\x2197', '⠘⠳⠎']
+ - ['\x2198', '⠘⠳⠣']
+ - ['\x2199', '⠘⠳⠜']
+ - ['\x21D4', '⠘⠳⠺⠶⠗⠕']
+
+# Math signs (experimental)
+
+ - ['\x2200', '⠘⠁']
+ - ['\x2208', '⠘⠑']
+ - ['\x2213', '⠸⠤']
+ - ['\x221d', '⠸⠐⢶']
+ - ['\x2229', '⠨⠦']
+ - ['\x222a', '⠨⠖']
+ - ['\x2243', '⠸⠔']
+ - ['\x2245', '⠐⠘⠔']
+ - ['\x2248', '⠘⠔']
+ - ['\x224f', '⠘⠐⢶']
+ - ['\x2251', '⠨⠐⢶']
+ - ['\x2260', '⠐⢶⠈⠱']
+ - ['\x2261', '⠸⠿']
+ - ['\x2264', '⠸⢔']
+ - ['\x2265', '⠸⡢']
+ - ['\x226a', '⠨⢔']
+ - ['\x226b', '⠨⡢']
+ - ['\x22c5', '⠐⠲']
+
+# Pangram
+
+ - - 'Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Walther spillede på xylofon.'
+ - '⡟⠥⠊⠵⠙⠑⠇⠞⠁⠛⠑⠗⠝⠑ ⠎⠏⠊⠎⠞⠑ ⠚⠕⠗⠙⠃⠜⠗ ⠍⠑⠙ ⠋⠇⠪⠙⠑⠂ ⠍⠑⠝⠎ ⠉⠊⠗⠅⠥⠎⠅⠇⠕⠧⠝⠑⠝ ⡺⠁⠇⠞⠓⠑⠗ ⠎⠏⠊⠇⠇⠑⠙⠑ ⠏⠡ ⠭⠽⠇⠕⠋⠕⠝⠄'
+
+# Section sign
+
+ - ["§ 3", "⣐⢉"]
+ - ["§ 3:", "⣐⢉⠒"]
+
+# Characters and constructs which cannot be properly back-translated
+
+flags: {testmode: forward}
+tests:
+
+ - ['\x0102\x0103', '⠐⡁⠐⠁']
+ - ['\x0104\x0105', '⠐⡁⠐⠁']
+ - ['\x0108\x0109', '⠐⡉⠐⠉']
+ - ['\x010a\x010b', '⠐⡉⠐⠉']
+ - ['\x010c\x010d', '⠐⡉⠐⠉']
+ - ['\x0110\x0111', '⠐⡙⠐⠙']
+ - ['\x0114\x0115', '⠐⡑⠐⠑']
+ - ['\x0116\x0117', '⠐⡑⠐⠑']
+ - ['\x0118\x0119', '⠐⡑⠐⠑']
+ - ['\x011a\x011b', '⠐⡑⠐⠑']
+ - ['\x011e\x011f', '⠐⡛⠐⠛']
+ - ['\x0120\x0121', '⠐⡛⠐⠛']
+ - ['\x0122\x0123', '⠐⡛⠐⠛']
+ - ['\x0126\x0127', '⠐⡓⠐⠓']
+ - ['\x012a\x012b', '⠐⡊⠐⠊']
+ - ['\x012c\x012d', '⠐⡊⠐⠊']
+ - ['\x012e\x012f', '⠐⡊⠐⠊']
+ - ['\x0130\x0131', '⠐⡊⠐⠊']
+ - ['\x0132\x0133', '⡊⠚⠊⠚']
+ - ['\x013b\x013c', '⠐⡇⠐⠇']
+ - ['\x013d\x013e', '⠐⡇⠐⠇']
+ - ['\x013f\x0140', '⠐⡇⠐⠇']
+ - ['\x0141\x0142', '⠐⡇⠐⠇']
+ - ['\x0145\x0146', '⠐⡝⠐⠝']
+ - ['\x0147\x0148', '⠐⡝⠐⠝']
+ - ['\x0149', '⠈⠝']
+ - ['\x014a\x014b', '⠐⡝⠐⠝']
+ - ['\x014e\x014f', '⠐⡕⠐⠕']
+ - ['\x0150\x0151', '⠐⡕⠐⠕']
+ - ['\x0156\x0157', '⠐⡗⠐⠗']
+ - ['\x0158\x0159', '⠐⡗⠐⠗']
+ - ['\x015c\x015d', '⠐⡎⠐⠎']
+ - ['\x015e\x015f', '⠐⡎⠐⠎']
+ - ['\x0164\x0165', '⠐⡞⠐⠞']
+ - ['\x0166\x0167', '⠐⡞⠐⠞']
+ - ['\x016a\x016b', '⠐⡥⠐⠥']
+ - ['\x016c\x016d', '⠐⡥⠐⠥']
+ - ['\x016e\x016f', '⠐⡥⠐⠥']
+ - ['\x0170\x0171', '⠐⡥⠐⠥']
+ - ['\x0172\x0173', '⠐⡥⠐⠥']
+ - ['\x017b\x017c', '⠐⡵⠐⠵']
+ - ['\x017f', '⠐⠎']
+
+# Punctuation and bullits
+
+ - ['\x2000', ' ']
+ - ['\x2001', ' ']
+ - ['\x2002', ' ']
+ - ['\x2003', ' ']
+ - ['\x2004', ' ']
+ - ['\x2005', ' ']
+ - ['\x2006', ' ']
+ - ['\x2007', ' ']
+ - ['\x2008', ' ']
+ - ['\x2009', ' ']
+ - ['\x200a', ' ']
+ - ['\x2010', '⢤']
+ - ['\x2011', '⢤']
+ - ['\x2012', '⢤']
+ - ['\x201b', '⠈']
+ - ['\x201f', '⠶']
+ - ['\x2023', '⡄']
+ - ['\x202f', ' ']
+ - ['\x203c', '⠖⠖']
+ - ['\x203d', '⠢⠖']
+ - ['\x2043', '⡄']
+ - ['\x2047', '⠢⠢']
+ - ['\x2048', '⠢⠖']
+ - ['\x2049', '⠖⠢']
+ - ['\x204c', '⡄']
+ - ['\x204d', '⡄']
+
+# Geometrical shapes
+
+ - ['\x25e6', '⡄']
+
+# Emphasis
+
+ - # Bold line
+ - En linje med fed.
+ - ⠰⡑⠝ ⠇⠊⠝⠚⠑ ⠍⠑⠙ ⠋⠑⠙⠄⠰
+ - typeform:
+ bold: '+++++++++++++++++'
+ - # Bold word
+ - Et ord med fed.
+ - ⡑⠞ ⠰⠕⠗⠙⠰ ⠍⠑⠙ ⠋⠑⠙⠄
+ - typeform:
+ bold: ' +++ '
+ - # Bold letter
+ - Et bogstav med fed.
+ - ⡑⠞ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍⠑⠙ ⠋⠑⠙⠄
+ - typeform:
+ bold: ' + '
+
+ - # Italic line
+ - En linje med kursiv.
+ - ⠰⡑⠝ ⠇⠊⠝⠚⠑ ⠍⠑⠙ ⠅⠥⠗⠎⠊⠧⠄⠰
+ - typeform:
+ italic: '++++++++++++++++++++'
+ - # Italic word
+ - Et ord med kursiv.
+ - ⡑⠞ ⠰⠕⠗⠙⠰ ⠍⠑⠙ ⠅⠥⠗⠎⠊⠧⠄
+ - typeform:
+ italic: ' +++ '
+ - # Italic letter
+ - Et bogstav med kursiv.
+ - ⡑⠞ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍⠑⠙ ⠅⠥⠗⠎⠊⠧⠄
+ - typeform:
+ italic: ' + '
+
+ - # Underlined line
+ - En linje med understreget.
+ - ⠰⡑⠝ ⠇⠊⠝⠚⠑ ⠍⠑⠙ ⠥⠝⠙⠑⠗⠎⠞⠗⠑⠛⠑⠞⠄⠰
+ - typeform:
+ underline: '++++++++++++++++++++++++++'
+ - # Underlined word
+ - Et ord med understreget.
+ - ⡑⠞ ⠰⠕⠗⠙⠰ ⠍⠑⠙ ⠥⠝⠙⠑⠗⠎⠞⠗⠑⠛⠑⠞⠄
+ - typeform:
+ underline: ' +++ '
+ - # Underlined letter
+ - Et bogstav med understreget.
+ - ⡑⠞ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍⠑⠙ ⠥⠝⠙⠑⠗⠎⠞⠗⠑⠛⠑⠞⠄
+ - typeform:
+ underline: ' + '
+
+ - # Bold, italic and underlined line
+ - En linje med alt.
+ - ⠰⡑⠝ ⠇⠊⠝⠚⠑ ⠍⠑⠙ ⠁⠇⠞⠄⠰
+ - typeform:
+ bold: '+++++++++++++++++'
+ italic: '+++++++++++++++++'
+ underline: '+++++++++++++++++'
+ - # Bold, italic and underlined word
+ - Et ord med alt.
+ - ⡑⠞ ⠰⠕⠗⠙⠰ ⠍⠑⠙ ⠁⠇⠞⠄
+ - typeform:
+ bold: ' +++ '
+ italic: ' +++ '
+ underline: ' +++ '
+ - # Bold, italic and underlined letter
+ - Et bogstav med alt.
+ - ⡑⠞ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍⠑⠙ ⠁⠇⠞⠄
+ - typeform:
+ bold: ' + '
+ italic: ' + '
+ underline: ' + '
+
+# ---------
+# Grade 1.5
+# ---------
+
+table: {language: da, grade: 1.5, dots: 8, version: 1993, __assert-match: da-dk-g28l_1993.ctb}
+flags: {testmode: bothDirections}
+tests:
+
+# Characters from 0x21 to 0xff
+
+ - [' ', ' ']
+ - ['"', '⠶']
+ - ['$', '⣲']
+ - ['%', '⣚']
+ - ['&', '⢯']
+ - ['''', '⠈']
+ - ['(', '⢦']
+ - [')', '⢴']
+ - ['*', '⠠⠔']
+ - ['+', '⢖']
+ - [',', '⠂']
+ - ['-', '⢤']
+ - ['.', '⠄']
+ - ['/', '⢌']
+ - ['0', '⢚']
+ - ['1', '⢁']
+ - ['2', '⢃']
+ - ['3', '⢉']
+ - ['4', '⢙']
+ - ['5', '⢑']
+ - ['6', '⢋']
+ - ['7', '⢛']
+ - ['8', '⢓']
+ - ['9', '⢊']
+ - [':', '⠒']
+ - [';', '⠆']
+ - ['<', '⢔']
+ - ['=', '⢶']
+ - ['>', '⡢']
+ - ['?', '⠢']
+ - ['@', '⣈']
+ - ['A', '⠠⡁']
+ - ['B', '⠠⡃']
+ - ['C', '⠠⡉']
+ - ['D', '⠠⡙']
+ - ['E', '⠠⡑']
+ - ['F', '⠠⡋']
+ - ['G', '⠠⡛']
+ - ['H', '⠠⡓']
+ - ['I', '⡊']
+ - ['J', '⠠⡚']
+ - ['K', '⠠⡅']
+ - ['L', '⠠⡇']
+ - ['M', '⠠⡍']
+ - ['N', '⠠⡝']
+ - ['O', '⠠⡕']
+ - ['P', '⠠⡏']
+ - ['Q', '⠠⡟']
+ - ['R', '⠠⡗']
+ - ['S', '⠠⡎']
+ - ['T', '⠠⡞']
+ - ['U', '⠠⡥']
+ - ['V', '⠠⡧']
+ - ['W', '⠠⡺']
+ - ['X', '⠠⡭']
+ - ['Y', '⠠⡽']
+ - ['Z', '⠠⡵']
+ - ['[', '⣦']
+ - ['\\', '⠠⡌']
+ - [']', '⣴']
+ - ['^', '⢏']
+ - ['_', '⣤']
+ - ['`', '⠐']
+ - ['a', '⠠⠁']
+ - ['b', '⠠⠃']
+ - ['c', '⠠⠉']
+ - ['d', '⠠⠙']
+ - ['e', '⠠⠑']
+ - ['f', '⠠⠋']
+ - ['g', '⠠⠛']
+ - ['h', '⠠⠓']
+ - ['i', '⠊']
+ - ['j', '⠠⠚']
+ - ['k', '⠠⠅']
+ - ['l', '⠠⠇']
+ - ['m', '⠠⠍']
+ - ['n', '⠠⠝']
+ - ['o', '⠠⠕']
+ - ['p', '⠠⠏']
+ - ['q', '⠠⠟']
+ - ['r', '⠠⠗']
+ - ['s', '⠠⠎']
+ - ['t', '⠠⠞']
+ - ['u', '⠠⠥']
+ - ['v', '⠠⠧']
+ - ['w', '⠠⠺']
+ - ['x', '⠠⠭']
+ - ['y', '⠠⠽']
+ - ['z', '⠠⠵']
+ - ['{', '⣧']
+ - ['|', '⢸']
+ - ['}', '⣼']
+ - ['~', '⡨']
+ - ['€', '⣑']
+ - ['‚', '⡘']
+ - ['ƒ', '⢐']
+ - ['„', '⣆']
+ - ['…', '⠠⠄⠄⠄']
+ - ['†', '⠠⡖']
+ - ['‡', '⠠⣖']
+ - ['ˆ', '⠠⣰']
+ - ['‰', '⣺']
+ - ['Š', '⠠⣎']
+ - ['‹', '⠸']
+ - ['Œ', '⠠⣕']
+ - ['Ž', '⠠⡬']
+ - ['‘', '⡈']
+ - ['’', '⢈']
+ - ['“', '⡆']
+ - ['”', '⢰']
+ - ['•', '⡄']
+ - ['–', '⠠⠤']
+ - ['—', '⠠⡤']
+ - ['˜', '⠨']
+ - ['™', '⣞']
+ - ['š', '⠠⢎']
+ - ['›', '⡸']
+ - ['œ', '⠠⢕']
+ - ['ž', '⠠⠬']
+ - ['Ÿ', '⠠⣾']
+ - [' ', '⢞']
+ - ['¡', '⠠⠲', {xfail: true}]
+ - ['¢', '⣒']
+ - ['£', '⢇']
+ - ['¤', '⠠⡦']
+ - ['¥', '⡠']
+ - ['¦', '⣌']
+ - ['§', '⣐']
+ - ['¨', '⠠⠰']
+ - ['©', '⣭']
+ - ['ª', '⠠⣮']
+ - ['«', '⡐']
+ - ['¬', '⠠⡼']
+ - ['', '⠠⣄']
+ - ['®', '⣗']
+ - ['¯', '⡶']
+ - ['°', '⠠⠴', {xfail: true}]
+ - ['±', '⢟']
+ - ['²', '⢆']
+ - ['³', '⢒']
+ - ['´', '⢨']
+ - ['µ', '⠠⠦']
+ - ['¶', '⢿']
+ - ['·', '⢄']
+ - ['¸', '⣨']
+ - ['¹', '⢂']
+ - ['º', '⠠⣿']
+ - ['»', '⡰']
+ - ['¼', '⢝']
+ - ['½', '⢘']
+ - ['¾', '⠠⠼']
+ - ['À', '⠠⡷']
+ - ['Á', '⠠⣷']
+ - ['Â', '⠠⣡']
+ - ['Ã', '⠠⣩']
+ - ['Ä', '⠠⣜']
+ - ['Å', '⠠⡡']
+ - ['Æ', '⠠⡜']
+ - ['Ç', '⠠⡯']
+ - ['È', '⠠⡮']
+ - ['É', '⠠⡿']
+ - ['Ê', '⠠⡣']
+ - ['Ë', '⠠⡫']
+ - ['Ì', '⠠⣱']
+ - ['Í', '⠠⣣']
+ - ['Î', '⠠⡩']
+ - ['Ï', '⠠⡻']
+ - ['Ð', '⠠⣽']
+ - ['Ñ', '⠠⣻']
+ - ['Ò', '⠠⣫']
+ - ['Ó', '⠠⣬']
+ - ['Ô', '⠠⡹']
+ - ['Õ', '⠠⣹']
+ - ['Ö', '⠠⣪']
+ - ['×', '⢭']
+ - ['Ø', '⠠⡪']
+ - ['Ù', '⠠⡾']
+ - ['Ú', '⠠⣳']
+ - ['Û', '⠠⡱']
+ - ['Ü', '⠠⡳']
+ - ['Ý', '⠠⣍']
+ - ['Þ', '⠠⣅']
+ - ['ß', '⠠⢮']
+ - ['à', '⠠⠷']
+ - ['á', '⠠⢷']
+ - ['â', '⠠⢡']
+ - ['ã', '⠠⢩']
+ - ['ä', '⠠⢜']
+ - ['å', '⠠⠡']
+ - ['æ', '⠠⠜']
+ - ['ç', '⠠⠯']
+ - ['è', '⠠⠮']
+ - ['é', '⠠⠿']
+ - ['ê', '⠠⠣']
+ - ['ë', '⠠⠫']
+ - ['ì', '⠠⢱']
+ - ['í', '⠠⢣']
+ - ['î', '⠠⠩']
+ - ['ï', '⠠⠻']
+ - ['ð', '⠠⢽']
+ - ['ñ', '⠠⢻']
+ - ['ò', '⠠⢫']
+ - ['ó', '⠠⢬']
+ - ['ô', '⠠⠹']
+ - ['õ', '⠠⢹']
+ - ['ö', '⠠⢪']
+ - ['÷', '⢲']
+ - ['ø', '⠠⠪']
+ - ['ù', '⠠⠾']
+ - ['ú', '⠠⢳']
+ - ['û', '⠠⠱']
+ - ['ü', '⠠⠳']
+ - ['ý', '⠠⢍']
+ - ['þ', '⠠⢅']
+ - ['ÿ', '⠠⢾']
+
+# Misc Unicode chars
+# For each accented letter, the first occurring instance is chosen for back-translation.
+# There are no rules about this in the specs of Danish Braille,
+# So the choice is arbitrary and may change over time.
+
+ - ['\x0100\x0101', '⠐⡁⠐⠁']
+ - ['\x0106\x0107', '⠐⡉⠐⠉']
+ - ['\x010e\x010f', '⠐⡙⠐⠙']
+ - ['\x0112\x0113', '⠐⡑⠐⠑']
+ - ['\x011c\x011d', '⠐⡛⠐⠛']
+ - ['\x0124\x0125', '⠐⡓⠐⠓']
+ - ['\x0128\x0129', '⠐⡊⠐⠊']
+ - ['\x0134\x0135', '⠐⡚⠐⠚']
+ - ['\x0136\x0137', '⠐⡅⠐⠅']
+ - ['\x0138', '⠐⠟']
+ - ['\x0139\x013a', '⠐⡇⠐⠇']
+ - ['\x0143\x0144', '⠐⡝⠐⠝']
+ - ['\x014c\x014d', '⠐⡕⠐⠕']
+ - ['\x0154\x0155', '⠐⡗⠐⠗']
+ - ['\x015a\x015b', '⠐⡎⠐⠎']
+ - ['\x0162\x0163', '⠐⡞⠐⠞']
+ - ['\x0168\x0169', '⠐⡥⠐⠥']
+ - ['\x0174\x0175', '⠐⡺⠐⠺']
+ - ['\x0176\x0177', '⠐⡽⠐⠽']
+ - ['\x0179\x017a', '⠐⡵⠐⠵']
+
+# Greek letters (with dots 458 as prefix)
+
+ - ['\x0386\x03ac', '⢘⠐⡁⢘⠐⠁', {xfail: {forward: true}}]
+ - ['\x0388\x03ad', '⢘⠐⡑⢘⠐⠑', {xfail: {forward: true}}]
+ - ['\x0389\x03ae', '⢘⠐⡱⢘⠐⠱', {xfail: {forward: true}}]
+ - ['\x038a\x03af', '⢘⠐⡊⢘⠐⠊', {xfail: {forward: true}}]
+ - ['\x038c\x03cc', '⢘⠐⡕⢘⠐⠕', {xfail: {forward: true}}]
+ - ['\x038e\x03cd', '⢘⠐⡥⢘⠐⠥', {xfail: {forward: true}}]
+ - ['\x038f\x03ce', '⢘⠐⡺⢘⠐⠺', {xfail: {forward: true}}]
+ - ['\x0391\x03b1', '⢘⡁⢘⠁', {xfail: {forward: true}}]
+ - ['\x0392\x03b2', '⢘⡃⢘⠃', {xfail: {forward: true}}]
+ - ['\x0393\x03b3', '⢘⡛⢘⠛', {xfail: {forward: true}}]
+ - ['\x0394\x03b4', '⢘⡙⢘⠙', {xfail: {forward: true}}]
+ - ['\x0395\x03b5', '⢘⡑⢘⠑', {xfail: {forward: true}}]
+ - ['\x0396\x03b6', '⢘⡵⢘⠵', {xfail: {forward: true}}]
+ - ['\x0397\x03b7', '⢘⡱⢘⠱', {xfail: {forward: true}}]
+ - ['\x0398\x03b8', '⢘⡹⢘⠹', {xfail: {forward: true}}]
+ - ['\x0399\x03b9', '⢘⡊⢘⠊', {xfail: {forward: true}}]
+ - ['\x039a\x03ba', '⢘⡅⢘⠅', {xfail: {forward: true}}]
+ - ['\x039b\x03bb', '⢘⡇⢘⠇', {xfail: {forward: true}}]
+ - ['\x039c\x03bc', '⢘⡍⢘⠍', {xfail: {forward: true}}]
+ - ['\x039d\x03bd', '⢘⡝⢘⠝', {xfail: {forward: true}}]
+ - ['\x039e\x03be', '⢘⡭⢘⠭', {xfail: {forward: true}}]
+ - ['\x039f\x03bf', '⢘⡕⢘⠕', {xfail: {forward: true}}]
+ - ['\x03a0\x03c0', '⢘⡏⢘⠏', {xfail: {forward: true}}]
+ - ['\x03a1\x03c1', '⢘⡗⢘⠗', {xfail: {forward: true}}]
+ - ['\x03a3\x03c3', '⢘⡎⢘⠎', {xfail: {forward: true}}]
+ - ['\x03a4\x03c4', '⢘⡞⢘⠞', {xfail: {forward: true}}]
+ - ['\x03a5\x03c5', '⢘⡥⢘⠥', {xfail: {forward: true}}]
+ - ['\x03a6\x03c6', '⢘⡋⢘⠋', {xfail: {forward: true}}]
+ - ['\x03a7\x03c7', '⢘⡯⢘⠯', {xfail: {forward: true}}]
+ - ['\x03a8\x03c8', '⢘⡽⢘⠽', {xfail: {forward: true}}]
+ - ['\x03a9\x03c9', '⢘⡺⢘⠺', {xfail: {forward: true}}]
+
+# Punctuation and bullits
+
+ - ['\x2016', '⠘⢸']
+ - ['\x2017', '⠘⣤']
+
+# Arrows
+
+ - ['\x2190', '⠘⠳⠪']
+ - ['\x2191', '⠘⠳⠬']
+ - ['\x2192', '⠘⠳⠕']
+ - ['\x2193', '⠘⠳⠩']
+ - ['\x2194', '⠘⠳⠺⠗⠕']
+ - ['\x2196', '⠘⠳⠱']
+ - ['\x2197', '⠘⠳⠎']
+ - ['\x2198', '⠘⠳⠣']
+ - ['\x2199', '⠘⠳⠜']
+ - ['\x21D4', '⠘⠳⠺⠶⠗⠕']
+
+# Math signs (experimental)
+
+ - ['\x2200', '⠘⠁']
+ - ['\x2208', '⠘⠑']
+ - ['\x2213', '⠸⠤']
+ - ['\x221d', '⠸⠐⢶']
+ - ['\x2229', '⠨⠦']
+ - ['\x222a', '⠨⠖']
+ - ['\x2243', '⠸⠔']
+ - ['\x2245', '⠐⠘⠔']
+ - ['\x2248', '⠘⠔']
+ - ['\x224f', '⠘⠐⢶']
+ - ['\x2251', '⠨⠐⢶']
+ - ['\x2260', '⠐⢶⠈⠱']
+ - ['\x2261', '⠸⠿']
+ - ['\x2264', '⠸⢔']
+ - ['\x2265', '⠸⡢']
+ - ['\x226a', '⠨⢔']
+ - ['\x226b', '⠨⡢']
+ - ['\x22c5', '⠐⠲']
+
+# Pangram
+
+ - - 'Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Walther spillede på xylofon.'
+ - '⠠⡟⠥⠊⠠⠵⠙⠑⠇⠞⠁⠛⠑⠗⠝⠑ ⠎⠏⠊⠎⠞⠑ ⠚⠕⠗⠙⠃⠜⠗ ⠍ ⠋⠇⠪⠙⠑⠂ ⠍⠑⠝⠎ ⠉⠊⠗⠅⠥⠎⠅⠇⠕⠧⠝⠑⠝ ⠠⡺⠁⠇⠞⠓⠑⠗ ⠎⠏⠊⠇⠇⠑⠙⠑ ⠏ ⠠⠭⠽⠇⠕⠋⠕⠝⠄'
+
+# No letsign before numbers
+
+ - ['v8', '⠠⠧⢓']
+ - ['A4', '⠠⡁⢙']
+ - ['Eleva2ren', '⡑⠇⠑⠧⠁⢃⠗⠑⠝']
+
+# URLs emails and file names
+
+ - ['$at', '⣲⠁⠞']
+ - ['\\at\\bliver', '⠠⡌⠁⠞⠠⡌⠃⠇⠊⠧⠑⠗']
+ - ['at@bliver.og', '⠁⠞⣈⠃⠇⠊⠧⠑⠗⠄⠕⠛']
+ - ['http://at.bliver.og', '⠓⠞⠞⠏⠒⢌⢌⠁⠞⠄⠃⠇⠊⠧⠑⠗⠄⠕⠛']
+ - ['www.at.bliver.og', '⠠⠺⠠⠺⠠⠺⠄⠁⠞⠄⠃⠇⠊⠧⠑⠗⠄⠕⠛']
+ - ['www.at.bliver.com', '⠠⠺⠠⠺⠠⠺⠄⠁⠞⠄⠃⠇⠊⠧⠑⠗⠄⠉⠕⠍']
+ - ['www.a.b.c', '⠠⠺⠠⠺⠠⠺⠄⠠⠁⠄⠠⠃⠄⠠⠉']
+
+# Section sign
+
+ - ["§ 3", "⣐⢉"]
+ - ["§ 3:", "⣐⢉⠒"]
+
+# Single cell word contractions
+
+ - ['At', '⡁']
+ - ['at', '⠁']
+ - ['Bliver', '⡃']
+ - ['bliver', '⠃']
+ - ['Og', '⡉']
+ - ['og', '⠉']
+ - ['Du', '⡙']
+ - ['du', '⠙']
+ - ['Eller', '⡑']
+ - ['eller', '⠑']
+ - ['For', '⡋']
+ - ['for', '⠋']
+ - ['Gør', '⡛']
+ - ['gør', '⠛']
+ - ['Har', '⡓']
+ - ['har', '⠓']
+ - ['Jeg', '⡚']
+ - ['jeg', '⠚']
+ - ['Kan', '⡅']
+ - ['kan', '⠅']
+ - ['Lige', '⡇']
+ - ['lige', '⠇']
+ - ['Med', '⡍']
+ - ['med', '⠍']
+ - ['Når', '⡝']
+ - ['når', '⠝']
+ - ['Op', '⡕']
+ - ['op', '⠕']
+ - ['På', '⡏']
+ - ['på', '⠏']
+ - ['Under', '⡟']
+ - ['under', '⠟']
+ - ['Rigtig', '⡗']
+ - ['rigtig', '⠗']
+ - ['Som', '⡎']
+ - ['som', '⠎']
+ - ['Til', '⡞']
+ - ['til', '⠞']
+ - ['Hun', '⡥']
+ - ['hun', '⠥']
+ - ['Ved', '⡧']
+ - ['ved', '⠧']
+ - ['Hvad', '⡺']
+ - ['hvad', '⠺']
+ - ['Over', '⡭']
+ - ['over', '⠭']
+ - ['Han', '⡽']
+ - ['han', '⠽']
+ - ['Efter', '⡵']
+ - ['efter', '⠵']
+ - ['Være', '⡜']
+ - ['være', '⠜']
+ - ['Før', '⡪']
+ - ['før', '⠪']
+ - ['Så', '⡡']
+ - ['så', '⠡']
+ - ['Den', '⡯']
+ - ['den', '⠯']
+ - ['Der', '⡾']
+ - ['der', '⠾']
+ - ['Det', '⡮']
+ - ['det', '⠮']
+ - ['De', '⡹']
+ - ['de', '⠹']
+ - ['En', '⡣']
+ - ['en', '⠣']
+ - ['Er', '⡱']
+ - ['er', '⠱']
+ - ['Et', '⡬']
+ - ['et', '⠬']
+ - ['Gennem', '⡻']
+ - ['gennem', '⠻']
+ - ['Hvor', '⡌']
+ - ['hvor', '⠌']
+ - ['Men', '⡩']
+ - ['men', '⠩']
+ - ['Ned', '⡫']
+ - ['ned', '⠫']
+ - ['Ret', '⡷']
+ - ['ret', '⠷']
+ - ['Skal', '⡿']
+ - ['skal', '⠿']
+ - ['Te', '⡳']
+ - ['te', '⠳']
+ - ['Ve', '⡼']
+ - ['ve', '⠼']
+
+# Capsnocont
+
+ - ['UNDER et', '⡥⡝⡙⡑⡗ ⠬']
+
+# No single cell contractions before or after dashes
+
+ - ['at-bliver', '⠁⠞⢤⠃⠇⠊⠧⠑⠗', {xfail: {forward: true}}]
+ - ['d-d-du', '⠠⠙⢤⠠⠙⢤⠙⠥', {xfail: {forward: true}}]
+
+# Combinations with slashes and other punctuation signs
+
+ - ["at!", "⠁⠖"]
+ - ["bliver!", "⠃⠖"]
+ - ["og!", "⠉⠖"]
+ - ['Han/hun', '⡽⢌⠥']
+ - ['han/hun', '⠽⢌⠥']
+ - ['Over/under', '⡭⢌⠟']
+ - ['over/under', '⠭⢌⠟']
+ - ['Til/fra', '⡞⢌⠋', {xfail: true}]
+ - ['til/fra', '⠞⢌⠋', {xfail: true}]
+
+# Combinations which require letsign
+
+ - ['1st', '⢁⠠⠎⠞']
+ - ['2nd', '⢃⠠⠝⠙', {xfail: {forward: true}}]
+ - ['1A', '⢁⠠⡁']
+ - ['1a', '⢁⠠⠁']
+ - ['2B', '⢃⠠⡃']
+ - ['2b', '⢃⠠⠃']
+
+# Characters and constructs which cannot be properly back-translated
+
+flags: {testmode: forward}
+tests:
+ - ['\x0102\x0103', '⠐⡁⠐⠁']
+ - ['\x0104\x0105', '⠐⡁⠐⠁']
+ - ['\x0108\x0109', '⠐⡉⠐⠉']
+ - ['\x010a\x010b', '⠐⡉⠐⠉']
+ - ['\x010c\x010d', '⠐⡉⠐⠉']
+ - ['\x0110\x0111', '⠐⡙⠐⠙']
+ - ['\x0114\x0115', '⠐⡑⠐⠑']
+ - ['\x0116\x0117', '⠐⡑⠐⠑']
+ - ['\x0118\x0119', '⠐⡑⠐⠑']
+ - ['\x011a\x011b', '⠐⡑⠐⠑']
+ - ['\x011e\x011f', '⠐⡛⠐⠛']
+ - ['\x0120\x0121', '⠐⡛⠐⠛']
+ - ['\x0122\x0123', '⠐⡛⠐⠛']
+ - ['\x0126\x0127', '⠐⡓⠐⠓']
+ - ['\x012a\x012b', '⠐⡊⠐⠊']
+ - ['\x012c\x012d', '⠐⡊⠐⠊']
+ - ['\x012e\x012f', '⠐⡊⠐⠊']
+ - ['\x0130\x0131', '⠐⡊⠐⠊']
+ - ['\x0132\x0133', '⡊⠚⠊⠚']
+ - ['\x013b\x013c', '⠐⡇⠐⠇']
+ - ['\x013d\x013e', '⠐⡇⠐⠇']
+ - ['\x013f\x0140', '⠐⡇⠐⠇']
+ - ['\x0141\x0142', '⠐⡇⠐⠇']
+ - ['\x0145\x0146', '⠐⡝⠐⠝']
+ - ['\x0147\x0148', '⠐⡝⠐⠝']
+ - ['\x0149', '⠈⠝']
+ - ['\x014a\x014b', '⠐⡝⠐⠝']
+ - ['\x014e\x014f', '⠐⡕⠐⠕']
+ - ['\x0150\x0151', '⠐⡕⠐⠕']
+ - ['\x0156\x0157', '⠐⡗⠐⠗']
+ - ['\x0158\x0159', '⠐⡗⠐⠗']
+ - ['\x015c\x015d', '⠐⡎⠐⠎']
+ - ['\x015e\x015f', '⠐⡎⠐⠎']
+ - ['\x0164\x0165', '⠐⡞⠐⠞']
+ - ['\x0166\x0167', '⠐⡞⠐⠞']
+ - ['\x016a\x016b', '⠐⡥⠐⠥']
+ - ['\x016c\x016d', '⠐⡥⠐⠥']
+ - ['\x016e\x016f', '⠐⡥⠐⠥']
+ - ['\x0170\x0171', '⠐⡥⠐⠥']
+ - ['\x0172\x0173', '⠐⡥⠐⠥']
+ - ['\x017b\x017c', '⠐⡵⠐⠵']
+ - ['\x017f', '⠐⠎']
+
+# Punctuation and bullits
+
+ - ['\x2000', ' ']
+ - ['\x2001', ' ']
+ - ['\x2002', ' ']
+ - ['\x2003', ' ']
+ - ['\x2004', ' ']
+ - ['\x2005', ' ']
+ - ['\x2006', ' ']
+ - ['\x2007', ' ']
+ - ['\x2008', ' ']
+ - ['\x2009', ' ']
+ - ['\x200a', ' ']
+ - ['\x2010', '⢤']
+ - ['\x2011', '⢤']
+ - ['\x2012', '⢤']
+ - ['\x201b', '⠈']
+ - ['\x201f', '⠶']
+ - ['\x2023', '⡄']
+ - ['\x202f', ' ']
+ - ['\x203c', '⠖⠖']
+ - ['\x203d', '⠢⠖']
+ - ['\x2043', '⡄']
+ - ['\x2047', '⠢⠢']
+ - ['\x2048', '⠢⠖']
+ - ['\x2049', '⠖⠢']
+ - ['\x204c', '⡄']
+ - ['\x204d', '⡄']
+
+# Geometrical shapes
+
+ - ['\x25e6', '⡄']
+
+# Emphasis
+
+ - # Bold line
+ - En linje med fed.
+ - ⠰⡣ ⠇⠊⠝⠚⠑ ⠍ ⠋⠑⠙⠄⠰
+ - typeform:
+ bold: '+++++++++++++++++'
+ - # Bold word
+ - Et ord med fed.
+ - ⡬ ⠰⠕⠗⠙⠰ ⠍ ⠋⠑⠙⠄
+ - typeform:
+ bold: ' +++ '
+ - # Bold letter
+ - Et bogstav med fed.
+ - ⡬ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍ ⠋⠑⠙⠄
+ - typeform:
+ bold: ' + '
+
+ - # Italic line
+ - En linje med kursiv.
+ - ⠰⡣ ⠇⠊⠝⠚⠑ ⠍ ⠅⠥⠗⠎⠊⠧⠄⠰
+ - typeform:
+ italic: '++++++++++++++++++++'
+ - # Italic word
+ - Et ord med kursiv.
+ - ⡬ ⠰⠕⠗⠙⠰ ⠍ ⠅⠥⠗⠎⠊⠧⠄
+ - typeform:
+ italic: ' +++ '
+ - # Italic letter
+ - Et bogstav med kursiv.
+ - ⡬ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍ ⠅⠥⠗⠎⠊⠧⠄
+ - typeform:
+ italic: ' + '
+
+ - # Underlined line
+ - En linje med understreget.
+ - ⠰⡣ ⠇⠊⠝⠚⠑ ⠍ ⠥⠝⠙⠑⠗⠎⠞⠗⠑⠛⠑⠞⠄⠰
+ - typeform:
+ underline: '++++++++++++++++++++++++++'
+ - # Underlined word
+ - Et ord med understreget.
+ - ⡬ ⠰⠕⠗⠙⠰ ⠍ ⠥⠝⠙⠑⠗⠎⠞⠗⠑⠛⠑⠞⠄
+ - typeform:
+ underline: ' +++ '
+ - # Underlined letter
+ - Et bogstav med understreget.
+ - ⡬ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍ ⠥⠝⠙⠑⠗⠎⠞⠗⠑⠛⠑⠞⠄
+ - typeform:
+ underline: ' + '
+
+ - # Bold, italic and underlined line
+ - En linje med alt.
+ - ⠰⡣ ⠇⠊⠝⠚⠑ ⠍ ⠁⠇⠞⠄⠰
+ - typeform:
+ bold: '+++++++++++++++++'
+ italic: '+++++++++++++++++'
+ underline: '+++++++++++++++++'
+ - # Bold, italic and underlined word
+ - Et ord med alt.
+ - ⡬ ⠰⠕⠗⠙⠰ ⠍ ⠁⠇⠞⠄
+ - typeform:
+ bold: ' +++ '
+ italic: ' +++ '
+ underline: ' +++ '
+ - # Bold, italic and underlined letter
+ - Et bogstav med alt.
+ - ⡬ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍ ⠁⠇⠞⠄
+ - typeform:
+ bold: ' + '
+ italic: ' + '
+ underline: ' + '
+
+# -------
+# Grade 2
+# -------
+
+table: {language: da, grade: 2, dots: 8, version: 1993, __assert-match: da-dk-g28_1993.ctb}
+flags: {testmode: bothDirections}
+tests:
+
+# Characters from 0x21 to 0xff
+
+ - [' ', ' ']
+ - ['"', '⠶']
+ - ['$', '⣲']
+ - ['%', '⣚']
+ - ['&', '⢯']
+ - ['''', '⠈']
+ - ['(', '⢦']
+ - [')', '⢴']
+ - ['*', '⠠⠔']
+ - ['+', '⢖']
+ - [',', '⠂']
+ - ['-', '⢤']
+ - ['.', '⠄']
+ - ['/', '⢌']
+ - ['0', '⢚']
+ - ['1', '⢁']
+ - ['2', '⢃']
+ - ['3', '⢉']
+ - ['4', '⢙']
+ - ['5', '⢑']
+ - ['6', '⢋']
+ - ['7', '⢛']
+ - ['8', '⢓']
+ - ['9', '⢊']
+ - [':', '⠒']
+ - [';', '⠆']
+ - ['<', '⢔']
+ - ['=', '⢶']
+ - ['>', '⡢']
+ - ['?', '⠢']
+ - ['@', '⣈']
+ - ['A', '⠠⡁']
+ - ['B', '⠠⡃']
+ - ['C', '⠠⡉']
+ - ['D', '⠠⡙']
+ - ['E', '⠠⡑']
+ - ['F', '⠠⡋']
+ - ['G', '⠠⡛']
+ - ['H', '⠠⡓']
+ - ['I', '⡊']
+ - ['J', '⠠⡚']
+ - ['K', '⠠⡅']
+ - ['L', '⠠⡇']
+ - ['M', '⠠⡍']
+ - ['N', '⠠⡝']
+ - ['O', '⠠⡕']
+ - ['P', '⠠⡏']
+ - ['Q', '⠠⡟']
+ - ['R', '⠠⡗']
+ - ['S', '⠠⡎']
+ - ['T', '⠠⡞']
+ - ['U', '⠠⡥']
+ - ['V', '⠠⡧']
+ - ['W', '⠠⡺']
+ - ['X', '⠠⡭']
+ - ['Y', '⠠⡽']
+ - ['Z', '⠠⡵']
+ - ['[', '⣦']
+ - ['\\', '⠠⡌']
+ - [']', '⣴']
+ - ['^', '⢏']
+ - ['_', '⣤']
+ - ['`', '⠐']
+ - ['a', '⠠⠁']
+ - ['b', '⠠⠃']
+ - ['c', '⠠⠉']
+ - ['d', '⠠⠙']
+ - ['e', '⠠⠑']
+ - ['f', '⠠⠋']
+ - ['g', '⠠⠛']
+ - ['h', '⠠⠓']
+ - ['i', '⠊']
+ - ['j', '⠠⠚']
+ - ['k', '⠠⠅']
+ - ['l', '⠠⠇']
+ - ['m', '⠠⠍']
+ - ['n', '⠠⠝']
+ - ['o', '⠠⠕']
+ - ['p', '⠠⠏']
+ - ['q', '⠠⠟']
+ - ['r', '⠠⠗']
+ - ['s', '⠠⠎']
+ - ['t', '⠠⠞']
+ - ['u', '⠠⠥']
+ - ['v', '⠠⠧']
+ - ['w', '⠠⠺']
+ - ['x', '⠠⠭']
+ - ['y', '⠠⠽']
+ - ['z', '⠠⠵']
+ - ['{', '⣧']
+ - ['|', '⢸']
+ - ['}', '⣼']
+ - ['~', '⡨']
+ - ['€', '⣑']
+ - ['‚', '⡘']
+ - ['ƒ', '⢐']
+ - ['„', '⣆']
+ - ['…', '⠠⠄⠄⠄']
+ - ['†', '⠠⡖']
+ - ['‡', '⠠⣖']
+ - ['ˆ', '⠠⣰']
+ - ['‰', '⣺']
+ - ['Š', '⠠⣎']
+ - ['‹', '⠸']
+ - ['Œ', '⠠⣕']
+ - ['Ž', '⠠⡬']
+ - ['‘', '⡈']
+ - ['’', '⢈']
+ - ['“', '⡆']
+ - ['”', '⢰']
+ - ['•', '⡄']
+ - ['–', '⠠⠤']
+ - ['—', '⠠⡤']
+ - ['˜', '⠨']
+ - ['™', '⣞']
+ - ['š', '⠠⢎']
+ - ['›', '⡸']
+ - ['œ', '⠠⢕']
+ - ['ž', '⠠⠬']
+ - ['Ÿ', '⠠⣾']
+ - [' ', '⢞']
+ - ['¡', '⠠⠲']
+ - ['¢', '⣒']
+ - ['£', '⢇']
+ - ['¤', '⠠⡦']
+ - ['¥', '⡠']
+ - ['¦', '⣌']
+ - ['§', '⣐']
+ - ['¨', '⠠⠰']
+ - ['©', '⣭']
+ - ['ª', '⠠⣮']
+ - ['«', '⡐']
+ - ['¬', '⠠⡼']
+ - ['', '⠠⣄']
+ - ['®', '⣗']
+ - ['¯', '⡶']
+ - ['°', '⠈⠴']
+ - ['±', '⢟']
+ - ['²', '⢆']
+ - ['³', '⢒']
+ - ['´', '⢨']
+ - ['µ', '⠠⠦']
+ - ['¶', '⢿']
+ - ['·', '⢄']
+ - ['¸', '⣨']
+ - ['¹', '⢂']
+ - ['º', '⠠⣿']
+ - ['»', '⡰']
+ - ['¼', '⢝']
+ - ['½', '⢘']
+ - ['¾', '⠠⠼']
+ - ['À', '⠠⡷']
+ - ['Á', '⠠⣷']
+ - ['Â', '⠠⣡']
+ - ['Ã', '⠠⣩']
+ - ['Ä', '⠠⣜']
+ - ['Å', '⠠⡡']
+ - ['Æ', '⠠⡜']
+ - ['Ç', '⠠⡯']
+ - ['È', '⠠⡮']
+ - ['É', '⠠⡿']
+ - ['Ê', '⠠⡣']
+ - ['Ë', '⠠⡫']
+ - ['Ì', '⠠⣱']
+ - ['Í', '⠠⣣']
+ - ['Î', '⠠⡩']
+ - ['Ï', '⠠⡻']
+ - ['Ð', '⠠⣽']
+ - ['Ñ', '⠠⣻']
+ - ['Ò', '⠠⣫']
+ - ['Ó', '⠠⣬']
+ - ['Ô', '⠠⡹']
+ - ['Õ', '⠠⣹']
+ - ['Ö', '⠠⣪']
+ - ['×', '⢭']
+ - ['Ø', '⠠⡪']
+ - ['Ù', '⠠⡾']
+ - ['Ú', '⠠⣳']
+ - ['Û', '⠠⡱']
+ - ['Ü', '⠠⡳']
+ - ['Ý', '⠠⣍']
+ - ['Þ', '⠠⣅']
+ - ['ß', '⠠⢮']
+ - ['à', '⠠⠷']
+ - ['á', '⠠⢷']
+ - ['â', '⠠⢡']
+ - ['ã', '⠠⢩']
+ - ['ä', '⠠⢜']
+ - ['å', '⠠⠡']
+ - ['æ', '⠠⠜']
+ - ['ç', '⠠⠯']
+ - ['è', '⠠⠮']
+ - ['é', '⠠⠿']
+ - ['ê', '⠠⠣']
+ - ['ë', '⠠⠫']
+ - ['ì', '⠠⢱']
+ - ['í', '⠠⢣']
+ - ['î', '⠠⠩']
+ - ['ï', '⠠⠻']
+ - ['ð', '⠠⢽']
+ - ['ñ', '⠠⢻']
+ - ['ò', '⠠⢫']
+ - ['ó', '⠠⢬']
+ - ['ô', '⠠⠹']
+ - ['õ', '⠠⢹']
+ - ['ö', '⠠⢪']
+ - ['÷', '⢲']
+ - ['ø', '⠠⠪']
+ - ['ù', '⠠⠾']
+ - ['ú', '⠠⢳']
+ - ['û', '⠠⠱']
+ - ['ü', '⠠⠳']
+ - ['ý', '⠠⢍']
+ - ['þ', '⠠⢅']
+ - ['ÿ', '⠠⢾']
+
+# Misc Unicode chars
+# For each accented letter, the first occurring instance is chosen for back-translation.
+# There are no rules about this in the specs of Danish Braille,
+# So the choice is arbitrary and may change over time.
+
+ - ['\x0100\x0101', '⠐⡁⠐⠁']
+ - ['\x0106\x0107', '⠐⡉⠐⠉']
+ - ['\x010e\x010f', '⠐⡙⠐⠙']
+ - ['\x0112\x0113', '⠐⡑⠐⠑']
+ - ['\x011c\x011d', '⠐⡛⠐⠛']
+ - ['\x0124\x0125', '⠐⡓⠐⠓']
+ - ['\x0128\x0129', '⠐⡊⠐⠊']
+ - ['\x0134\x0135', '⠐⡚⠐⠚']
+ - ['\x0136\x0137', '⠐⡅⠐⠅']
+ - ['\x0138', '⠐⠟']
+ - ['\x0139\x013a', '⠐⡇⠐⠇']
+ - ['\x0143\x0144', '⠐⡝⠐⠝']
+ - ['\x014c\x014d', '⠐⡕⠐⠕']
+ - ['\x0154\x0155', '⠐⡗⠐⠗']
+ - ['\x015a\x015b', '⠐⡎⠐⠎']
+ - ['\x0162\x0163', '⠐⡞⠐⠞']
+ - ['\x0168\x0169', '⠐⡥⠐⠥']
+ - ['\x0174\x0175', '⠐⡺⠐⠺']
+ - ['\x0176\x0177', '⠐⡽⠐⠽']
+ - ['\x0179\x017a', '⠐⡵⠐⠵']
+
+# Greek letters (with dots 458 as prefix)
+
+ - ['\x0386\x03ac', '⢘⠐⡁⢘⠐⠁', {xfail: {forward: true}}]
+ - ['\x0388\x03ad', '⢘⠐⡑⢘⠐⠑', {xfail: {forward: true}}]
+ - ['\x0389\x03ae', '⢘⠐⡱⢘⠐⠱', {xfail: {forward: true}}]
+ - ['\x038a\x03af', '⢘⠐⡊⢘⠐⠊', {xfail: {forward: true}}]
+ - ['\x038c\x03cc', '⢘⠐⡕⢘⠐⠕', {xfail: {forward: true}}]
+ - ['\x038e\x03cd', '⢘⠐⡥⢘⠐⠥', {xfail: {forward: true}}]
+ - ['\x038f\x03ce', '⢘⠐⡺⢘⠐⠺', {xfail: {forward: true}}]
+ - ['\x0391\x03b1', '⢘⡁⢘⠁', {xfail: {forward: true}}]
+ - ['\x0392\x03b2', '⢘⡃⢘⠃', {xfail: {forward: true}}]
+ - ['\x0393\x03b3', '⢘⡛⢘⠛', {xfail: {forward: true}}]
+ - ['\x0394\x03b4', '⢘⡙⢘⠙', {xfail: {forward: true}}]
+ - ['\x0395\x03b5', '⢘⡑⢘⠑', {xfail: {forward: true}}]
+ - ['\x0396\x03b6', '⢘⡵⢘⠵', {xfail: {forward: true}}]
+ - ['\x0397\x03b7', '⢘⡱⢘⠱', {xfail: {forward: true}}]
+ - ['\x0398\x03b8', '⢘⡹⢘⠹', {xfail: {forward: true}}]
+ - ['\x0399\x03b9', '⢘⡊⢘⠊', {xfail: {forward: true}}]
+ - ['\x039a\x03ba', '⢘⡅⢘⠅', {xfail: {forward: true}}]
+ - ['\x039b\x03bb', '⢘⡇⢘⠇', {xfail: {forward: true}}]
+ - ['\x039c\x03bc', '⢘⡍⢘⠍', {xfail: {forward: true}}]
+ - ['\x039d\x03bd', '⢘⡝⢘⠝', {xfail: {forward: true}}]
+ - ['\x039e\x03be', '⢘⡭⢘⠭', {xfail: {forward: true}}]
+ - ['\x039f\x03bf', '⢘⡕⢘⠕', {xfail: {forward: true}}]
+ - ['\x03a0\x03c0', '⢘⡏⢘⠏', {xfail: {forward: true}}]
+ - ['\x03a1\x03c1', '⢘⡗⢘⠗', {xfail: {forward: true}}]
+ - ['\x03a3\x03c3', '⢘⡎⢘⠎', {xfail: {forward: true}}]
+ - ['\x03a4\x03c4', '⢘⡞⢘⠞', {xfail: {forward: true}}]
+ - ['\x03a5\x03c5', '⢘⡥⢘⠥', {xfail: {forward: true}}]
+ - ['\x03a6\x03c6', '⢘⡋⢘⠋', {xfail: {forward: true}}]
+ - ['\x03a7\x03c7', '⢘⡯⢘⠯', {xfail: {forward: true}}]
+ - ['\x03a8\x03c8', '⢘⡽⢘⠽', {xfail: {forward: true}}]
+ - ['\x03a9\x03c9', '⢘⡺⢘⠺', {xfail: {forward: true}}]
+
+# Punctuation and bullits
+
+ - ['\x2016', '⠘⢸']
+ - ['\x2017', '⠘⣤']
+
+# Arrows
+
+ - ['\x2190', '⠘⠳⠪']
+ - ['\x2191', '⠘⠳⠬']
+ - ['\x2192', '⠘⠳⠕']
+ - ['\x2193', '⠘⠳⠩']
+ - ['\x2194', '⠘⠳⠺⠗⠕']
+ - ['\x2196', '⠘⠳⠱']
+ - ['\x2197', '⠘⠳⠎']
+ - ['\x2198', '⠘⠳⠣']
+ - ['\x2199', '⠘⠳⠜']
+ - ['\x21D4', '⠘⠳⠺⠶⠗⠕']
+
+# Math signs (experimental)
+
+ - ['\x2200', '⠘⠁']
+ - ['\x2208', '⠘⠑']
+ - ['\x2213', '⠸⠤']
+ - ['\x221d', '⠸⠐⢶']
+ - ['\x2229', '⠨⠦']
+ - ['\x222a', '⠨⠖']
+ - ['\x2243', '⠸⠔']
+ - ['\x2245', '⠐⠘⠔']
+ - ['\x2248', '⠘⠔']
+ - ['\x224f', '⠘⠐⢶']
+ - ['\x2251', '⠨⠐⢶']
+ - ['\x2260', '⠐⢶⠈⠱']
+ - ['\x2261', '⠸⠿']
+ - ['\x2264', '⠸⢔']
+ - ['\x2265', '⠸⡢']
+ - ['\x226a', '⠨⢔']
+ - ['\x226b', '⠨⡢']
+ - ['\x22c5', '⠐⠲']
+
+# Pangram
+
+ - - 'Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Walther spillede på xylofon.'
+ - '⠠⡟⠥⠊⠠⠵⠹⠇⠞⠁⠛⠱⠫ ⠎⠏⠊⠵⠑ ⠚⠭⠙⠃⠜⠗ ⠍ ⠋⠇⠪⠹⠂ ⠍⠣⠎ ⠉⠊⠗⠅⠥⠎⠅⠇⠕⠧⠝⠣ ⠠⡺⠁⠇⠞⠓⠱ ⠎⠏⠊⠇⠇⠑⠹ ⠏ ⠠⠭⠽⠇⠕⠋⠕⠝⠄'
+
+# Inverted exclamation
+
+ - ['¡Que lastima!', '⠠⠲⠠⡟⠥⠑ ⠇⠁⠵⠊⠍⠁⠖']
+
+# No letsign before numbers
+
+ - ['v8', '⠠⠧⢓']
+ - ['A4', '⠠⡁⢙']
+ - ['Eleva2ren', '⡑⠇⠑⠧⠁⢃⠗⠣']
+
+# URLs emails and file names
+
+ - ['$at', '⣲⠁⠞']
+ - ['\\at\\bliver', '⠠⡌⠁⠞⠠⡌⠃⠇⠊⠧⠑⠗']
+ - ['at@bliver.og', '⠁⠞⣈⠃⠇⠊⠧⠑⠗⠄⠕⠛']
+ - ['http://at.bliver.og', '⠓⠞⠞⠏⠒⢌⢌⠁⠞⠄⠃⠇⠊⠧⠑⠗⠄⠕⠛']
+ - ['www.at.bliver.og', '⠠⠺⠠⠺⠠⠺⠄⠁⠞⠄⠃⠇⠊⠧⠑⠗⠄⠕⠛']
+ - ['www.at.bliver.com', '⠠⠺⠠⠺⠠⠺⠄⠁⠞⠄⠃⠇⠊⠧⠑⠗⠄⠉⠕⠍']
+ - ['www.a.b.c', '⠠⠺⠠⠺⠠⠺⠄⠠⠁⠄⠠⠃⠄⠠⠉']
+ - ['test.txt', '⠳⠵⠄⠞⠠⠭⠞']
+
+# Section sign
+
+ - ["§ 3", "⣐⢉"]
+ - ["§ 3:", "⣐⢉⠒"]
+
+# Word contractions
+
+ - ['At', '⡁']
+ - ['at', '⠁']
+ - ['Aldrig', '⡁⠔']
+ - ['aldrig', '⠁⠔']
+ - ['aig', '⠁⠊⠛']
+ - ['Alle', '⡁⠑']
+ - ['alle', '⠁⠑']
+ - ['ae', '⠠⠁⠑']
+ - ['Allerede', '⡁⠇⠗']
+ - ['allerede', '⠁⠇⠗']
+ - ['alr', '⠠⠁⠇⠗']
+ - ['Alligevel', '⡁⠇⠧']
+ - ['alligevel', '⠁⠇⠧']
+ - ['alv', '⠠⠁⠇⠧']
+ - ['Altid', '⡁⠞⠙']
+ - ['altid', '⠁⠞⠙']
+ - ['atd', '⠠⠁⠞⠙']
+ - ['Altså', '⡁⠡']
+ - ['altså', '⠁⠡']
+ - ['aå', '⠠⠁⠡']
+ - ['Bliver', '⡃']
+ - ['bliver', '⠃']
+ - ['Og', '⡉']
+ - ['og', '⠉']
+ - ['Deres', '⡲']
+ - ['deres', '⠲']
+ - ['Du', '⡙']
+ - ['du', '⠙']
+ - ['Eller', '⡑']
+ - ['eller', '⠑']
+ - ['For', '⡋']
+ - ['for', '⠋']
+ - ['Gør', '⡛']
+ - ['gør', '⠛']
+ - ['Har', '⡓']
+ - ['har', '⠓']
+ - ['Jeg', '⡚']
+ - ['jeg', '⠚']
+ - ['Kan', '⡅']
+ - ['kan', '⠅']
+ - ['Lige', '⡇']
+ - ['lige', '⠇']
+ - ['Med', '⡍']
+ - ['med', '⠍']
+ - ['Når', '⡝']
+ - ['når', '⠝']
+ - ['Op', '⡕']
+ - ['op', '⠕']
+ - ['På', '⡏']
+ - ['på', '⠏']
+ - ['Under', '⡟']
+ - ['under', '⠟']
+ - ['Rigtig', '⡗']
+ - ['rigtig', '⠗']
+ - ['Som', '⡎']
+ - ['som', '⠎']
+ - ['Til', '⡞']
+ - ['til', '⠞']
+ - ['Hun', '⡥']
+ - ['hun', '⠥']
+ - ['Ved', '⡧']
+ - ['ved', '⠧']
+ - ['Hvad', '⡺']
+ - ['hvad', '⠺']
+ - ['Over', '⡭']
+ - ['over', '⠭']
+ - ['Han', '⡽']
+ - ['han', '⠽']
+ - ['Efter', '⡵']
+ - ['efter', '⠵']
+ - ['Være', '⡜']
+ - ['være', '⠜']
+ - ['Før', '⡪']
+ - ['før', '⠪']
+ - ['Så', '⡡']
+ - ['så', '⠡']
+ - ['Den', '⡯']
+ - ['den', '⠯']
+ - ['Der', '⡾']
+ - ['der', '⠾']
+ - ['Det', '⡮']
+ - ['det', '⠮']
+ - ['De', '⡹']
+ - ['de', '⠹']
+ - ['En', '⡣']
+ - ['en', '⠣']
+ - ['Er', '⡱']
+ - ['er', '⠱']
+ - ['Et', '⡬']
+ - ['et', '⠬']
+ - ['Gennem', '⡻']
+ - ['gennem', '⠻']
+ - ['Hvor', '⡌']
+ - ['hvor', '⠌']
+ - ['Men', '⡩']
+ - ['men', '⠩']
+ - ['Ned', '⡫']
+ - ['ned', '⠫']
+ - ['Ret', '⡷']
+ - ['ret', '⠷']
+ - ['Skal', '⡿']
+ - ['skal', '⠿']
+ - ['Te', '⡳']
+ - ['te', '⠳']
+ - ['Ve', '⡼']
+ - ['ve', '⠼']
+
+# Partword/nocross
+
+ - ['Denne', '⡯⠫']
+ - ['denne', '⠯⠫']
+ - ['Mændene', '⡍⠜⠝⠹⠫']
+ - ['mændene', '⠍⠜⠝⠹⠫']
+ - ['Derhos', '⡾⠓⠕⠎']
+ - ['derhos', '⠾⠓⠕⠎']
+ - ['Hunderace', '⡓⠥⠝⠹⠗⠁⠉⠑']
+ - ['hunderace', '⠓⠥⠝⠹⠗⠁⠉⠑']
+ - ['Dette', '⡮⠳']
+ - ['dette', '⠮⠳']
+ - ['Detalje', '⡹⠞⠁⠇⠚⠑']
+ - ['detalje', '⠹⠞⠁⠇⠚⠑']
+
+# Nocross multiple cells
+
+ - ['Endda', '⡑⠟⠙⠁']
+ - ['endda', '⠑⠟⠙⠁']
+ - ['Morgendag', '⡍⠭⠛⠣⠙⠁⠛']
+ - ['morgendag', '⠍⠭⠛⠣⠙⠁⠛']
+ - ['Gendanne', '⡛⠣⠙⠁⠝⠫']
+ - ['gendanne', '⠛⠣⠙⠁⠝⠫']
+ - ['Generelt', '⡻⠫⠷⠇⠞']
+ - ['generelt', '⠻⠫⠷⠇⠞']
+
+ - ['Fra!', '⡋⠗⠁⠖']
+ - ['fra!', '⠋⠗⠁⠖']
+ - ['!Fra', '⠠⠖⡖']
+ - ['!fra', '⠖⠋⠗⠁']
+ - ['''Af', '⠈⡴']
+ - ['''af', '⠈⠁⠋']
+
+# Capsnocont
+
+ - ['UNDER et', '⡥⡝⡙⡑⡗ ⠬']
+
+# No single cell contractions before or after dashes
+
+ - ['at-bliver', '⠁⠞⢤⠃']
+ - ['d-d-du', '⠠⠙⢤⠠⠙⢤⠙⠥']
+
+# Combinations with slashes and other punctuation signs
+
+ - ["at!", "⠁⠖"]
+ - ["bliver!", "⠃⠖"]
+ - ["og!", "⠉⠖"]
+ - ['Han/hun', '⡽⢌⠥']
+ - ['han/hun', '⠽⢌⠥']
+ - ['Over/under', '⡭⢌⠟']
+ - ['over/under', '⠭⢌⠟']
+ - ['Til/fra', '⡞⢌⠖']
+ - ['til/fra', '⠞⢌⠖']
+
+# Combinations which require letsign
+
+ - ['1st', '⢁⠠⠎⠞']
+ - ['2nd', '⢃⠝⠙']
+ - ['1A', '⢁⠠⡁']
+ - ['1a', '⢁⠠⠁']
+ - ['2B', '⢃⠠⡃']
+ - ['2b', '⢃⠠⠃']
+
+# Characters and constructs which cannot be properly back-translated
+
+flags: {testmode: forward}
+tests:
+ - ['\x0102\x0103', '⠐⡁⠐⠁']
+ - ['\x0104\x0105', '⠐⡁⠐⠁']
+ - ['\x0108\x0109', '⠐⡉⠐⠉']
+ - ['\x010a\x010b', '⠐⡉⠐⠉']
+ - ['\x010c\x010d', '⠐⡉⠐⠉']
+ - ['\x0110\x0111', '⠐⡙⠐⠙']
+ - ['\x0114\x0115', '⠐⡑⠐⠑']
+ - ['\x0116\x0117', '⠐⡑⠐⠑']
+ - ['\x0118\x0119', '⠐⡑⠐⠑']
+ - ['\x011a\x011b', '⠐⡑⠐⠑']
+ - ['\x011e\x011f', '⠐⡛⠐⠛']
+ - ['\x0120\x0121', '⠐⡛⠐⠛']
+ - ['\x0122\x0123', '⠐⡛⠐⠛']
+ - ['\x0126\x0127', '⠐⡓⠐⠓']
+ - ['\x012a\x012b', '⠐⡊⠐⠊']
+ - ['\x012c\x012d', '⠐⡊⠐⠊']
+ - ['\x012e\x012f', '⠐⡊⠐⠊']
+ - ['\x0130\x0131', '⠐⡊⠐⠊']
+ - ['\x0132\x0133', '⡊⠚⠊⠚']
+ - ['\x013b\x013c', '⠐⡇⠐⠇']
+ - ['\x013d\x013e', '⠐⡇⠐⠇']
+ - ['\x013f\x0140', '⠐⡇⠐⠇']
+ - ['\x0141\x0142', '⠐⡇⠐⠇']
+ - ['\x0145\x0146', '⠐⡝⠐⠝']
+ - ['\x0147\x0148', '⠐⡝⠐⠝']
+ - ['\x0149', '⠈⠝']
+ - ['\x014a\x014b', '⠐⡝⠐⠝']
+ - ['\x014e\x014f', '⠐⡕⠐⠕']
+ - ['\x0150\x0151', '⠐⡕⠐⠕']
+ - ['\x0156\x0157', '⠐⡗⠐⠗']
+ - ['\x0158\x0159', '⠐⡗⠐⠗']
+ - ['\x015c\x015d', '⠐⡎⠐⠎']
+ - ['\x015e\x015f', '⠐⡎⠐⠎']
+ - ['\x0164\x0165', '⠐⡞⠐⠞']
+ - ['\x0166\x0167', '⠐⡞⠐⠞']
+ - ['\x016a\x016b', '⠐⡥⠐⠥']
+ - ['\x016c\x016d', '⠐⡥⠐⠥']
+ - ['\x016e\x016f', '⠐⡥⠐⠥']
+ - ['\x0170\x0171', '⠐⡥⠐⠥']
+ - ['\x0172\x0173', '⠐⡥⠐⠥']
+ - ['\x017b\x017c', '⠐⡵⠐⠵']
+ - ['\x017f', '⠐⠎']
+
+# Punctuation and bullits
+
+ - ['\x2000', ' ']
+ - ['\x2001', ' ']
+ - ['\x2002', ' ']
+ - ['\x2003', ' ']
+ - ['\x2004', ' ']
+ - ['\x2005', ' ']
+ - ['\x2006', ' ']
+ - ['\x2007', ' ']
+ - ['\x2008', ' ']
+ - ['\x2009', ' ']
+ - ['\x200a', ' ']
+ - ['\x2010', '⢤']
+ - ['\x2011', '⢤']
+ - ['\x2012', '⢤']
+ - ['\x201b', '⠈']
+ - ['\x201f', '⠶']
+ - ['\x2023', '⡄']
+ - ['\x202f', ' ']
+ - ['\x203c', '⠖⠖']
+ - ['\x203d', '⠢⠖']
+ - ['\x2043', '⡄']
+ - ['\x2047', '⠢⠢']
+ - ['\x2048', '⠢⠖']
+ - ['\x2049', '⠖⠢']
+ - ['\x204c', '⡄']
+ - ['\x204d', '⡄']
+
+# Geometrical shapes
+
+ - ['\x25e6', '⡄']
+
+# Emphasis
+
+ - # Bold line
+ - En linje med fed.
+ - ⠰⡣ ⠇⠊⠝⠚⠑ ⠍ ⠋⠑⠙⠄⠰
+ - typeform:
+ bold: '+++++++++++++++++'
+ - # Bold word
+ - Et ord med fed.
+ - ⡬ ⠰⠭⠙⠰ ⠍ ⠋⠑⠙⠄
+ - typeform:
+ bold: ' +++ '
+ - # Bold letter
+ - Et bogstav med fed.
+ - ⡬ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍ ⠋⠑⠙⠄
+ - typeform:
+ bold: ' + '
+
+ - # Italic line
+ - En linje med kursiv.
+ - ⠰⡣ ⠇⠊⠝⠚⠑ ⠍ ⠅⠥⠗⠎⠊⠧⠄⠰
+ - typeform:
+ italic: '++++++++++++++++++++'
+ - # Italic word
+ - Et ord med kursiv.
+ - ⡬ ⠰⠭⠙⠰ ⠍ ⠅⠥⠗⠎⠊⠧⠄
+ - typeform:
+ italic: ' +++ '
+ - # Italic letter
+ - Et bogstav med kursiv.
+ - ⡬ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍ ⠅⠥⠗⠎⠊⠧⠄
+ - typeform:
+ italic: ' + '
+
+ - # Underlined line
+ - En linje med understreget.
+ - ⠰⡣ ⠇⠊⠝⠚⠑ ⠍ ⠥⠝⠾⠵⠷⠛⠬⠄⠰
+ - typeform:
+ underline: '++++++++++++++++++++++++++'
+ - # Underlined word
+ - Et ord med understreget.
+ - ⡬ ⠰⠭⠙⠰ ⠍ ⠥⠝⠾⠵⠷⠛⠬⠄
+ - typeform:
+ underline: ' +++ '
+ - # Underlined letter
+ - Et bogstav med understreget.
+ - ⡬ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍ ⠥⠝⠾⠵⠷⠛⠬⠄
+ - typeform:
+ underline: ' + '
+
+ - # Bold, italic and underlined line
+ - En linje med alt.
+ - ⠰⡣ ⠇⠊⠝⠚⠑ ⠍ ⠁⠇⠞⠄⠰
+ - typeform:
+ bold: '+++++++++++++++++'
+ italic: '+++++++++++++++++'
+ underline: '+++++++++++++++++'
+ - # Bold, italic and underlined word
+ - Et ord med alt.
+ - ⡬ ⠰⠭⠙⠰ ⠍ ⠁⠇⠞⠄
+ - typeform:
+ bold: ' +++ '
+ italic: ' +++ '
+ underline: ' +++ '
+ - # Bold, italic and underlined letter
+ - Et bogstav med alt.
+ - ⡬ ⠃⠕⠛⠰⠎⠰⠞⠁⠧ ⠍ ⠁⠇⠞⠄
+ - typeform:
+ bold: ' + '
+ italic: ' + '
+ underline: ' + '
+
+# Space characters
+
+display: |
+ include unicode-without-blank.dis
+ display a a
+
+table: {language: da, grade: 0, dots: 8, direction: both, version: 1993}
+table: {language: da, grade: 1, dots: 8, direction: both, version: 1993}
+table: {language: da, grade: 1.5, dots: 8, direction: both, version: 1993}
+table: {language: da, grade: 2, dots: 8, direction: both, version: 1993}
+table: {language: da, grade: 1, dots: 6, direction: forward, version: 1993}
+table: {language: da, grade: 1.5, dots: 6, direction: forward, version: 1993}
+table: {language: da, grade: 2, dots: 6, direction: forward, version: 1993}
+table: {language: da, grade: 1, dots: 6, direction: both, version: 1993}
+table: {language: da, grade: 1.5, dots: 6, direction: both, version: 1993}
+table: {language: da, grade: 2, dots: 6, direction: both, version: 1993}
+flags: {testmode: bothDirections}
+tests:
+ - ['\x0009', '⣊']
+ - ['\x000a', '⣠']
+ - ['\x000b', '⢥']
+ - ['\x000c', '⣇']
+ - ['\x000d', '⡒']
+ - ['\x0020', '\x0020']
+
+table: {language: da, grade: 0, dots: 8, direction: both, version: 1993}
+table: {language: da, grade: 1, dots: 8, direction: both, version: 1993}
+table: {language: da, grade: 1.5, dots: 8, direction: both, version: 1993}
+table: {language: da, grade: 2, dots: 8, direction: both, version: 1993}
+flags: {testmode: bothDirections}
+tests:
+ - ['\x00a0', '⢞']
+
+table: {language: da, grade: 1, dots: 6, direction: forward, version: 1993}
+table: {language: da, grade: 1.5, dots: 6, direction: forward, version: 1993}
+table: {language: da, grade: 2, dots: 6, direction: forward, version: 1993}
+table: {language: da, grade: 1, dots: 6, direction: both, version: 1993}
+table: {language: da, grade: 1.5, dots: 6, direction: both, version: 1993}
+table: {language: da, grade: 2, dots: 6, direction: both, version: 1993}
+flags: {testmode: bothDirections}
+tests:
+ - ['\x00a0', 'a']
diff --git a/LibLouis.NET.Test/nota-tables/README.md b/LibLouis.NET.Test/nota-tables/README.md
new file mode 100644
index 0000000..da6339e
--- /dev/null
+++ b/LibLouis.NET.Test/nota-tables/README.md
@@ -0,0 +1,31 @@
+# Nota's Danish tables, for the tests
+
+Kept in their own directory, and copied to `nota-tables/` in the output rather than `tables/`.
+
+`LibLouis.NET.Tables` copies the upstream table set into `tables/`. Five of the files here share a
+name with an upstream table and differ from it, so a single shared directory would make which copy
+a test gets depend on MSBuild item ordering. Separate directories mean every test states which set
+it means, and the upstream braille specs can be checked against upstream tables without this set
+shadowing them.
+
+## What these are
+
+A fork of an older upstream, not a patch on the current one. They add things upstream does not
+have, such as the `foreign` emphasis class behind `TypeForm.ForeignLanguage`, and they are missing
+things upstream has since fixed, such as the rules that remove the space between `§` and a following
+number. Do not assume a file here matches the upstream file of the same name in either direction.
+
+Two of them, `da-dk-g16-markers.ctb` and `da-dk-braillo.dis`, exist nowhere upstream, which is why
+the tests cannot simply use the upstream set.
+
+## These are not canonical
+
+The canonical Nota tables ship with the application. This is a copy, and a stale one: only seven of
+the thirty files are reachable from any test.
+
+Reachable: `da-dk-g16-markers.ctb`, `da-dk-braillo.dis`, `da-dk-g08.ctb`, `da-dk-g26.ctb`, and the
+three they include (`da-dk-6miscChars.cti`, `da-dk-octobraille.dis`, `da-dk-g2.dic`).
+
+The other twenty three are referenced by nothing. They are kept for now, but nothing keeps them in
+step with the application's copy, so treat any of them as evidence of nothing. Prefer adding a test
+that needs a file over adding a file that no test needs.
diff --git a/LibLouis.NET.Test/tables/da-dk-6miscChars.cti b/LibLouis.NET.Test/nota-tables/da-dk-6miscChars.cti
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-6miscChars.cti
rename to LibLouis.NET.Test/nota-tables/da-dk-6miscChars.cti
diff --git a/LibLouis.NET.Test/tables/da-dk-6miscChars_1993.cti b/LibLouis.NET.Test/nota-tables/da-dk-6miscChars_1993.cti
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-6miscChars_1993.cti
rename to LibLouis.NET.Test/nota-tables/da-dk-6miscChars_1993.cti
diff --git a/LibLouis.NET.Test/tables/da-dk-8miscChars.cti b/LibLouis.NET.Test/nota-tables/da-dk-8miscChars.cti
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-8miscChars.cti
rename to LibLouis.NET.Test/nota-tables/da-dk-8miscChars.cti
diff --git a/LibLouis.NET.Test/tables/da-dk-8miscChars_1993.cti b/LibLouis.NET.Test/nota-tables/da-dk-8miscChars_1993.cti
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-8miscChars_1993.cti
rename to LibLouis.NET.Test/nota-tables/da-dk-8miscChars_1993.cti
diff --git a/LibLouis.NET.Test/tables/da-dk-braillo.dis b/LibLouis.NET.Test/nota-tables/da-dk-braillo.dis
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-braillo.dis
rename to LibLouis.NET.Test/nota-tables/da-dk-braillo.dis
diff --git a/LibLouis.NET.Test/tables/da-dk-g08.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g08.ctb
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-g08.ctb
rename to LibLouis.NET.Test/nota-tables/da-dk-g08.ctb
diff --git a/LibLouis.NET.Test/tables/da-dk-g08_1993.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g08_1993.ctb
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-g08_1993.ctb
rename to LibLouis.NET.Test/nota-tables/da-dk-g08_1993.ctb
diff --git a/LibLouis.NET.Test/tables/da-dk-g16-crossword.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g16-crossword.ctb
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-g16-crossword.ctb
rename to LibLouis.NET.Test/nota-tables/da-dk-g16-crossword.ctb
diff --git a/LibLouis.NET.Test/tables/da-dk-g16-lit_1993.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g16-lit_1993.ctb
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-g16-lit_1993.ctb
rename to LibLouis.NET.Test/nota-tables/da-dk-g16-lit_1993.ctb
diff --git a/LibLouis.NET.Test/tables/da-dk-g16-markers.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g16-markers.ctb
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-g16-markers.ctb
rename to LibLouis.NET.Test/nota-tables/da-dk-g16-markers.ctb
diff --git a/LibLouis.NET.Test/tables/da-dk-g16.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g16.ctb
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-g16.ctb
rename to LibLouis.NET.Test/nota-tables/da-dk-g16.ctb
diff --git a/LibLouis.NET.Test/tables/da-dk-g16_1993-markers.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g16_1993-markers.ctb
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-g16_1993-markers.ctb
rename to LibLouis.NET.Test/nota-tables/da-dk-g16_1993-markers.ctb
diff --git a/LibLouis.NET.Test/tables/da-dk-g16_1993.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g16_1993.ctb
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-g16_1993.ctb
rename to LibLouis.NET.Test/nota-tables/da-dk-g16_1993.ctb
diff --git a/LibLouis.NET.Test/tables/da-dk-g18.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g18.ctb
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-g18.ctb
rename to LibLouis.NET.Test/nota-tables/da-dk-g18.ctb
diff --git a/LibLouis.NET.Test/tables/da-dk-g18_1993.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g18_1993.ctb
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-g18_1993.ctb
rename to LibLouis.NET.Test/nota-tables/da-dk-g18_1993.ctb
diff --git a/LibLouis.NET.Test/tables/da-dk-g2.dic b/LibLouis.NET.Test/nota-tables/da-dk-g2.dic
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-g2.dic
rename to LibLouis.NET.Test/nota-tables/da-dk-g2.dic
diff --git a/LibLouis.NET.Test/tables/da-dk-g26-lit_1993.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g26-lit_1993.ctb
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-g26-lit_1993.ctb
rename to LibLouis.NET.Test/nota-tables/da-dk-g26-lit_1993.ctb
diff --git a/LibLouis.NET.Test/tables/da-dk-g26.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g26.ctb
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-g26.ctb
rename to LibLouis.NET.Test/nota-tables/da-dk-g26.ctb
diff --git a/LibLouis.NET.Test/tables/da-dk-g26_1993.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g26_1993.ctb
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-g26_1993.ctb
rename to LibLouis.NET.Test/nota-tables/da-dk-g26_1993.ctb
diff --git a/LibLouis.NET.Test/tables/da-dk-g26l-lit.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g26l-lit.ctb
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-g26l-lit.ctb
rename to LibLouis.NET.Test/nota-tables/da-dk-g26l-lit.ctb
diff --git a/LibLouis.NET.Test/tables/da-dk-g26l-lit_1993.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g26l-lit_1993.ctb
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-g26l-lit_1993.ctb
rename to LibLouis.NET.Test/nota-tables/da-dk-g26l-lit_1993.ctb
diff --git a/LibLouis.NET.Test/tables/da-dk-g26l.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g26l.ctb
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-g26l.ctb
rename to LibLouis.NET.Test/nota-tables/da-dk-g26l.ctb
diff --git a/LibLouis.NET.Test/tables/da-dk-g26l_1993.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g26l_1993.ctb
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-g26l_1993.ctb
rename to LibLouis.NET.Test/nota-tables/da-dk-g26l_1993.ctb
diff --git a/LibLouis.NET.Test/tables/da-dk-g28.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g28.ctb
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-g28.ctb
rename to LibLouis.NET.Test/nota-tables/da-dk-g28.ctb
diff --git a/LibLouis.NET.Test/tables/da-dk-g28_1993.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g28_1993.ctb
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-g28_1993.ctb
rename to LibLouis.NET.Test/nota-tables/da-dk-g28_1993.ctb
diff --git a/LibLouis.NET.Test/tables/da-dk-g28l.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g28l.ctb
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-g28l.ctb
rename to LibLouis.NET.Test/nota-tables/da-dk-g28l.ctb
diff --git a/LibLouis.NET.Test/tables/da-dk-g28l_1993.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g28l_1993.ctb
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-g28l_1993.ctb
rename to LibLouis.NET.Test/nota-tables/da-dk-g28l_1993.ctb
diff --git a/LibLouis.NET.Test/tables/da-dk-g2_1993.dic b/LibLouis.NET.Test/nota-tables/da-dk-g2_1993.dic
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-g2_1993.dic
rename to LibLouis.NET.Test/nota-tables/da-dk-g2_1993.dic
diff --git a/LibLouis.NET.Test/tables/da-dk-octobraille.dis b/LibLouis.NET.Test/nota-tables/da-dk-octobraille.dis
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-octobraille.dis
rename to LibLouis.NET.Test/nota-tables/da-dk-octobraille.dis
diff --git a/LibLouis.NET.Test/tables/da-dk-octobraille_1993.dis b/LibLouis.NET.Test/nota-tables/da-dk-octobraille_1993.dis
similarity index 100%
rename from LibLouis.NET.Test/tables/da-dk-octobraille_1993.dis
rename to LibLouis.NET.Test/nota-tables/da-dk-octobraille_1993.dis