az
Version:
A NLP library for Russian language
203 lines (187 loc) • 10.3 kB
HTML
<html>
<head>
<meta charset="utf-8">
<title>Az Demo</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="//fonts.googleapis.com/css?family=Open+Sans:400,700,400italic,300,600&subset=latin,cyrillic,cyrillic-ext,latin-ext" rel="stylesheet" type="text/css">
<link href="uikit.css" rel="stylesheet">
<script src="../src/az.js"></script>
<script src="../src/az.dawg.js"></script>
<script src="../src/az.morph.js"></script>
<script src="../src/az.tokens.js"></script>
<style>
.token {
height: 18px;
max-width: 160px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
vertical-align: middle;
display: inline-block;
padding: 1px 5px;
border-radius: 3px;
margin: 2px;
background: #ECECEC;
cursor: default;
}
/* Simple tokens */
.token-CYRIL, .token-WORD {
background: #FFBFBF;
}
.token-LATIN, .token-MIXED {
background: #FF8686;
}
.token-PUNCT {
background: #B1BEFF;
}
.token-NUMBER {
background: #A1EF82;;
}
.token-SPACE {
background: #ECECEC;
}
.token-OTHER {
background: #9E9E9E;
color: #FFF;
}
.token-LINK {
background: #1E1AFF;
color: #FFF;
}
.token-EMAIL {
background: #13B5DA;
color: #FFF;
}
.token-HASHTAG {
background: #9C2FFF;
color: #FFF;
}
.token-MARKUP {
background: #2D9812;
color: #FFF;
}
.token-TAG {
background: #F79F00;
color: #FFF;
}
.token-CONTENT {
background: #BFBF00;
color: #FFF;
}
.parse > div {
background: #fafafa;
color: #666;
border: 1px solid #e5e5e5;
border-radius: 4px;
border-bottom: none;
}
</style>
</head>
<body style="padding: 20px">
<div class="uk-grid uk-form">
<div class="uk-width-large-1-2">
<h3>Текст для токенизации</h3>
<textarea id="text" class="pure-input-1" style="height: 270px; width: 100%" placeholder="Текст для разбора">Текст (от лат. textus — «ткань; сплетение, связь, паутина, сочетание») — зафиксированная на каком-либо материальном носителе человеческая мысль; в общем плане связная и полная последовательность символов.
Существуют две основные трактовки понятия «текст»: «имманентная» (расширенная, философски нагруженная) и «репрезентативная» (более частная). Имманентный подход подразумевает отношение к тексту как к автономной реальности, нацеленность на выявление его внутренней структуры. Репрезентативный — рассмотрение текста как особой формы представления знаний о внешней тексту действительности.
В лингвистике термин текст используется в широком значении, включая и образцы устной речи. Восприятие текста изучается в рамках лингвистики текста и психолингвистики. Так, например, И. Р. Гальперин определяет текст следующим образом: «это письменное сообщение, объективированное в виде письменного документа, состоящее из ряда высказываний, объединённых разными типами лексической, грамматической и логической связи, имеющее определённый моральный характер, прагматическую установку и соответственно литературно обработанное»[1].</textarea>
<h3>Легенда</h3>
<p class="uk-clearfix" style="margin-bottom: 20px" id="tokensLegend"></p>
</div>
<div class="uk-width-large-1-2">
<h3>Результат токенизации</h3>
<div id="tokensResults"></div>
</div>
</div>
<hr/>
<div class="uk-form">
<h3>Слово для морфологического разбора<br/><small>(можно кликать по кириллическим токенам сверху)</small></h3>
<input id="word" type="text" style="width: 50%" placeholder="Слово для разбора" value="варкалось">
</div>
<h3>Результаты разбора</h3>
<div class="uk-grid" id="morphResults">
</div>
<script>
function showAll(variantId) {
var el = document.getElementById('allForms' + variantId);
el.style.display = (el.style.display == 'none') ? 'table-row' : 'none';
}
Az.Morph.init('../dicts', function(err, Morph) {
document.getElementById('word').addEventListener('keyup', updateMorph, false);
updateMorph();
});
function updateMorph() {
var variants = Az.Morph(document.getElementById('word').value, { typos: 'auto' });
var html = [];
for (var i = 0; i < variants.length; i++) {
html.push('<div class="uk-width-medium-1-3 parse" style="margin-bottom: 20px"><div><table class="uk-table uk-table-striped uk-table-condensed" style="font-size: 13px">' +
'<tr><th colspan="2">' + variants[i] + '</th></tr>' +
'<tr><td width="40%">Score</td><td><b>' + variants[i].score.toFixed(6) + '</b></td></tr>' +
'<tr><td width="40%">Парсер</td><td><b>' + variants[i].parser + '</b></td></tr>' +
'<tr><td width="40%">Граммемы<br/><small>по-русски</small></td><td>' + variants[i].tag.ext + '</td></tr>' +
'<tr><td width="40%">Граммемы<br/><small>внутренний формат</small></td><td>' + variants[i].tag + '</td></tr>' +
'<tr><td width="40%">Начальная форма</td><td>' + variants[i].normalize() + '</td></tr>' +
'<tr><td width="40%">Начальная форма<br/><small>(та же часть речи)</small></td><td>' + variants[i].normalize(true) + '</td></tr>' +
'<tr><td width="40%">Устранено повторов букв</td><td>' + (variants[i].stutterCnt || 0) + '</td></tr>' +
'<tr><td width="40%">Устранено опечаток</td><td>' + (variants[i].typosCnt || 0) + '</td></tr>');
if (variants[i].formCnt) {
html.push(
'<tr><td colspan="2"><a href="#" onclick="showAll(' + i + '); return false;">Показать всю парадигму (' + variants[i].formCnt + ' ' + Az.Morph('форма')[0].pluralize(variants[i].formCnt) + ')</a></td></tr>' +
'<tr id="allForms' + i + '" style="display: none"><td colspan="2" style="padding: 0"><table class="uk-table uk-table-condensed" style="font-size: 13px; margin-bottom: 0px">');
for (var formIdx = 0; formIdx < variants[i].formCnt; formIdx++) {
var form = variants[i].inflect(formIdx);
html.push('<tr><td width="40%"><strong>' + form + '</strong></td><td>' + form.tag.ext + '</td></tr>');
}
html.push('</table></td></tr>');
}
html.push('</table></div></div>');
}
if (!html.length) {
html.push('<div class="uk-width-1"><i>Нет вариантов</i></div>');
}
document.getElementById('morphResults').innerHTML = html.join('');
}
var types = ['SPACE', 'WORD', 'NUMBER', 'PUNCT', 'LINK', 'EMAIL', 'HASHTAG', 'MARKUP', 'TAG', 'CONTENT', 'OTHER'].map(function(type) {
return Az.Tokens[type];
});
var html = types.map(function(type) {
return '<span style="white-space: nowrap; float: left;"><input id="filter-' + type + '" type="checkbox" checked onchange="update()" style="margin-left: 10px"/><span class="token token-' + type + '" style="cursor: default">' + type + '</span></span>';
});
document.getElementById('tokensLegend').innerHTML = html.join('');
var tokens = [], timeSt, timeEn;
function update() {
var incl = [];
for (var i = 0; i < types.length; i++) {
if (document.getElementById('filter-' + types[i]).checked) {
incl.push(types[i]);
}
}
if (incl.indexOf(Az.Tokens.CYRIL) > -1 || incl.indexOf(Az.Tokens.LATIN) > -1) {
incl.push(Az.Tokens.WORD);
}
html = tokens.done(incl, false).map(function(token, i) {
if ((token.type === Az.Tokens.WORD) && (token.subType === Az.Tokens.CYRIL)) {
return '<span class="token token-' + token.type + (token.subType ? ' token-' + token.subType : '') + '" title="' + token.type + (token.subType ? ', ' + token.subType : '') + '" onclick="morph(\'' + token.toString().split('\'').join('\\\'') + '\');" style="cursor: pointer">' + token.toString().split('&').join('&').split('<').join('<').split(' ').join(' ').split('\n').join('↵') + '</span>';
}
return '<span class="token token-' + token.type + (token.subType ? ' token-' + token.subType : '') + '" title="' + token.type + (token.subType ? ', ' + token.subType : '') + '">' + token.toString().split('&').join('&').split('<').join('<').split(' ').join(' ').split('\n').join('↵') + '</span>';
});
document.getElementById('tokensResults').innerHTML = html.join('') + '<p>Токенизация выполнена за ' + (timeEn - timeSt) + 'мс, всего ' + tokens.tokens.length + ' токенов</p>';
}
function morph(s) {
document.getElementById('word').value = s;
updateMorph();
}
function tokenize() {
timeSt = (new Date()).getTime();
tokens = Az.Tokens(document.getElementById('text').value, {
html: true,
wiki: true,
markdown: true
});
timeEn = (new Date()).getTime();
update();
}
document.getElementById('text').addEventListener('keyup', tokenize, false);
tokenize();
</script>
</body>
</html>