Build liblouis_nacl using gyp.

Tries to reland 237638 after fixing compiler warnings from a more recent compiler used on arm.

This cl ports the nacl wrapper to the chromium build system and adds local modifications from Chromevox to liblouis. The native library and braille tables are copied to the location in the resources output directory where chromevox can pick them up.

BUG=316353

Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=237638

Review URL: https://codereview.chromium.org/67283007

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@238548 0039d316-1c4b-4281-b951-d872f2087c98
parent deb2998a
......@@ -32,6 +32,7 @@ sys.path.insert(1, os.path.join(chrome_src, 'native_client', 'build'))
sys.path.insert(1, os.path.join(chrome_src, 'native_client_sdk', 'src',
'build_tools'))
sys.path.insert(1, os.path.join(chrome_src, 'remoting', 'tools', 'build'))
sys.path.insert(1, os.path.join(chrome_src, 'third_party', 'liblouis'))
sys.path.insert(1, os.path.join(chrome_src, 'third_party', 'WebKit',
'Source', 'build', 'scripts'))
......
......@@ -23,6 +23,9 @@
'<(PRODUCT_DIR)/nacl_helper_bootstrap<(EXECUTABLE_SUFFIX)',
'<(PRODUCT_DIR)/xdisplaycheck<(EXECUTABLE_SUFFIX)',
],
'isolate_dependency_untracked': [
'<(PRODUCT_DIR)/chromevox_test_data/',
],
},
}],
['OS=="linux" or OS=="mac"', {
......
......@@ -1668,7 +1668,17 @@
'test/data/nacl/nacl_test_data.gyp:*',
'../ppapi/native_client/native_client.gyp:nacl_irt',
'../ppapi/ppapi_untrusted.gyp:ppapi_nacl_tests',
'../ppapi/tests/extensions/extensions.gyp:ppapi_tests_extensions_socket'
'../ppapi/tests/extensions/extensions.gyp:ppapi_tests_extensions_socket',
],
'conditions': [
['OS=="linux"', {
'sources': [
'../third_party/liblouis/nacl_wrapper/liblouis_wrapper_browsertest.cc',
],
'dependencies': [
'../third_party/liblouis/liblouis_untrusted.gyp:liblouis_test_data',
],
}],
],
}],
['OS=="win" or OS=="linux"', {
......
{
"key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJ8Hl8K6R+n/hrPsN1ienxRU3GbL00wFHLJNML45MHwT+3PstgWf4EgC3wbyyTXFtbvJC+Hn14Hyltfhsa+cSraldNHeL+rl+FL04kE4uYHq8YhOYEtzUfg380+o7XV9oESKu9oLTeG9QuQCjmlp3MUqC9wm7ICjxR9flODClOkQIDAQAB",
"name": "liblouis_nacl tests",
"version": "0.1",
"manifest_version": 2,
"description": "test",
"background": {
"scripts": [ "test.js" ]
}
}
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var pass = chrome.test.callbackPass;
var TABLE_NAME = 'en-us-comp8.ctb';
var TEXT = 'hello';
// Translation of the above string as a hexadecimal sequence of cells.
var CELLS = '1311070715';
var pendingCallback = null;
var pendingMessageId = -1;
var nextMessageId = 0;
var naclEmbed = null;
function loadLibrary(callback) {
var embed = document.createElement('embed');
embed.src = 'liblouis_nacl.nmf';
embed.type = 'application/x-nacl';
embed.width = 0;
embed.height = 0;
embed.setAttribute('tablesdir', 'tables');
embed.addEventListener('load', function() {
console.log("liblouis loaded");
naclEmbed = embed;
callback();
}, false /* useCapture */);
embed.addEventListener('error', function() {
chrome.test.fail('liblouis load error');
}, false /* useCapture */);
embed.addEventListener('message', function(e) {
var reply = JSON.parse(e.data);
console.log('Message from liblouis: ' + e.data);
pendingCallback(reply);
}, false /* useCapture */);
document.body.appendChild(embed);
}
function rpc(command, args, callback) {
var messageId = '' + nextMessageId++;
args['command'] = command;
args['message_id'] = messageId;
var json = JSON.stringify(args)
console.log('Message to liblouis: ' + json);
naclEmbed.postMessage(json);
pendingCallback = callback;
pendingMessageId = messageId;
}
function expectSuccessReply(callback) {
return function(reply) {
chrome.test.assertEq(pendingMessageId, reply['in_reply_to']);
chrome.test.assertTrue(reply['error'] === undefined);
chrome.test.assertTrue(reply['success']);
if (callback) {
callback(reply);
}
};
}
loadLibrary(function() {
chrome.test.runTests([
function testGetTranslator() {
rpc('CheckTable', { 'table_name': TABLE_NAME},
pass(expectSuccessReply()));
},
function testTranslateString() {
rpc('Translate', { 'table_name': TABLE_NAME, 'text': TEXT},
pass(expectSuccessReply(function(reply) {
chrome.test.assertEq(CELLS, reply['cells']);
})));
},
function testBackTranslateString() {
rpc('BackTranslate', { 'table_name': TABLE_NAME, 'cells': CELLS},
pass(expectSuccessReply(function(reply) {
chrome.test.assertEq(TEXT, reply['text']);
})));
},
])});
......@@ -15,4 +15,13 @@ libloius is used in a native client binary in ChromeVox and not linked into
Chrome itself.
Local Modifications:
...
* Add manually created liblouis.h.
* On Android: log to logcat.
* Fix backtranslation to not output unicode braille patterns
(svn r838)
* Fix 3 letters in Danish 8 dot braille table, reverting part of svn r238.
* Fix out-of-bounds array access (code removed by upstream).
* Fix compiler warnings (part of svn r856).
* Add tables.json a list of tables with metadata.
* Add a wrapper to expose the library in native client.
#!/usr/bin/env python
# Copyright 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import os
import re
import sys
import json
import optparse
# Matches the include statement in the braille table files.
INCLUDE_RE = re.compile(r"^\s*include\s+([^#\s]+)")
def Error(msg):
print >> sys.stderr, 'liblouis_list_tables: %s' % msg
sys.exit(1)
def ToNativePath(pathname):
return os.path.sep.join(pathname.split('/'))
def LoadTablesFile(filename):
with open(ToNativePath(filename), 'r') as fh:
return json.load(fh)
def FindFile(filename, directories):
for d in directories:
fullname = '/'.join([d, filename])
if os.path.isfile(ToNativePath(fullname)):
return fullname
Error('File not found: %s' % filename)
def GetIncludeFiles(filename):
result = []
with open(ToNativePath(filename), 'r') as fh:
for line in fh.xreadlines():
match = INCLUDE_RE.match(line)
if match:
result.append(match.group(1))
return result
def ProcessFile(output_set, filename, directories):
fullname = FindFile(filename, directories)
if fullname in output_set:
return
output_set.add(fullname)
for include_file in GetIncludeFiles(fullname):
ProcessFile(output_set, include_file, directories)
def DoMain(argv):
"Entry point for gyp's pymod_do_main command."
parser = optparse.OptionParser()
# Give a clearer error message when this is used as a module.
parser.prog = 'liblouis_list_tables'
parser.set_usage('usage: %prog [options] listfile')
parser.add_option('-D', '--directory', dest='directories',
action='append', help='Where to search for table files')
(options, args) = parser.parse_args(argv)
if len(args) != 1:
parser.error('Expecting exactly one argument')
if not options.directories:
parser.error('At least one --directory option must be specified')
tables = LoadTablesFile(args[0])
output_set = set()
for table in tables:
ProcessFile(output_set, table['fileName'], options.directories)
return '\n'.join(output_set)
def main(argv):
print DoMain(argv[1:])
if __name__ == '__main__':
try:
sys.exit(main(sys.argv))
except KeyboardInterrupt:
Error('interrupted')
# Copyright 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
{
'variables': {
'braille_test_data_dir': '<(PRODUCT_DIR)/chromevox_test_data/braille',
'braille_chromevox_dir': '<(PRODUCT_DIR)/resources/chromeos/chromevox/chromevox/background/braille',
'table_files': [
'>!@pymod_do_main(liblouis_list_tables -D overrides/tables -D src/tables tables.json)',
],
},
# x86 targets build both 32 and 64 bit binaries by default. We only need
# the one that matches our target architecture.
'target_defaults': {
'conditions': [
['target_arch=="ia32"', {
'variables': {
'enable_x86_64': 0,
},
}],
['target_arch=="x64"', {
'variables': {
'enable_x86_32': 0,
},
}],
],
},
'includes': [
'../../build/common_untrusted.gypi',
],
'conditions': [
['disable_nacl==0 and disable_nacl_untrusted==0', {
'targets': [
{
'target_name': 'liblouis_untrusted',
'type': 'none',
'variables': {
'nacl_untrusted_build': 1,
'nlib_target': 'liblouis_untrusted.a',
'build_newlib': 1,
},
'compile_flags': [
'-Wno-switch',
'-Wno-unused-but-set-variable',
],
'include_dirs': [
'overrides/liblouis',
'src/liblouis',
'.',
],
'direct_dependent_settings': {
'include_dirs': [
'overrides',
],
},
'sources': [
'overrides/liblouis/config.h',
'overrides/liblouis/liblouis.h',
'overrides/liblouis/compileTranslationTable.c',
'src/liblouis/lou_backTranslateString.c',
'src/liblouis/lou_translateString.c',
'src/liblouis/transcommon.ci',
'src/liblouis/wrappers.c',
],
'dependencies': [
'../../native_client/tools.gyp:prep_toolchain',
],
},
{
'target_name': 'liblouis_nacl_wrapper_untrusted',
'type': 'none',
'variables': {
'nacl_untrusted_build': 1,
'nexe_target': 'liblouis_nacl',
'out_newlib64': '<(braille_test_data_dir)/>(nexe_target)_x86_64.nexe',
'out_newlib32': '<(braille_test_data_dir)/>(nexe_target)_x86_32.nexe',
'out_newlib_arm': '<(braille_test_data_dir)/>(nexe_target)_arm.nexe',
'build_newlib': 1,
'extra_args': [
'--strip-debug',
],
'nmf': '<(braille_test_data_dir)/>(nexe_target).nmf',
'target_conditions': [
['enable_x86_64==1', {
'nexe_files': ['>(out_newlib64)'],
}],
['enable_x86_32==1', {
'nexe_files': ['>(out_newlib32)'],
}],
['enable_arm==1', {
'nexe_files': ['>(out_newlib_arm)'],
}],
],
},
'sources': [
'nacl_wrapper/liblouis_instance.h',
'nacl_wrapper/liblouis_instance.cc',
'nacl_wrapper/liblouis_module.h',
'nacl_wrapper/liblouis_module.cc',
'nacl_wrapper/liblouis_wrapper.h',
'nacl_wrapper/liblouis_wrapper.cc',
'nacl_wrapper/translation_params.h',
'nacl_wrapper/translation_result.h',
],
'link_flags': [
'-lppapi',
'-lppapi_cpp',
'-llouis_untrusted',
'-ljsoncpp_untrusted',
'-lpthread',
'-lnacl_io',
],
'dependencies': [
'../../native_client/src/untrusted/nacl/nacl.gyp:nacl_lib',
'../../native_client/tools.gyp:prep_toolchain',
'../../native_client_sdk/native_client_sdk_untrusted.gyp:nacl_io_untrusted',
'../../ppapi/native_client/native_client.gyp:ppapi_lib',
'../../ppapi/ppapi_untrusted.gyp:ppapi_cpp_lib',
'../jsoncpp/jsoncpp_untrusted.gyp:jsoncpp_untrusted',
'liblouis_untrusted',
],
'actions': [
{
'action_name': 'Generate NEWLIB NMF',
'inputs': [
'>@(nexe_files)',
],
'outputs': ['>(nmf)'],
'action': [
'python',
'<(DEPTH)/native_client_sdk/src/tools/create_nmf.py',
'>@(_inputs)',
'--output=>(nmf)',
],
},
],
# Copy specific files into the product directory to avoid
# copying over the unstripped binary file.
# TODO(plundblad): Temporarily disabled while the rest of chromevox
# lands.
# 'copies': [
# {
# 'destination': '<(braille_chromevox_dir)',
# 'files': [
# '<(nmf)',
# '>@(nexe_files)',
# 'tables.json',
# ],
# },
# {
# 'destination': '<(braille_chromevox_dir)/tables',
# 'files': [
# '<@(table_files)',
# ],
# },
# ],
},
{
'target_name': 'liblouis_test_data',
'type': 'none',
'variables': {
'test_extension_dir': '<(DEPTH)/chrome/test/data/chromeos/liblouis_nacl',
},
'dependencies': [
'liblouis_nacl_wrapper_untrusted',
],
'copies': [
{
'destination': '<(braille_test_data_dir)',
'files': [
'tables.json',
'<(test_extension_dir)/manifest.json',
'<(test_extension_dir)/test.js',
],
},
{
'destination': '<(braille_test_data_dir)/tables',
'files': [
'<@(table_files)',
],
},
],
},
],
}],
],
}
// Copyright 2013 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#include "liblouis_instance.h"
#include <cstdio>
#include <cstring>
#include <sys/mount.h>
#include <vector>
#include "nacl_io/nacl_io.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/cpp/module.h"
#include "translation_result.h"
namespace {
static const char kHexadecimalChars[] = "0123456789abcdef";
// Converts a vector of bytes into a (lowercase) hexadecimal string.
static void BytesToHexString(const std::vector<unsigned char>& bytes,
std::string* out) {
std::string hex;
hex.reserve(bytes.size() * 2);
for (size_t i = 0; i < bytes.size(); ++i) {
unsigned char byte = bytes[i];
hex.push_back(kHexadecimalChars[byte >> 4]);
hex.push_back(kHexadecimalChars[byte & 0x0f]);
}
out->swap(hex);
}
// Converts a hexadecimal string to a vector of bytes.
// Returns false on failure.
static bool HexStringToBytes(const std::string& hex,
std::vector<unsigned char>* out) {
if (hex.size() % 2 != 0) {
return false;
}
std::vector<unsigned char> bytes;
bytes.reserve(hex.size() / 2);
for (size_t i = 0; i < hex.size(); i += 2) {
unsigned char byte;
char ch = hex[i];
if ('0' <= ch && ch <= '9') {
byte = (ch - '0') << 4;
} else if ('a' <= ch && ch <= 'f') {
byte = (ch - 'a' + 10) << 4;
} else if ('A' <= ch && ch <= 'F') {
byte = (ch - 'A' + 10) << 4;
} else {
return false;
}
ch = hex[i+1];
if ('0' <= ch && ch <= '9') {
byte |= ch - '0';
} else if ('a' <= ch && ch <= 'f') {
byte |= ch - 'a' + 10;
} else if ('A' <= ch && ch <= 'F') {
byte |= ch - 'A' + 10;
} else {
return false;
}
bytes.push_back(byte);
}
out->swap(bytes);
return true;
}
template <typename T>
static void CopyVectorToJson(const std::vector<T>& vec, Json::Value* out) {
Json::Value result(Json::arrayValue);
result.resize(vec.size());
for (size_t i = 0; i < vec.size(); ++i) {
result[i] = vec[i];
}
out->swap(result);
}
} // namespace
namespace liblouis_nacl {
// Well-known strings used for configuration.
static const char kTablesDirKey[] = "tablesdir";
static const char kTablesDirDefault[] = "tables";
// Well-known strings used in JSON messages.
static const char kCommandKey[] = "command";
static const char kMessageIdKey[] = "message_id";
static const char kInReplyToKey[] = "in_reply_to";
static const char kErrorKey[] = "error";
static const char kTableNameKey[] = "table_name";
static const char kSuccessKey[] = "success";
static const char kTextKey[] = "text";
static const char kCellsKey[] = "cells";
static const char kCursorPositionKey[] = "cursor_position";
static const char kTextToBrailleKey[] = "text_to_braille";
static const char kBrailleToTextKey[] = "braille_to_text";
static const char kCheckTableCommand[] = "CheckTable";
static const char kTranslateCommand[] = "Translate";
static const char kBackTranslateCommand[] = "BackTranslate";
LibLouisInstance::LibLouisInstance(PP_Instance instance)
: pp::Instance(instance), liblouis_thread_(this), cc_factory_(this) {}
LibLouisInstance::~LibLouisInstance() {}
bool LibLouisInstance::Init(uint32_t argc, const char* argn[],
const char* argv[]) {
const char* tables_dir = kTablesDirDefault;
for (size_t i = 0; i < argc; ++i) {
if (strcmp(argn[i], kTablesDirKey) == 0) {
tables_dir = argv[i];
}
}
nacl_io_init_ppapi(pp_instance(),
pp::Module::Get()->get_browser_interface());
if (mount(tables_dir, liblouis_.tables_dir(), "httpfs", 0, "") != 0) {
// TODO(jbroman): report this error.
return false;
}
return liblouis_thread_.Start();
}
void LibLouisInstance::HandleMessage(const pp::Var& var_message) {
if (!var_message.is_string()) {
PostError("expected message to be a JSON string");
return;
}
Json::Value message;
Json::Reader reader;
bool parsed = reader.parse(var_message.AsString(),
message, false /* collectComments */);
if (!parsed) {
PostError("expected message to be a JSON string");
return;
}
Json::Value message_id = message[kMessageIdKey];
if (!message_id.isString()) {
PostError("expected message_id string");
return;
}
std::string message_id_str = message_id.asString();
Json::Value command = message[kCommandKey];
if (!command.isString()) {
PostError("expected command string", message_id_str);
return;
}
std::string command_str = command.asString();
if (command_str == kCheckTableCommand) {
HandleCheckTable(message, message_id_str);
} else if (command_str == kTranslateCommand) {
HandleTranslate(message, message_id_str);
} else if (command_str == kBackTranslateCommand) {
HandleBackTranslate(message, message_id_str);
} else {
PostError("unknown command", message_id_str);
}
}
void LibLouisInstance::PostReply(Json::Value reply,
const std::string& in_reply_to) {
Json::FastWriter writer;
reply[kInReplyToKey] = in_reply_to;
pp::Var var_reply(writer.write(reply));
PostMessage(var_reply);
}
void LibLouisInstance::PostError(const std::string& error_message) {
Json::FastWriter writer;
Json::Value reply(Json::objectValue);
reply[kErrorKey] = error_message;
pp::Var var_reply(writer.write(reply));
PostMessage(var_reply);
}
void LibLouisInstance::PostError(const std::string& error_message,
const std::string& in_reply_to) {
Json::FastWriter writer;
Json::Value reply(Json::objectValue);
reply[kErrorKey] = error_message;
reply[kInReplyToKey] = in_reply_to;
reply[kSuccessKey] = false;
pp::Var var_reply(writer.write(reply));
PostMessage(var_reply);
}
void LibLouisInstance::HandleCheckTable(const Json::Value& message,
const std::string& message_id) {
Json::Value table_name = message[kTableNameKey];
if (!table_name.isString()) {
PostError("expected table_name to be a string", message_id);
return;
}
PostWorkToBackground(cc_factory_.NewCallback(
&LibLouisInstance::CheckTableInBackground,
table_name.asString(), message_id));
}
void LibLouisInstance::CheckTableInBackground(int32_t result,
const std::string& table_name, const std::string& message_id) {
if (result != PP_OK) {
PostError("failed to transfer call to background thread", message_id);
return;
}
bool success = liblouis_.CheckTable(table_name);
Json::Value reply(Json::objectValue);
reply[kSuccessKey] = success;
PostReply(reply, message_id);
}
void LibLouisInstance::HandleTranslate(const Json::Value& message,
const std::string& message_id) {
Json::Value table_name = message[kTableNameKey];
Json::Value text = message[kTextKey];
Json::Value cursor_position = message[kCursorPositionKey];
if (!table_name.isString()) {
PostError("expected table_name to be a string", message_id);
return;
} else if (!text.isString()) {
PostError("expected text to be a string", message_id);
return;
} else if (!cursor_position.isNull() && !cursor_position.isIntegral()) {
PostError("expected cursor_position to be null or integral", message_id);
return;
}
TranslationParams params;
params.table_name = table_name.asString();
params.text = text.asString();
params.cursor_position = cursor_position.isIntegral() ?
cursor_position.asInt() : -1;
PostWorkToBackground(cc_factory_.NewCallback(
&LibLouisInstance::TranslateInBackground,
params, message_id));
}
void LibLouisInstance::TranslateInBackground(int32_t result,
const TranslationParams& params, const std::string& message_id) {
if (result != PP_OK) {
PostError("failed to transfer call to background thread", message_id);
return;
}
TranslationResult translation_result;
bool success = liblouis_.Translate(params, &translation_result);
Json::Value reply(Json::objectValue);
reply[kSuccessKey] = success;
if (success) {
std::string hex_cells;
Json::Value text_to_braille;
Json::Value braille_to_text;
BytesToHexString(translation_result.cells, &hex_cells);
CopyVectorToJson(translation_result.text_to_braille, &text_to_braille);
CopyVectorToJson(translation_result.braille_to_text, &braille_to_text);
reply[kCellsKey] = hex_cells;
reply[kTextToBrailleKey] = text_to_braille;
reply[kBrailleToTextKey] = braille_to_text;
if (translation_result.cursor_position >= 0) {
reply[kCursorPositionKey] = translation_result.cursor_position;
}
}
PostReply(reply, message_id);
}
void LibLouisInstance::HandleBackTranslate(const Json::Value& message,
const std::string& message_id) {
Json::Value table_name = message[kTableNameKey];
Json::Value cells = message[kCellsKey];
if (!table_name.isString()) {
PostError("expected table_name to be a string", message_id);
return;
} else if (!cells.isString()) {
PostError("expected cells to be a string", message_id);
return;
}
std::vector<unsigned char> cells_vector;
if (!HexStringToBytes(cells.asString(), &cells_vector)) {
PostError("expected cells to be a valid hexadecimal string", message_id);
return;
}
PostWorkToBackground(cc_factory_.NewCallback(
&LibLouisInstance::BackTranslateInBackground,
table_name.asString(), cells_vector, message_id));
}
void LibLouisInstance::BackTranslateInBackground(int32_t result,
const std::string& table_name, const std::vector<unsigned char>& cells,
const std::string& message_id) {
if (result != PP_OK) {
PostError("failed to transfer call to background thread", message_id);
return;
}
std::string text;
bool success = liblouis_.BackTranslate(table_name, cells, &text);
Json::Value reply(Json::objectValue);
reply[kSuccessKey] = success;
if (success) {
reply[kTextKey] = text;
}
PostReply(reply, message_id);
}
} // namespace liblouis_nacl
// Copyright 2013 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#ifndef LIBLOUIS_NACL_LIBLOUIS_INSTANCE_H_
#define LIBLOUIS_NACL_LIBLOUIS_INSTANCE_H_
#include <string>
#include "base/basictypes.h"
#include "json/json.h"
#include "liblouis_wrapper.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/cpp/completion_callback.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/message_loop.h"
#include "ppapi/cpp/var.h"
#include "ppapi/utility/completion_callback_factory.h"
#include "ppapi/utility/threading/simple_thread.h"
#include "translation_params.h"
namespace liblouis_nacl {
class LibLouisInstance : public pp::Instance {
public:
explicit LibLouisInstance(PP_Instance instance);
virtual ~LibLouisInstance();
virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]);
virtual void HandleMessage(const pp::Var& var_message);
private:
// Post work to the background (liblouis) thread.
int32_t PostWorkToBackground(const pp::CompletionCallback& callback) {
return liblouis_thread_.message_loop().PostWork(callback);
}
// Encodes a message as JSON and sends it over to JavaScript.
void PostReply(Json::Value reply, const std::string& in_reply_to);
// Posts an error response to JavaScript.
void PostError(const std::string& error);
// Posts an error response to JavaScript, with the message ID of the call
// which caused it.
void PostError(const std::string& error, const std::string& in_reply_to);
// Parses and executes a table check command.
void HandleCheckTable(const Json::Value& message,
const std::string& message_id);
// Called to check a table on a background thread.
void CheckTableInBackground(int32_t result, const std::string& table_name,
const std::string& message_id);
// Parses and executes a translation command.
void HandleTranslate(const Json::Value& message,
const std::string& message_id);
// Called to translate text on a background thread.
void TranslateInBackground(int32_t result, const TranslationParams& params,
const std::string& message_id);
// Parses and executes a back translation command.
void HandleBackTranslate(const Json::Value& message,
const std::string& message_id);
// Called to back-translate text on a background thread.
void BackTranslateInBackground(int32_t result,
const std::string& table_name, const std::vector<unsigned char>& cells,
const std::string& message_id);
LibLouisWrapper liblouis_;
pp::SimpleThread liblouis_thread_;
pp::CompletionCallbackFactory<LibLouisInstance> cc_factory_;
DISALLOW_COPY_AND_ASSIGN(LibLouisInstance);
};
} // namespace liblouis_nacl
#endif // LIBLOUIS_NACL_LIBLOUIS_INSTANCE_H_
// Copyright 2013 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#include "liblouis_module.h"
#include <cstddef>
#include "liblouis_instance.h"
namespace liblouis_nacl {
LibLouisModule::LibLouisModule() : pp::Module() {}
LibLouisModule::~LibLouisModule() {}
pp::Instance* LibLouisModule::CreateInstance(PP_Instance instance) {
static bool created = false;
if (!created) {
created = true;
return new LibLouisInstance(instance);
}
return NULL;
}
} // namespace liblouis_nacl
namespace pp {
Module* CreateModule() {
static bool created = false;
if (!created) {
created = true;
return new liblouis_nacl::LibLouisModule();
}
return NULL;
}
} // namespace pp
// Copyright 2013 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#ifndef LIBLOUIS_NACL_LIBLOUIS_MODULE_H_
#define LIBLOUIS_NACL_LIBLOUIS_MODULE_H_
#include "base/basictypes.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/module.h"
namespace liblouis_nacl {
// Native Client module which contains liblouis.
class LibLouisModule : public pp::Module {
public:
LibLouisModule();
virtual ~LibLouisModule();
virtual pp::Instance* CreateInstance(PP_Instance instance);
private:
DISALLOW_COPY_AND_ASSIGN(LibLouisModule);
};
} // namespace liblouis_nacl
#endif // LIBLOUIS_NACL_LIBLOUIS_MODULE_H_
// Copyright 2013 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#include "liblouis_wrapper.h"
#include <cstddef>
#include "liblouis/liblouis.h"
namespace {
// Decodes UTF-8 into 16-bit wide characters.
// This implementation is very permissive and may miss encoding errors.
// It ignores charaters which are not in the Unicode Basic Multilingual Plane.
// TODO(jbroman): Handle more than BMP if liblouis changes to accept UTF-16.
static bool DecodeUtf8(const std::string& in, std::vector<widechar>* out) {
int len = in.length();
std::vector<widechar> result;
result.reserve(len);
int i = 0;
while (i < len) {
int ch = static_cast<unsigned char>(in[i++]);
widechar cp;
if ((ch & 0x80) == 0x00) { // U+0000 - U+007F
cp = ch;
} else if ((ch & 0xe0) == 0xc0 && i < len) { // U+0080 - U+07FF
cp = (ch & 0x1f) << 6;
ch = static_cast<unsigned char>(in[i++]);
cp |= (ch & 0x3f);
} else if ((ch & 0xf0) == 0xe0 && i+1 < len) { // U+0800 - U+FFFF
cp = (ch & 0x0f) << 12;
ch = static_cast<unsigned char>(in[i++]);
cp |= (ch & 0x3f) << 6;
ch = static_cast<unsigned char>(in[i++]);
cp |= (ch & 0x3f);
} else if ((ch & 0xf8) == 0xf0 && i+2 < len) { // U+10000 - U+1FFFFF
i += 3;
continue;
} else if ((ch & 0xfc) == 0xf8 && i+3 < len) { // U+200000 - U+3FFFFFF
i += 4;
continue;
} else if ((ch & 0xfe) == 0xfc && i+4 < len) { // U+4000000 - U+7FFFFFFF
i += 5;
continue;
} else {
// Invalid first code point.
return false;
}
result.push_back(cp);
}
out->swap(result);
return true;
}
// Encodes 16-bit wide characters into UTF-8.
// This implementation is very permissive and may miss invalid code points in
// its input.
// TODO(jbroman): Handle more than BMP if widechar ever becomes larger.
static bool EncodeUtf8(const std::vector<widechar>& in, std::string* out) {
std::string result;
result.reserve(in.size() * 2);
for (std::vector<widechar>::const_iterator it = in.begin(); it != in.end();
++it) {
unsigned int cp = *it;
if (cp <= 0x007f) { // U+0000 - U+007F
result.push_back(static_cast<char>(cp));
} else if (cp <= 0x07ff) { // U+0080 - U+07FF
result.push_back(static_cast<char>(0xc0 | ((cp >> 6) & 0x1f)));
result.push_back(static_cast<char>(0x80 | (cp & 0x3f)));
} else if (cp <= 0xffff) { // U+0800 - U+FFFF
result.push_back(static_cast<char>(0xe0 | ((cp >> 12) & 0x0f)));
result.push_back(static_cast<char>(0x80 | ((cp >> 6) & 0x3f)));
result.push_back(static_cast<char>(0x80 | (cp & 0x3f)));
} else {
// This can't happen if widechar is 16 bits wide.
// TODO(jbroman): assert this
}
}
out->swap(result);
return true;
}
} // namespace
namespace liblouis_nacl {
LibLouisWrapper::LibLouisWrapper() {
char data_path[] = "/"; // Needed because lou_setDataPath takes a char*.
lou_setDataPath(data_path);
}
LibLouisWrapper::~LibLouisWrapper() {
lou_free();
}
const char* LibLouisWrapper::tables_dir() const {
return "/liblouis/tables";
}
bool LibLouisWrapper::CheckTable(const std::string& table_name) {
return lou_getTable(table_name.c_str()) != NULL;
}
bool LibLouisWrapper::Translate(const TranslationParams& params,
TranslationResult* out) {
// Convert the character set of the input text.
std::vector<widechar> inbuf;
if (!DecodeUtf8(params.text, &inbuf)) {
// TODO(jbroman): log this
return false;
}
int inlen = inbuf.size();
int outlen = inlen * 2; // TODO(jbroman): choose this size more accurately.
std::vector<widechar> outbuf(outlen);
std::vector<int> text_to_braille(inlen);
std::vector<int> braille_to_text(outlen);
// Compute the cursor position pointer to pass to liblouis.
int out_cursor_position;
int* out_cursor_position_ptr;
if (params.cursor_position < 0) {
out_cursor_position = -1;
out_cursor_position_ptr = NULL;
} else {
out_cursor_position = params.cursor_position;
out_cursor_position_ptr = &out_cursor_position;
}
// Invoke liblouis.
int result = lou_translate(params.table_name.c_str(),
&inbuf[0], &inlen, &outbuf[0], &outlen,
NULL /* typeform */, NULL /* spacing */,
&text_to_braille[0], &braille_to_text[0],
out_cursor_position_ptr, dotsIO /* mode */);
if (result == 0) {
// TODO(jbroman): log this
return false;
}
// Massage the result.
std::vector<unsigned char> cells;
cells.reserve(outlen);
for (int i = 0; i < outlen; i++) {
cells.push_back(outbuf[i]);
}
braille_to_text.resize(outlen);
// Return the translation result.
out->cells.swap(cells);
out->text_to_braille.swap(text_to_braille);
out->braille_to_text.swap(braille_to_text);
out->cursor_position = out_cursor_position;
return true;
}
bool LibLouisWrapper::BackTranslate(const std::string& table_name,
const std::vector<unsigned char>& cells, std::string* out) {
std::vector<widechar> inbuf;
inbuf.reserve(cells.size());
for (std::vector<unsigned char>::const_iterator it = cells.begin();
it != cells.end(); ++it) {
// Set the high-order bit to prevent liblouis from dropping empty cells.
inbuf.push_back(*it | 0x8000);
}
int inlen = inbuf.size();
int outlen = inlen * 2; // TODO(jbroman): choose this size more accurately.
std::vector<widechar> outbuf(outlen);
// Invoke liblouis.
int result = lou_backTranslateString(table_name.c_str(),
&inbuf[0], &inlen, &outbuf[0], &outlen,
NULL /* typeform */, NULL /* spacing */, dotsIO /* mode */);
if (result == 0) {
// TODO(njbroman): log this
return false;
}
// Massage the result.
outbuf.resize(outlen);
std::string text;
if (!EncodeUtf8(outbuf, &text)) {
// TODO(jbroman): log this
return false;
}
// Return the back translation result.
out->swap(text);
return true;
}
} // namespace liblouis_nacl
// Copyright 2013 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#ifndef LIBLOUIS_NACL_LIBLOUIS_WRAPPER_H_
#define LIBLOUIS_NACL_LIBLOUIS_WRAPPER_H_
#include <string>
#include "base/basictypes.h"
#include "translation_params.h"
#include "translation_result.h"
namespace liblouis_nacl {
// Encapsulates logic for interacting (synchronously) with liblouis.
//
// This class is *not* thread-safe; it should be used only from one thread.
// Since the underlying library is not reentrant, only one instance should be
// in use at a time.
//
// All input strings should be represented in UTF-8.
class LibLouisWrapper {
public:
LibLouisWrapper();
~LibLouisWrapper();
// Returns one of the paths where tables may be searched for.
const char* tables_dir() const;
// Loads, checks, and compiles the requested table.
// Returns true on success.
bool CheckTable(const std::string& table_name);
// Translates the given text and cursor position into braille.
bool Translate(const TranslationParams& params, TranslationResult* out);
// Translates the given braille cells into text.
bool BackTranslate(const std::string& table_name,
const std::vector<unsigned char>& cells, std::string* out);
private:
DISALLOW_COPY_AND_ASSIGN(LibLouisWrapper);
};
} // namespace liblouis_nacl
#endif // LIBLOUIS_NACL_LIBLOUIS_WRAPPER_H_
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/base_paths.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "chrome/browser/extensions/extension_apitest.h"
class LibLouisWrapperTest : public ExtensionApiTest {
};
IN_PROC_BROWSER_TEST_F(LibLouisWrapperTest, LibLouisLoad) {
ASSERT_TRUE(PathService::Get(base::DIR_EXE, &test_data_dir_));
test_data_dir_ = test_data_dir_.AppendASCII("chromevox_test_data");
LOG(ERROR) << "Test data dir: " << test_data_dir_.MaybeAsASCII();
ASSERT_TRUE(RunExtensionTest("braille")) << message_;
}
// Copyright 2013 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#ifndef LIBLOUIS_NACL_TRANSLATION_PARAMS_H_
#define LIBLOUIS_NACL_TRANSLATION_PARAMS_H_
#include <string>
namespace liblouis_nacl {
// Struct containing the parameters of translation.
struct TranslationParams {
public:
std::string table_name;
std::string text;
int cursor_position;
};
}
#endif // LIBLOUIS_NACL_TRANSLATION_PARAMS_H_
// Copyright 2013 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#ifndef LIBLOUIS_NACL_TRANSLATION_RESULT_H_
#define LIBLOUIS_NACL_TRANSLATION_RESULT_H_
#include <vector>
namespace liblouis_nacl {
// Struct containing the result of translation.
struct TranslationResult {
public:
std::vector<unsigned char> cells;
std::vector<int> text_to_braille;
std::vector<int> braille_to_text;
int cursor_position;
};
}
#endif // LIBLOUIS_NACL_TRANSLATION_RESULT_H_
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* Copyright 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
#define TABLESDIR ""
#define PACKAGE_VERSION "2.5.1-google"
/* liblouis Braille Translation and Back-Translation Library
Based on the Linux screenreader BRLTTY, copyright (C) 1999-2006 by
The BRLTTY Team
Copyright (C) 2004, 2005, 2006, 2009 ViewPlus Technologies, Inc.
www.viewplus.com and JJB Software, Inc. www.jjb-software.com
liblouis is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
liblouis is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this program. If not, see
<http://www.gnu.org/licenses/>.
Maintained by John J. Boyer john.boyer@abilitiessoft.com
*/
#ifndef __LIBLOUIS_H_
#define __LIBLOUIS_H_
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
#define widechar unsigned short int
#ifdef _WIN32
#define EXPORT_CALL __stdcall
char * EXPORT_CALL lou_getProgramPath ();
#else
#define EXPORT_CALL
#endif
typedef enum
{
plain_text = 0,
italic = 1,
underline = 2,
bold = 4,
computer_braille = 8
} typeforms;
#define comp_emph_1 italic
#define comp_emph_2 underline
#define comp_emph_3 bold
typedef enum
{
noContractions = 1,
compbrlAtCursor = 2,
dotsIO = 4,
comp8Dots = 8,
pass1Only = 16,
compbrlLeftCursor = 32,
otherTrans = 64,
ucBrl = 128
} translationModes;
char * EXPORT_CALL lou_version ();
int EXPORT_CALL lou_charSize ();
/* Return the size of widechar */
int EXPORT_CALL lou_translateString
(const char *tableList,
const widechar *inbuf,
int *inlen,
widechar * outbuf,
int *outlen, char *typeform, char *spacing, int mode);
int EXPORT_CALL lou_translate (const char *tableList, const widechar
*inbuf,
int *inlen, widechar * outbuf, int *outlen,
char *typeform, char *spacing, int *outputPos, int
*inputPos, int *cursorPos, int mode);
int EXPORT_CALL lou_hyphenate (const char *tableList, const widechar
*inbuf,
int inlen, char *hyphens, int mode);
int EXPORT_CALL lou_dotsToChar (const char *tableList, widechar *inbuf,
widechar *outbuf, int length, int mode);
int EXPORT_CALL lou_charToDots (const char *tableList, const widechar
*inbuf,
widechar *outbuf, int length, int mode);
int EXPORT_CALL lou_backTranslateString (const char *tableList,
const widechar *inbuf,
int *inlen,
widechar * outbuf,
int *outlen, char *typeform, char
*spacing, int mode);
int EXPORT_CALL lou_backTranslate (const char *tableList, const widechar
*inbuf,
int *inlen, widechar * outbuf, int *outlen,
char *typeform, char *spacing, int
*outputPos, int *inputPos, int *cursorPos, int
mode);
void EXPORT_CALL lou_logPrint (char *format, ...);
/* prints error messages to a file */
void EXPORT_CALL lou_logFile (const char *filename);
/* Specifies the name of the file to be used by lou_logPrint. If it is
* not used, this file is stderr*/
int EXPORT_CALL lou_readCharFromFile (const char *fileName, int *mode);
/*Read a character from a file, whether big-encian, little-endian or
* ASCII8, and return it as an integer. EOF at end of file. Mode = 1 on
* first call, any other value thereafter*/
void EXPORT_CALL lou_logEnd ();
/* Closes the log file so it can be read by other functions. */
void * EXPORT_CALL lou_getTable (const char *tableList);
/* This function checks a table for errors. If none are found it loads
* the table into memory and returns a pointer to it. if errors are found
* it returns a null pointer. It is called by lou_translateString and
* lou_backTranslateString and also by functions in liblouisxml
*/
int EXPORT_CALL lou_compileString (const char *tableList, const char
*inString);
char * EXPORT_CALL lou_setDataPath (char *path);
/* Set the path used for searching for tables and liblouisutdml files.
* Overrides the installation path. */
char * EXPORT_CALL lou_getDataPath ();
/* Get the path set in the previous function. */
// char EXPORT_CALL * lou_getTablePaths ();
/* Get a list of paths actually used in seraching for tables*/
void EXPORT_CALL lou_free ();
/* This function should be called at the end of
* the application to free all memory allocated by liblouis. */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /*LibLOUIS_H_ */
#
# Copyright (C) 2010, 2011 DocArch <http://www.docarch.be>.
#
# This file is part of liblouis.
#
# liblouis is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# liblouis is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with liblouis. If not, see
# <http://www.gnu.org/licenses/>.
#
# ----------------------------------------------------------------------------------------------
# odt2braille - Braille authoring in OpenOffice.org.
# ----------------------------------------------------------------------------------------------
# ----------------------------------------------------------------------------------------------
# Unicode 2800..28FF Braille Patterns
# ----------------------------------------------------------------------------------------------
noback sign \x2800 0 # ⠀ BRAILLE PATTERN DOTS-0
noback sign \x2801 1 # ⠁ BRAILLE PATTERN DOTS-1
noback sign \x2802 2 # ⠂ BRAILLE PATTERN DOTS-2
noback sign \x2803 12 # ⠃ BRAILLE PATTERN DOTS-12
noback sign \x2804 3 # ⠄ BRAILLE PATTERN DOTS-3
noback sign \x2805 13 # ⠅ BRAILLE PATTERN DOTS-13
noback sign \x2806 23 # ⠆ BRAILLE PATTERN DOTS-23
noback sign \x2807 123 # ⠇ BRAILLE PATTERN DOTS-123
noback sign \x2808 4 # ⠈ BRAILLE PATTERN DOTS-4
noback sign \x2809 14 # ⠉ BRAILLE PATTERN DOTS-14
noback sign \x280A 24 # ⠊ BRAILLE PATTERN DOTS-24
noback sign \x280B 124 # ⠋ BRAILLE PATTERN DOTS-124
noback sign \x280C 34 # ⠌ BRAILLE PATTERN DOTS-34
noback sign \x280D 134 # ⠍ BRAILLE PATTERN DOTS-134
noback sign \x280E 234 # ⠎ BRAILLE PATTERN DOTS-234
noback sign \x280F 1234 # ⠏ BRAILLE PATTERN DOTS-1234
noback sign \x2810 5 # ⠐ BRAILLE PATTERN DOTS-5
noback sign \x2811 15 # ⠑ BRAILLE PATTERN DOTS-15
noback sign \x2812 25 # ⠒ BRAILLE PATTERN DOTS-25
noback sign \x2813 125 # ⠓ BRAILLE PATTERN DOTS-125
noback sign \x2814 35 # ⠔ BRAILLE PATTERN DOTS-35
noback sign \x2815 135 # ⠕ BRAILLE PATTERN DOTS-135
noback sign \x2816 235 # ⠖ BRAILLE PATTERN DOTS-235
noback sign \x2817 1235 # ⠗ BRAILLE PATTERN DOTS-1235
noback sign \x2818 45 # ⠘ BRAILLE PATTERN DOTS-45
noback sign \x2819 145 # ⠙ BRAILLE PATTERN DOTS-145
noback sign \x281A 245 # ⠚ BRAILLE PATTERN DOTS-245
noback sign \x281B 1245 # ⠛ BRAILLE PATTERN DOTS-1245
noback sign \x281C 345 # ⠜ BRAILLE PATTERN DOTS-345
noback sign \x281D 1345 # ⠝ BRAILLE PATTERN DOTS-1345
noback sign \x281E 2345 # ⠞ BRAILLE PATTERN DOTS-2345
noback sign \x281F 12345 # ⠟ BRAILLE PATTERN DOTS-12345
noback sign \x2820 6 # ⠠ BRAILLE PATTERN DOTS-6
noback sign \x2821 16 # ⠡ BRAILLE PATTERN DOTS-16
noback sign \x2822 26 # ⠢ BRAILLE PATTERN DOTS-26
noback sign \x2823 126 # ⠣ BRAILLE PATTERN DOTS-126
noback sign \x2824 36 # ⠤ BRAILLE PATTERN DOTS-36
noback sign \x2825 136 # ⠥ BRAILLE PATTERN DOTS-136
noback sign \x2826 236 # ⠦ BRAILLE PATTERN DOTS-236
noback sign \x2827 1236 # ⠧ BRAILLE PATTERN DOTS-1236
noback sign \x2828 46 # ⠨ BRAILLE PATTERN DOTS-46
noback sign \x2829 146 # ⠩ BRAILLE PATTERN DOTS-146
noback sign \x282A 246 # ⠪ BRAILLE PATTERN DOTS-246
noback sign \x282B 1246 # ⠫ BRAILLE PATTERN DOTS-1246
noback sign \x282C 346 # ⠬ BRAILLE PATTERN DOTS-346
noback sign \x282D 1346 # ⠭ BRAILLE PATTERN DOTS-1346
noback sign \x282E 2346 # ⠮ BRAILLE PATTERN DOTS-2346
noback sign \x282F 12346 # ⠯ BRAILLE PATTERN DOTS-12346
noback sign \x2830 56 # ⠰ BRAILLE PATTERN DOTS-56
noback sign \x2831 156 # ⠱ BRAILLE PATTERN DOTS-156
noback sign \x2832 256 # ⠲ BRAILLE PATTERN DOTS-256
noback sign \x2833 1256 # ⠳ BRAILLE PATTERN DOTS-1256
noback sign \x2834 356 # ⠴ BRAILLE PATTERN DOTS-356
noback sign \x2835 1356 # ⠵ BRAILLE PATTERN DOTS-1356
noback sign \x2836 2356 # ⠶ BRAILLE PATTERN DOTS-2356
noback sign \x2837 12356 # ⠷ BRAILLE PATTERN DOTS-12356
noback sign \x2838 456 # ⠸ BRAILLE PATTERN DOTS-456
noback sign \x2839 1456 # ⠹ BRAILLE PATTERN DOTS-1456
noback sign \x283A 2456 # ⠺ BRAILLE PATTERN DOTS-2456
noback sign \x283B 12456 # ⠻ BRAILLE PATTERN DOTS-12456
noback sign \x283C 3456 # ⠼ BRAILLE PATTERN DOTS-3456
noback sign \x283D 13456 # ⠽ BRAILLE PATTERN DOTS-13456
noback sign \x283E 23456 # ⠾ BRAILLE PATTERN DOTS-23456
noback sign \x283F 123456 # ⠿ BRAILLE PATTERN DOTS-123456
noback sign \x2840 7 # ⡀ BRAILLE PATTERN DOTS-7
noback sign \x2841 17 # ⡁ BRAILLE PATTERN DOTS-17
noback sign \x2842 27 # ⡂ BRAILLE PATTERN DOTS-27
noback sign \x2843 127 # ⡃ BRAILLE PATTERN DOTS-127
noback sign \x2844 37 # ⡄ BRAILLE PATTERN DOTS-37
noback sign \x2845 137 # ⡅ BRAILLE PATTERN DOTS-137
noback sign \x2846 237 # ⡆ BRAILLE PATTERN DOTS-237
noback sign \x2847 1237 # ⡇ BRAILLE PATTERN DOTS-1237
noback sign \x2848 47 # ⡈ BRAILLE PATTERN DOTS-47
noback sign \x2849 147 # ⡉ BRAILLE PATTERN DOTS-147
noback sign \x284A 247 # ⡊ BRAILLE PATTERN DOTS-247
noback sign \x284B 1247 # ⡋ BRAILLE PATTERN DOTS-1247
noback sign \x284C 347 # ⡌ BRAILLE PATTERN DOTS-347
noback sign \x284D 1347 # ⡍ BRAILLE PATTERN DOTS-1347
noback sign \x284E 2347 # ⡎ BRAILLE PATTERN DOTS-2347
noback sign \x284F 12347 # ⡏ BRAILLE PATTERN DOTS-12347
noback sign \x2850 57 # ⡐ BRAILLE PATTERN DOTS-57
noback sign \x2851 157 # ⡑ BRAILLE PATTERN DOTS-157
noback sign \x2852 257 # ⡒ BRAILLE PATTERN DOTS-257
noback sign \x2853 1257 # ⡓ BRAILLE PATTERN DOTS-1257
noback sign \x2854 357 # ⡔ BRAILLE PATTERN DOTS-357
noback sign \x2855 1357 # ⡕ BRAILLE PATTERN DOTS-1357
noback sign \x2856 2357 # ⡖ BRAILLE PATTERN DOTS-2357
noback sign \x2857 12357 # ⡗ BRAILLE PATTERN DOTS-12357
noback sign \x2858 457 # ⡘ BRAILLE PATTERN DOTS-457
noback sign \x2859 1457 # ⡙ BRAILLE PATTERN DOTS-1457
noback sign \x285A 2457 # ⡚ BRAILLE PATTERN DOTS-2457
noback sign \x285B 12457 # ⡛ BRAILLE PATTERN DOTS-12457
noback sign \x285C 3457 # ⡜ BRAILLE PATTERN DOTS-3457
noback sign \x285D 13457 # ⡝ BRAILLE PATTERN DOTS-13457
noback sign \x285E 23457 # ⡞ BRAILLE PATTERN DOTS-23457
noback sign \x285F 123457 # ⡟ BRAILLE PATTERN DOTS-123457
noback sign \x2860 67 # ⡠ BRAILLE PATTERN DOTS-67
noback sign \x2861 167 # ⡡ BRAILLE PATTERN DOTS-167
noback sign \x2862 267 # ⡢ BRAILLE PATTERN DOTS-267
noback sign \x2863 1267 # ⡣ BRAILLE PATTERN DOTS-1267
noback sign \x2864 367 # ⡤ BRAILLE PATTERN DOTS-367
noback sign \x2865 1367 # ⡥ BRAILLE PATTERN DOTS-1367
noback sign \x2866 2367 # ⡦ BRAILLE PATTERN DOTS-2367
noback sign \x2867 12367 # ⡧ BRAILLE PATTERN DOTS-12367
noback sign \x2868 467 # ⡨ BRAILLE PATTERN DOTS-467
noback sign \x2869 1467 # ⡩ BRAILLE PATTERN DOTS-1467
noback sign \x286A 2467 # ⡪ BRAILLE PATTERN DOTS-2467
noback sign \x286B 12467 # ⡫ BRAILLE PATTERN DOTS-12467
noback sign \x286C 3467 # ⡬ BRAILLE PATTERN DOTS-3467
noback sign \x286D 13467 # ⡭ BRAILLE PATTERN DOTS-13467
noback sign \x286E 23467 # ⡮ BRAILLE PATTERN DOTS-23467
noback sign \x286F 123467 # ⡯ BRAILLE PATTERN DOTS-123467
noback sign \x2870 567 # ⡰ BRAILLE PATTERN DOTS-567
noback sign \x2871 1567 # ⡱ BRAILLE PATTERN DOTS-1567
noback sign \x2872 2567 # ⡲ BRAILLE PATTERN DOTS-2567
noback sign \x2873 12567 # ⡳ BRAILLE PATTERN DOTS-12567
noback sign \x2874 3567 # ⡴ BRAILLE PATTERN DOTS-3567
noback sign \x2875 13567 # ⡵ BRAILLE PATTERN DOTS-13567
noback sign \x2876 23567 # ⡶ BRAILLE PATTERN DOTS-23567
noback sign \x2877 123567 # ⡷ BRAILLE PATTERN DOTS-123567
noback sign \x2878 4567 # ⡸ BRAILLE PATTERN DOTS-4567
noback sign \x2879 14567 # ⡹ BRAILLE PATTERN DOTS-14567
noback sign \x287A 24567 # ⡺ BRAILLE PATTERN DOTS-24567
noback sign \x287B 124567 # ⡻ BRAILLE PATTERN DOTS-124567
noback sign \x287C 34567 # ⡼ BRAILLE PATTERN DOTS-34567
noback sign \x287D 134567 # ⡽ BRAILLE PATTERN DOTS-134567
noback sign \x287E 234567 # ⡾ BRAILLE PATTERN DOTS-234567
noback sign \x287F 1234567 # ⡿ BRAILLE PATTERN DOTS-1234567
noback sign \x2880 8 # ⢀ BRAILLE PATTERN DOTS-8
noback sign \x2881 18 # ⢁ BRAILLE PATTERN DOTS-18
noback sign \x2882 28 # ⢂ BRAILLE PATTERN DOTS-28
noback sign \x2883 128 # ⢃ BRAILLE PATTERN DOTS-128
noback sign \x2884 38 # ⢄ BRAILLE PATTERN DOTS-38
noback sign \x2885 138 # ⢅ BRAILLE PATTERN DOTS-138
noback sign \x2886 238 # ⢆ BRAILLE PATTERN DOTS-238
noback sign \x2887 1238 # ⢇ BRAILLE PATTERN DOTS-1238
noback sign \x2888 48 # ⢈ BRAILLE PATTERN DOTS-48
noback sign \x2889 148 # ⢉ BRAILLE PATTERN DOTS-148
noback sign \x288A 248 # ⢊ BRAILLE PATTERN DOTS-248
noback sign \x288B 1248 # ⢋ BRAILLE PATTERN DOTS-1248
noback sign \x288C 348 # ⢌ BRAILLE PATTERN DOTS-348
noback sign \x288D 1348 # ⢍ BRAILLE PATTERN DOTS-1348
noback sign \x288E 2348 # ⢎ BRAILLE PATTERN DOTS-2348
noback sign \x288F 12348 # ⢏ BRAILLE PATTERN DOTS-12348
noback sign \x2890 58 # ⢐ BRAILLE PATTERN DOTS-58
noback sign \x2891 158 # ⢑ BRAILLE PATTERN DOTS-158
noback sign \x2892 258 # ⢒ BRAILLE PATTERN DOTS-258
noback sign \x2893 1258 # ⢓ BRAILLE PATTERN DOTS-1258
noback sign \x2894 358 # ⢔ BRAILLE PATTERN DOTS-358
noback sign \x2895 1358 # ⢕ BRAILLE PATTERN DOTS-1358
noback sign \x2896 2358 # ⢖ BRAILLE PATTERN DOTS-2358
noback sign \x2897 12358 # ⢗ BRAILLE PATTERN DOTS-12358
noback sign \x2898 458 # ⢘ BRAILLE PATTERN DOTS-458
noback sign \x2899 1458 # ⢙ BRAILLE PATTERN DOTS-1458
noback sign \x289A 2458 # ⢚ BRAILLE PATTERN DOTS-2458
noback sign \x289B 12458 # ⢛ BRAILLE PATTERN DOTS-12458
noback sign \x289C 3458 # ⢜ BRAILLE PATTERN DOTS-3458
noback sign \x289D 13458 # ⢝ BRAILLE PATTERN DOTS-13458
noback sign \x289E 23458 # ⢞ BRAILLE PATTERN DOTS-23458
noback sign \x289F 123458 # ⢟ BRAILLE PATTERN DOTS-123458
noback sign \x28A0 68 # ⢠ BRAILLE PATTERN DOTS-68
noback sign \x28A1 168 # ⢡ BRAILLE PATTERN DOTS-168
noback sign \x28A2 268 # ⢢ BRAILLE PATTERN DOTS-268
noback sign \x28A3 1268 # ⢣ BRAILLE PATTERN DOTS-1268
noback sign \x28A4 368 # ⢤ BRAILLE PATTERN DOTS-368
noback sign \x28A5 1368 # ⢥ BRAILLE PATTERN DOTS-1368
noback sign \x28A6 2368 # ⢦ BRAILLE PATTERN DOTS-2368
noback sign \x28A7 12368 # ⢧ BRAILLE PATTERN DOTS-12368
noback sign \x28A8 468 # ⢨ BRAILLE PATTERN DOTS-468
noback sign \x28A9 1468 # ⢩ BRAILLE PATTERN DOTS-1468
noback sign \x28AA 2468 # ⢪ BRAILLE PATTERN DOTS-2468
noback sign \x28AB 12468 # ⢫ BRAILLE PATTERN DOTS-12468
noback sign \x28AC 3468 # ⢬ BRAILLE PATTERN DOTS-3468
noback sign \x28AD 13468 # ⢭ BRAILLE PATTERN DOTS-13468
noback sign \x28AE 23468 # ⢮ BRAILLE PATTERN DOTS-23468
noback sign \x28AF 123468 # ⢯ BRAILLE PATTERN DOTS-123468
noback sign \x28B0 568 # ⢰ BRAILLE PATTERN DOTS-568
noback sign \x28B1 1568 # ⢱ BRAILLE PATTERN DOTS-1568
noback sign \x28B2 2568 # ⢲ BRAILLE PATTERN DOTS-2568
noback sign \x28B3 12568 # ⢳ BRAILLE PATTERN DOTS-12568
noback sign \x28B4 3568 # ⢴ BRAILLE PATTERN DOTS-3568
noback sign \x28B5 13568 # ⢵ BRAILLE PATTERN DOTS-13568
noback sign \x28B6 23568 # ⢶ BRAILLE PATTERN DOTS-23568
noback sign \x28B7 123568 # ⢷ BRAILLE PATTERN DOTS-123568
noback sign \x28B8 4568 # ⢸ BRAILLE PATTERN DOTS-4568
noback sign \x28B9 14568 # ⢹ BRAILLE PATTERN DOTS-14568
noback sign \x28BA 24568 # ⢺ BRAILLE PATTERN DOTS-24568
noback sign \x28BB 124568 # ⢻ BRAILLE PATTERN DOTS-124568
noback sign \x28BC 34568 # ⢼ BRAILLE PATTERN DOTS-34568
noback sign \x28BD 134568 # ⢽ BRAILLE PATTERN DOTS-134568
noback sign \x28BE 234568 # ⢾ BRAILLE PATTERN DOTS-234568
noback sign \x28BF 1234568 # ⢿ BRAILLE PATTERN DOTS-1234568
noback sign \x28C0 78 # ⣀ BRAILLE PATTERN DOTS-78
noback sign \x28C1 178 # ⣁ BRAILLE PATTERN DOTS-178
noback sign \x28C2 278 # ⣂ BRAILLE PATTERN DOTS-278
noback sign \x28C3 1278 # ⣃ BRAILLE PATTERN DOTS-1278
noback sign \x28C4 378 # ⣄ BRAILLE PATTERN DOTS-378
noback sign \x28C5 1378 # ⣅ BRAILLE PATTERN DOTS-1378
noback sign \x28C6 2378 # ⣆ BRAILLE PATTERN DOTS-2378
noback sign \x28C7 12378 # ⣇ BRAILLE PATTERN DOTS-12378
noback sign \x28C8 478 # ⣈ BRAILLE PATTERN DOTS-478
noback sign \x28C9 1478 # ⣉ BRAILLE PATTERN DOTS-1478
noback sign \x28CA 2478 # ⣊ BRAILLE PATTERN DOTS-2478
noback sign \x28CB 12478 # ⣋ BRAILLE PATTERN DOTS-12478
noback sign \x28CC 3478 # ⣌ BRAILLE PATTERN DOTS-3478
noback sign \x28CD 13478 # ⣍ BRAILLE PATTERN DOTS-13478
noback sign \x28CE 23478 # ⣎ BRAILLE PATTERN DOTS-23478
noback sign \x28CF 123478 # ⣏ BRAILLE PATTERN DOTS-123478
noback sign \x28D0 578 # ⣐ BRAILLE PATTERN DOTS-578
noback sign \x28D1 1578 # ⣑ BRAILLE PATTERN DOTS-1578
noback sign \x28D2 2578 # ⣒ BRAILLE PATTERN DOTS-2578
noback sign \x28D3 12578 # ⣓ BRAILLE PATTERN DOTS-12578
noback sign \x28D4 3578 # ⣔ BRAILLE PATTERN DOTS-3578
noback sign \x28D5 13578 # ⣕ BRAILLE PATTERN DOTS-13578
noback sign \x28D6 23578 # ⣖ BRAILLE PATTERN DOTS-23578
noback sign \x28D7 123578 # ⣗ BRAILLE PATTERN DOTS-123578
noback sign \x28D8 4578 # ⣘ BRAILLE PATTERN DOTS-4578
noback sign \x28D9 14578 # ⣙ BRAILLE PATTERN DOTS-14578
noback sign \x28DA 24578 # ⣚ BRAILLE PATTERN DOTS-24578
noback sign \x28DB 124578 # ⣛ BRAILLE PATTERN DOTS-124578
noback sign \x28DC 34578 # ⣜ BRAILLE PATTERN DOTS-34578
noback sign \x28DD 134578 # ⣝ BRAILLE PATTERN DOTS-134578
noback sign \x28DE 234578 # ⣞ BRAILLE PATTERN DOTS-234578
noback sign \x28DF 1234578 # ⣟ BRAILLE PATTERN DOTS-1234578
noback sign \x28E0 678 # ⣠ BRAILLE PATTERN DOTS-678
noback sign \x28E1 1678 # ⣡ BRAILLE PATTERN DOTS-1678
noback sign \x28E2 2678 # ⣢ BRAILLE PATTERN DOTS-2678
noback sign \x28E3 12678 # ⣣ BRAILLE PATTERN DOTS-12678
noback sign \x28E4 3678 # ⣤ BRAILLE PATTERN DOTS-3678
noback sign \x28E5 13678 # ⣥ BRAILLE PATTERN DOTS-13678
noback sign \x28E6 23678 # ⣦ BRAILLE PATTERN DOTS-23678
noback sign \x28E7 123678 # ⣧ BRAILLE PATTERN DOTS-123678
noback sign \x28E8 4678 # ⣨ BRAILLE PATTERN DOTS-4678
noback sign \x28E9 14678 # ⣩ BRAILLE PATTERN DOTS-14678
noback sign \x28EA 24678 # ⣪ BRAILLE PATTERN DOTS-24678
noback sign \x28EB 124678 # ⣫ BRAILLE PATTERN DOTS-124678
noback sign \x28EC 34678 # ⣬ BRAILLE PATTERN DOTS-34678
noback sign \x28ED 134678 # ⣭ BRAILLE PATTERN DOTS-134678
noback sign \x28EE 234678 # ⣮ BRAILLE PATTERN DOTS-234678
noback sign \x28EF 1234678 # ⣯ BRAILLE PATTERN DOTS-1234678
noback sign \x28F0 5678 # ⣰ BRAILLE PATTERN DOTS-5678
noback sign \x28F1 15678 # ⣱ BRAILLE PATTERN DOTS-15678
noback sign \x28F2 25678 # ⣲ BRAILLE PATTERN DOTS-25678
noback sign \x28F3 125678 # ⣳ BRAILLE PATTERN DOTS-125678
noback sign \x28F4 35678 # ⣴ BRAILLE PATTERN DOTS-35678
noback sign \x28F5 135678 # ⣵ BRAILLE PATTERN DOTS-135678
noback sign \x28F6 235678 # ⣶ BRAILLE PATTERN DOTS-235678
noback sign \x28F7 1235678 # ⣷ BRAILLE PATTERN DOTS-1235678
noback sign \x28F8 45678 # ⣸ BRAILLE PATTERN DOTS-45678
noback sign \x28F9 145678 # ⣹ BRAILLE PATTERN DOTS-145678
noback sign \x28FA 245678 # ⣺ BRAILLE PATTERN DOTS-245678
noback sign \x28FB 1245678 # ⣻ BRAILLE PATTERN DOTS-1245678
noback sign \x28FC 345678 # ⣼ BRAILLE PATTERN DOTS-345678
noback sign \x28FD 1345678 # ⣽ BRAILLE PATTERN DOTS-1345678
noback sign \x28FE 2345678 # ⣾ BRAILLE PATTERN DOTS-2345678
noback sign \x28FF 12345678 # ⣿ BRAILLE PATTERN DOTS-12345678
# ----------------------------------------------------------------------------------------------
###############################################################################
# BRLTTY - A background process providing access to the console screen (when in
# text mode) for a blind person using a refreshable braille display.
#
# Copyright (C) 1995-2008 by The BRLTTY Developers.
#
# BRLTTY comes with ABSOLUTELY NO WARRANTY.
#
# This is free software, placed under the terms of the
# GNU Lesser General Public License, as published by the Free Software
# Foundation; either version 2.1 of the License, or (at your option) any
# later version. Please see the file LICENSE-LGPL for details.
#
# Web Page: http://mielke.cc/brltty/
#
# This software is maintained by Dave Mielke <dave@mielke.cc>.
###############################################################################
# BRLTTY Text Table - Danish (iso-8859-1)
# This is the table which comes closest to the Danish standard 1252 table. All
# control characters are mapped as their corresponding capital letters with
# dot-8 added. Most Danish braille users should use this table.
# generated by ttbtest
letter \x0000 8 NULL
letter \x0001 178 START OF HEADING
letter \x0002 1278 START OF TEXT
letter \x0003 1478 END OF TEXT
letter \x0004 14578 END OF TRANSMISSION
letter \x0005 24568 ENQUIRY
letter \x0006 12478 ACKNOWLEDGE
letter \x0007 124578 BELL
letter \x0008 12578 BACKSPACE
space \t 2478 CHARACTER TABULATION
space \n 678 LINE FEED (LF)
space \v 1368 LINE TABULATION
space \f 12378 FORM FEED (FF)
space \r 257 CARRIAGE RETURN (CR)
letter \x000e 134578 SHIFT OUT
letter \x000f 12358 SHIFT IN
letter \x0010 123478 DATA LINK ESCAPE
letter \x0011 1234578 DEVICE CONTROL ONE
letter \x0012 13568 DEVICE CONTROL TWO
letter \x0013 4578 DEVICE CONTROL THREE
letter \x0014 268 DEVICE CONTROL FOUR
letter \x0015 13678 NEGATIVE ACKNOWLEDGE
letter \x0016 278 SYNCHRONOUS IDLE
letter \x0017 3578 END OF TRANSMISSION BLOCK
letter \x0018 78 CANCEL
letter \x0019 68 END OF MEDIUM
letter \x001a 135678 SUBSTITUTE
letter \x001b 2678 ESCAPE
letter \x001c 45678 INFORMATION SEPARATOR FOUR
letter \x001d 12368 INFORMATION SEPARATOR THREE
letter \x001e 1234678 INFORMATION SEPARATOR TWO
letter \x001f 235678 INFORMATION SEPARATOR ONE
space \s 0 SPACE
punctuation ! 235 EXCLAMATION MARK
punctuation " 2356 QUOTATION MARK
punctuation # 34568 NUMBER SIGN
punctuation $ 25678 DOLLAR SIGN
punctuation % 24578 PERCENT SIGN
punctuation & 123468 AMPERSAND
punctuation ' 4 APOSTROPHE
punctuation ( 2368 LEFT PARENTHESIS
punctuation ) 3568 RIGHT PARENTHESIS
punctuation * 35 ASTERISK
punctuation + 2358 PLUS SIGN
punctuation , 2 COMMA
punctuation - 368 HYPHEN-MINUS
punctuation . 3 FULL STOP
punctuation / 34 SOLIDUS
include digits8Dots.uti
punctuation : 25 COLON
punctuation ; 23 SEMICOLON
punctuation < 358 LESS-THAN SIGN
punctuation = 23568 EQUALS SIGN
punctuation > 267 GREATER-THAN SIGN
punctuation ? 26 QUESTION MARK
punctuation @ 478 COMMERCIAL AT
uppercase A 17 LATIN CAPITAL LETTER A
uppercase B 127 LATIN CAPITAL LETTER B
uppercase C 147 LATIN CAPITAL LETTER C
uppercase D 1457 LATIN CAPITAL LETTER D
uppercase E 157 LATIN CAPITAL LETTER E
uppercase F 1247 LATIN CAPITAL LETTER F
uppercase G 12457 LATIN CAPITAL LETTER G
uppercase H 1257 LATIN CAPITAL LETTER H
uppercase I 247 LATIN CAPITAL LETTER I
uppercase J 2457 LATIN CAPITAL LETTER J
uppercase K 137 LATIN CAPITAL LETTER K
uppercase L 1237 LATIN CAPITAL LETTER L
uppercase M 1347 LATIN CAPITAL LETTER M
uppercase N 13457 LATIN CAPITAL LETTER N
uppercase O 1357 LATIN CAPITAL LETTER O
uppercase P 12347 LATIN CAPITAL LETTER P
uppercase Q 123457 LATIN CAPITAL LETTER Q
uppercase R 12357 LATIN CAPITAL LETTER R
uppercase S 2347 LATIN CAPITAL LETTER S
uppercase T 23457 LATIN CAPITAL LETTER T
uppercase U 1367 LATIN CAPITAL LETTER U
uppercase V 12367 LATIN CAPITAL LETTER V
uppercase W 24567 LATIN CAPITAL LETTER W
uppercase X 13467 LATIN CAPITAL LETTER X
uppercase Y 134567 LATIN CAPITAL LETTER Y
uppercase Z 13567 LATIN CAPITAL LETTER Z
punctuation [ 23678 LEFT SQUARE BRACKET
punctuation \\ 347 REVERSE SOLIDUS
punctuation ] 35678 RIGHT SQUARE BRACKET
punctuation ^ 12348 CIRCUMFLEX ACCENT
punctuation _ 3678 LOW LINE
punctuation ` 5 GRAVE ACCENT
lowercase a 1 LATIN SMALL LETTER A
lowercase b 12 LATIN SMALL LETTER B
lowercase c 14 LATIN SMALL LETTER C
lowercase d 145 LATIN SMALL LETTER D
lowercase e 15 LATIN SMALL LETTER E
lowercase f 124 LATIN SMALL LETTER F
lowercase g 1245 LATIN SMALL LETTER G
lowercase h 125 LATIN SMALL LETTER H
lowercase i 24 LATIN SMALL LETTER I
lowercase j 245 LATIN SMALL LETTER J
lowercase k 13 LATIN SMALL LETTER K
lowercase l 123 LATIN SMALL LETTER L
lowercase m 134 LATIN SMALL LETTER M
lowercase n 1345 LATIN SMALL LETTER N
lowercase o 135 LATIN SMALL LETTER O
lowercase p 1234 LATIN SMALL LETTER P
lowercase q 12345 LATIN SMALL LETTER Q
lowercase r 1235 LATIN SMALL LETTER R
lowercase s 234 LATIN SMALL LETTER S
lowercase t 2345 LATIN SMALL LETTER T
lowercase u 136 LATIN SMALL LETTER U
lowercase v 1236 LATIN SMALL LETTER V
lowercase w 2456 LATIN SMALL LETTER W
lowercase x 1346 LATIN SMALL LETTER X
lowercase y 13456 LATIN SMALL LETTER Y
lowercase z 1356 LATIN SMALL LETTER Z
punctuation { 123678 LEFT CURLY BRACKET
punctuation | 4568 VERTICAL LINE
punctuation } 345678 RIGHT CURLY BRACKET
punctuation ~ 467 TILDE
letter \x007f 7 DELETE
letter \x20AC 1578 EURO SIGN
letter \x201A 457
letter \x0192 58
letter \x201E 2378
letter \x2022 37
letter \x2026 6
letter \x0080 24568 <control-0080>
letter \x0081 45 <control-0081>
letter \x0082 457 BREAK PERMITTED HERE
letter \x0083 5 NO BREAK HERE
letter \x0084 2378 <control-0084>
letter \x0085 6 NEXT LINE (NEL)
letter \x0086 2357 START OF SELECTED AREA
letter \x0087 23578 END OF SELECTED AREA
letter \x0088 5678 CHARACTER TABULATION SET
letter \x0089 3578 CHARACTER TABULATION WITH JUSTIFICATION
letter \x008a 4578 LINE TABULATION SET
letter \x008b 456 PARTIAL LINE FORWARD
letter \x008c 12358 PARTIAL LINE BACKWARD
letter \x008d 3567 REVERSE LINE FEED
letter \x008e 3467 SINGLE SHIFT TWO
letter \x008f 27 SINGLE SHIFT THREE
letter \x0090 357 DEVICE CONTROL STRING
letter \x0091 47 PRIVATE USE ONE
letter \x0092 48 PRIVATE USE TWO
letter \x0093 237 SET TRANSMIT STATE
letter \x0094 568 CANCEL CHARACTER
letter \x0095 37 MESSAGE WAITING
letter \x0096 36 START OF GUARDED AREA
letter \x0097 367 END OF GUARDED AREA
letter \x0098 46 START OF STRING
letter \x0099 268 <control-0099>
letter \x009a 2348 SINGLE CHARACTER INTRODUCER
letter \x009b 4567 CONTROL SEQUENCE INTRODUCER
letter \x009c 1358 STRING TERMINATOR
letter \x009d 23458 OPERATING SYSTEM COMMAND
letter \x009e 346 PRIVACY MESSAGE
letter \x009f 2345678 APPLICATION PROGRAM COMMAND
punctuation \x00a0 0 NO-BREAK SPACE
punctuation \x00a1 256 INVERTED EXCLAMATION MARK
punctuation \x00a2 2578 CENT SIGN
punctuation \x00a3 1238 POUND SIGN
punctuation \x00a4 2367 CURRENCY SIGN
punctuation \x00a5 67 YEN SIGN
punctuation \x00a6 3478 BROKEN BAR
punctuation \x00a7 578 SECTION SIGN
punctuation \x00a8 56 DIAERESIS
punctuation \x00a9 78 COPYRIGHT SIGN
letter \x00aa 234678 FEMININE ORDINAL INDICATOR
punctuation \x00ab 57 LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
punctuation \x00ac 34567 NOT SIGN
punctuation \x00ad 378 SOFT HYPHEN
punctuation \x00ae 13568 REGISTERED SIGN
punctuation \x00af 23567 MACRON
punctuation \x00b0 356 DEGREE SIGN
punctuation \x00b1 123458 PLUS-MINUS SIGN
punctuation \x00b2 238 SUPERSCRIPT TWO
punctuation \x00b3 258 SUPERSCRIPT THREE
punctuation \x00b4 468 ACUTE ACCENT
lowercase \x00b5 236 MICRO SIGN
punctuation \x00b6 1234568 PILCROW SIGN
punctuation \x00b7 38 MIDDLE DOT
punctuation \x00b8 4678 CEDILLA
punctuation \x00b9 28 SUPERSCRIPT ONE
letter \x00ba 7 MASCULINE ORDINAL INDICATOR
punctuation \x00bb 567 RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
punctuation \x00bc 13458 VULGAR FRACTION ONE QUARTER
punctuation \x00bd 458 VULGAR FRACTION ONE HALF
punctuation \x00be 3456 VULGAR FRACTION THREE QUARTERS
punctuation \x00bf 348 INVERTED QUESTION MARK
uppercase \x00c0 123567 LATIN CAPITAL LETTER A WITH GRAVE
uppercase \x00c1 1235678 LATIN CAPITAL LETTER A WITH ACUTE
uppercase \x00c2 1678 LATIN CAPITAL LETTER A WITH CIRCUMFLEX
uppercase \x00c3 14678 LATIN CAPITAL LETTER A WITH TILDE
uppercase \x00c4 34578 LATIN CAPITAL LETTER A WITH DIAERESIS
uppercase \x00c5 167 LATIN CAPITAL LETTER A WITH RING ABOVE
uppercase \x00c6 3457 LATIN CAPITAL LETTER AE
uppercase \x00c7 123467 LATIN CAPITAL LETTER C WITH CEDILLA
uppercase \x00c8 23467 LATIN CAPITAL LETTER E WITH GRAVE
uppercase \x00c9 1234567 LATIN CAPITAL LETTER E WITH ACUTE
uppercase \x00ca 1267 LATIN CAPITAL LETTER E WITH CIRCUMFLEX
uppercase \x00cb 12467 LATIN CAPITAL LETTER E WITH DIAERESIS
uppercase \x00cc 15678 LATIN CAPITAL LETTER I WITH GRAVE
uppercase \x00cd 12678 LATIN CAPITAL LETTER I WITH ACUTE
uppercase \x00ce 1467 LATIN CAPITAL LETTER I WITH CIRCUMFLEX
uppercase \x00cf 124567 LATIN CAPITAL LETTER I WITH DIAERESIS
uppercase \x00d0 68 LATIN CAPITAL LETTER ETH
uppercase \x00d1 1245678 LATIN CAPITAL LETTER N WITH TILDE
uppercase \x00d2 124678 LATIN CAPITAL LETTER O WITH GRAVE
uppercase \x00d3 34678 LATIN CAPITAL LETTER O WITH ACUTE
uppercase \x00d4 14567 LATIN CAPITAL LETTER O WITH CIRCUMFLEX
uppercase \x00d5 145678 LATIN CAPITAL LETTER O WITH TILDE
uppercase \x00d6 24678 LATIN CAPITAL LETTER O WITH DIAERESIS
punctuation \x00d7 13468 MULTIPLICATION SIGN
uppercase \x00d8 2467 LATIN CAPITAL LETTER O WITH STROKE
uppercase \x00d9 234567 LATIN CAPITAL LETTER U WITH GRAVE
uppercase \x00da 125678 LATIN CAPITAL LETTER U WITH ACUTE
uppercase \x00db 1567 LATIN CAPITAL LETTER U WITH CIRCUMFLEX
uppercase \x00dc 12567 LATIN CAPITAL LETTER U WITH DIAERESIS
uppercase \x00dd 257 LATIN CAPITAL LETTER Y WITH ACUTE
uppercase \x00de 1368 LATIN CAPITAL LETTER THORN
lowercase \x00df 23468 LATIN SMALL LETTER SHARP S
lowercase \x00e0 12356 LATIN SMALL LETTER A WITH GRAVE
lowercase \x00e1 123568 LATIN SMALL LETTER A WITH ACUTE
lowercase \x00e2 168 LATIN SMALL LETTER A WITH CIRCUMFLEX
lowercase \x00e3 1468 LATIN SMALL LETTER A WITH TILDE
lowercase \x00e4 3458 LATIN SMALL LETTER A WITH DIAERESIS
lowercase \x00e5 16 LATIN SMALL LETTER A WITH RING ABOVE
lowercase \x00e6 345 LATIN SMALL LETTER AE
lowercase \x00e7 12346 LATIN SMALL LETTER C WITH CEDILLA
lowercase \x00e8 2346 LATIN SMALL LETTER E WITH GRAVE
lowercase \x00e9 123456 LATIN SMALL LETTER E WITH ACUTE
lowercase \x00ea 126 LATIN SMALL LETTER E WITH CIRCUMFLEX
lowercase \x00eb 1246 LATIN SMALL LETTER E WITH DIAERESIS
lowercase \x00ec 1568 LATIN SMALL LETTER I WITH GRAVE
lowercase \x00ed 1268 LATIN SMALL LETTER I WITH ACUTE
lowercase \x00ee 146 LATIN SMALL LETTER I WITH CIRCUMFLEX
lowercase \x00ef 12456 LATIN SMALL LETTER I WITH DIAERESIS
lowercase \x00f0 134568 LATIN SMALL LETTER ETH
lowercase \x00f1 124568 LATIN SMALL LETTER N WITH TILDE
lowercase \x00f2 12468 LATIN SMALL LETTER O WITH GRAVE
lowercase \x00f3 3468 LATIN SMALL LETTER O WITH ACUTE
lowercase \x00f4 1456 LATIN SMALL LETTER O WITH CIRCUMFLEX
lowercase \x00f5 14568 LATIN SMALL LETTER O WITH TILDE
lowercase \x00f6 2468 LATIN SMALL LETTER O WITH DIAERESIS
punctuation \x00f7 2568 DIVISION SIGN
lowercase \x00f8 246 LATIN SMALL LETTER O WITH STROKE
lowercase \x00f9 23456 LATIN SMALL LETTER U WITH GRAVE
lowercase \x00fa 12568 LATIN SMALL LETTER U WITH ACUTE
lowercase \x00fb 156 LATIN SMALL LETTER U WITH CIRCUMFLEX
lowercase \x00fc 1256 LATIN SMALL LETTER U WITH DIAERESIS
lowercase \x00fd 1348 LATIN SMALL LETTER Y WITH ACUTE
lowercase \x00fe 138 LATIN SMALL LETTER THORN
lowercase \x00ff 234568 LATIN SMALL LETTER Y WITH DIAERESIS
punctuation \x0192 58
[
{
"locale": "ar",
"dots": "6",
"id": "ar-g1",
"grade": "1",
"fileName": "ar-ar-g1.utb"
},
{
"locale": "bg",
"dots": "8",
"id": "bg-comp8",
"fileName": "bg.ctb"
},
{
"locale": "ca",
"dots": "6",
"id": "ca-g1",
"grade": "1",
"fileName": "ca-g1.ctb"
},
{
"locale": "hr",
"dots": "8",
"id": "hr-comp8",
"fileName": "hr.ctb"
},
{
"locale": "cs",
"dots": "6",
"id": "cs-g1",
"grade": "1",
"fileName": "cs-g1.ctb"
},
{
"locale": "da",
"dots": "8",
"id": "da-comp8",
"fileName": "da.ctb"
},
{
"locale": "nl",
"dots": "6",
"id": "nl-g1",
"grade": "1",
"fileName": "Nl-Nl-g1.utb"
},
{
"locale": "en_CA",
"dots": "8",
"id": "en-CA-comp8",
"fileName": "en_CA.ctb"
},
{
"locale": "en_GB",
"dots": "6",
"id": "en-GB-g1",
"grade": "1",
"fileName": "en-gb-g1.utb"
},
{
"locale": "en_GB",
"dots": "6",
"id": "en-GB-g2",
"grade": "2",
"fileName": "en-GB-g2.ctb"
},
{
"locale": "en_US",
"dots": "8",
"id": "en-US-comp8",
"fileName": "en-us-comp8.ctb"
},
{
"locale": "en_US",
"dots": "6",
"id": "en-US-g1",
"grade": "1",
"fileName": "en-us-g1.ctb"
},
{
"locale": "en_US",
"dots": "6",
"id": "en-US-g2",
"grade": "2",
"fileName": "en-us-g2.ctb"
},
{
"locale": "et",
"dots": "8",
"id": "et-comp8",
"fileName": "et-g0.utb"
},
{
"locale": "fr",
"dots": "8",
"id": "fr-comp8",
"fileName": "fr-2007.ctb"
},
{
"locale": "fr_CA",
"dots": "6",
"id": "fr-CA-g1",
"grade": "1",
"fileName": "fr-ca-g1.utb"
},
{
"locale": "fr_CA",
"dots": "6",
"id": "fr-CA-g2",
"grade": "2",
"fileName": "Fr-Ca-g2.ctb"
},
{
"locale": "fr_FR",
"dots": "6",
"id": "fr-FR-g1",
"grade": "1",
"fileName": "fr-fr-g1.utb"
},
{
"locale": "fr_FR",
"dots": "6",
"id": "fr-FR-g2",
"grade": "2",
"fileName": "Fr-Fr-g2.ctb"
},
{
"locale": "fi",
"dots": "8",
"id": "fi-comp8",
"fileName": "fi-fi-8dot.ctb"
},
{
"locale": "de",
"dots": "8",
"id": "de-comp8",
"fileName": "de-de-comp8.ctb"
},
{
"locale": "de_CH",
"dots": "6",
"id": "de-CH-g0",
"grade": "0",
"fileName": "de-ch-g0.utb"
},
{
"locale": "de_CH",
"dots": "6",
"id": "de-CH-g1",
"grade": "1",
"fileName": "de-ch-g1.ctb"
},
{
"locale": "de_CH",
"dots": "6",
"id": "de-CH-g2",
"grade": "2",
"fileName": "de-ch-g2.ctb"
},
{
"locale": "de_DE",
"dots": "6",
"id": "de-DE-g0",
"grade": "0",
"fileName": "de-de-g0.utb"
},
{
"locale": "de_DE",
"dots": "6",
"id": "de-DE-g1",
"grade": "1",
"fileName": "de-de-g1.ctb"
},
{
"locale": "de_DE",
"dots": "6",
"id": "de-DE-g2",
"grade": "2",
"fileName": "de-de-g2.ctb"
},
{
"locale": "el",
"dots": "6",
"id": "el-g1",
"grade": "1",
"fileName": "gr-gr-g1.utb"
},
{
"locale": "hi",
"dots": "8",
"id": "hi-comp8",
"fileName": "hi.ctb"
},
{
"locale": "hi",
"dots": "6",
"id": "hi-g1",
"grade": "1",
"fileName": "hi-in-g1.utb"
},
{
"locale": "hu",
"dots": "8",
"id": "hu-comp8",
"fileName": "hu-hu-comp8.ctb"
},
{
"locale": "hu",
"dots": "6",
"id": "hu-g1",
"grade": "1",
"fileName": "hu-hu-g1.ctb"
},
{
"locale": "is",
"dots": "8",
"id": "is-comp8",
"fileName": "is.ctb"
},
{
"locale": "it",
"dots": "8",
"id": "it-comp8",
"fileName": "it-it-comp8.utb"
},
{
"locale": "it",
"dots": "6",
"id": "it-g1",
"grade": "1",
"fileName": "it-it-comp6.utb"
},
{
"locale": "lv",
"dots": "6",
"id": "lv-g1",
"grade": "1",
"fileName": "Lv-Lv-g1.utb"
},
{
"locale": "lt",
"dots": "8",
"id": "lt-comp8",
"fileName": "lt.ctb"
},
{
"locale": "nb",
"dots": "8",
"id": "nb-comp8",
"fileName": "no-no.ctb"
},
{
"locale": "nb",
"dots": "6",
"id": "nb-g0",
"grade": "0",
"fileName": "no-no-g0.utb"
},
{
"locale": "nb",
"dots": "6",
"id": "nb-g1",
"grade": "1",
"fileName": "no-no-g1.ctb"
},
{
"locale": "nb",
"dots": "6",
"id": "nb-g2",
"grade": "2",
"fileName": "no-no-g2.ctb"
},
{
"locale": "nb",
"dots": "6",
"id": "nb-g3",
"grade": "3",
"fileName": "no-no-g3.ctb"
},
{
"locale": "pl",
"dots": "6",
"id": "pl-g1",
"grade": "1",
"fileName": "Pl-Pl-g1.utb"
},
{
"locale": "pt",
"dots": "8",
"id": "pt-comp8",
"fileName": "pt-pt-comp8.ctb"
},
{
"locale": "pt",
"dots": "6",
"id": "pt-g1",
"grade": "1",
"fileName": "pt-pt-g1.utb"
},
{
"locale": "pt",
"dots": "6",
"id": "pt-g2",
"grade": "2",
"fileName": "pt-pt-g2.ctb"
},
{
"locale": "ro",
"dots": "8",
"id": "ro-comp8",
"fileName": "ro.ctb"
},
{
"locale": "ru",
"dots": "8",
"id": "ru-comp8",
"fileName": "ru.ctb"
},
{
"locale": "ru",
"dots": "6",
"id": "ru-g1",
"grade": "1",
"fileName": "ru-ru-g1.utb"
},
{
"locale": "sr",
"dots": "6",
"id": "sr-g1",
"grade": "1",
"fileName": "sr-g1.ctb"
},
{
"locale": "sk",
"dots": "6",
"id": "sk-g1",
"grade": "1",
"fileName": "sk-sk-g1.utb"
},
{
"locale": "sl",
"dots": "6",
"id": "sl-g1",
"grade": "1",
"fileName": "sl-si-g1.utb"
},
{
"locale": "es",
"dots": "8",
"id": "es-comp8",
"fileName": "Es-Es-G0.utb"
},
{
"locale": "es",
"dots": "6",
"id": "es-g1",
"grade": "1",
"fileName": "es-g1.ctb"
},
{
"locale": "sv",
"dots": "8",
"id": "sv-comp8",
"fileName": "sv-1996.ctb"
},
{
"locale": "sv",
"dots": "6",
"id": "sv-g1",
"grade": "1",
"fileName": "Se-Se-g1.utb"
},
{
"locale": "tr",
"dots": "8",
"id": "tr-comp8",
"fileName": "tr.ctb"
},
{
"locale": "vi",
"dots": "8",
"id": "vi-comp8",
"fileName": "vi.ctb"
},
{
"locale": "zh",
"dots": "8",
"id": "zh-comp8",
"fileName": "zh-hk.ctb"
},
{
"locale": "zh_TW",
"dots": "8",
"id": "zh-TW-comp8",
"fileName": "zh-tw.ctb"
}
]
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment