Converters\BooleanToBorderBrushConverter.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
using System.Windows.Media;
namespace Lexical.Converters
{
public class BooleanToBorderBrushConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var result = Colors.SeaGreen;
if ((bool)value)
{
result = Colors.Brown;
}
return new SolidColorBrush(result);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
Converters\BooleanToVisibilityConverter.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
namespace Lexical.Converters
{
public class BooleanToVisibitilyConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var result = (bool)value ? Visibility.Visible : Visibility.Collapsed;
if (parameter as string == "invert")
{
result = (bool)value ? Visibility.Collapsed : Visibility.Visible;
}
return result;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
Core\NavigationProvider.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using Lexical.Models;
namespace Lexical.Core
{
public class NavigationProvider
{
private static NavigationProvider provider;
public static NavigationProvider Provider
{
get
{
return provider;
}
}
private Frame frame;
private Dictionary<NavigationSource, Uri> navigationMapping;
private object parameter;
public object Parameter
{
get { return parameter; }
set { parameter = value; }
}
private void MapNavigation()
{
this.navigationMapping = new Dictionary<NavigationSource, Uri>
{
{NavigationSource.Main, new Uri("Views\\MainPage.xaml", UriKind.Relative)},
{NavigationSource.Lexical, new Uri("Views\\LexicalPage.xaml", UriKind.Relative)},
{NavigationSource.Stub, new Uri("Views\\StubPage.xaml", UriKind.Relative)},
//{NavigationSource.Conference, new Uri("Views\\InputData\\ConferenceView.xaml", UriKind.Relative)},
//{NavigationSource.Journal, new Uri("Views\\InputData\\JournalView.xaml", UriKind.Relative)},
//{NavigationSource.NDR, new Uri("Views\\InputData\\NdrView.xaml", UriKind.Relative)},
//{NavigationSource.NewsPaper, new Uri("Views\\InputData\\NewsPaperView.xaml", UriKind.Relative)},
//{NavigationSource.Site, new Uri("Views\\InputData\\SiteView.xaml", UriKind.Relative)},
//{NavigationSource.Atlas, new Uri("Views\\InputData\\AtlasView.xaml", UriKind.Relative)},
//{NavigationSource.Catalog, new Uri("Views\\InputData\\CatalogView.xaml", UriKind.Relative)},
//{NavigationSource.Dictionary, new Uri("Views\\InputData\\Dictionary.xaml", UriKind.Relative)},
//{NavigationSource.LegislationDocument, new Uri("Views\\InputData\\LegislationDocumentView.xaml", UriKind.Relative)},
//{NavigationSource.Standard, new Uri("Views\\InputData\\StandardView.xaml", UriKind.Relative)}
};
}
public void GoBack()
{
if (this.frame.CanGoBack)
{
this.frame.GoBack();
}
}
public void Navigate(NavigationSource newSource)
{
var newUri = this.navigationMapping[newSource];
frame.Navigate(newUri);
this.parameter = null;
}
public void Navigate(NavigationSource newSource, object parameter)
{
var newUri = this.navigationMapping[newSource];
frame.Navigate(newUri, parameter);
this.parameter = parameter;
}
public static void InitializeNavigation(Frame frame)
{
provider = new NavigationProvider();
provider.frame = frame;
provider.MapNavigation();
}
}
}
Core\RelayCommand.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
namespace Lexical.Core
{
public class RelayCommand : ICommand
{
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
public RelayCommand(Action<object> execute)
: this(execute, null)
{ }
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
_execute(parameter);
}
}
}
Core\RtbText.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Xml;
using System.Xml.Linq;
using Remotion.Utilities;
namespace Lexical.Core
{
public class RtbText
{
public static readonly DependencyProperty TextProperty = DependencyProperty.RegisterAttached(
"Text", typeof(string), typeof(RtbText), new PropertyMetadata(default(string), OnRtbTextChanged));
public static void SetText(DependencyObject element, string value)
{
element.SetValue(TextProperty, value);
}
public static string GetText(DependencyObject element)
{
return (string)element.GetValue(TextProperty);
}
private static void OnRtbTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var rtb = d as RichTextBox;
if (e.OldValue != null)
{
rtb.Document.Blocks.Clear();
}
if (e.NewValue != null)
{
GenerateText(rtb, (string)e.NewValue);
}
}
private static void GenerateText(RichTextBox rtb, string text)
{
var newText = "<document>" + text + "</document>";
var doc = XDocument.Parse(newText);
var rootNode = doc.Root as XElement;
if (rootNode.HasElements)
{
var paragraph = new Paragraph();
ParseNodes(paragraph, rootNode.FirstNode);
rtb.Document.Blocks.Add(paragraph);
}
else
{
var paragraph = new Paragraph();
var run = new Run {Text = text};
paragraph.Inlines.Add(run);
rtb.Document.Blocks.Add(paragraph);
}
rtb.FontSize = 20;
}
private static void ParseNodes(Paragraph paragraph, XNode node)
{
if (node.NodeType == XmlNodeType.Text)
{
var xText = (XText)node;
var run = new Run
{
Text = xText.Value
};
paragraph.Inlines.Add(run);
}
else
{
var element = node as XElement;
Run run = null;
string value = element.Value;
if (node.PreviousNode is XElement)
{
value = value.Insert(0, " ");
}
switch (element.Name.ToString())
{
case "TrueLexical":
run = new Run
{
Text = value,
Foreground = new SolidColorBrush(Colors.SeaGreen)
};
break;
case "FalseLexical":
run = new Run
{
Text = value,
Foreground = new SolidColorBrush(Colors.Brown)
};
break;
}
if (run != null)
{
var bold = new Bold(run);
paragraph.Inlines.Add(bold);
}
}
var nextNode = node.NextNode;
if (nextNode != null)
{
ParseNodes(paragraph, nextNode);
}
}}}
DataProviders\ExcelProvider.cs:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Lexical.Models.DbModels;
using Lexical.Models.Excel;
using LinqToExcel;
namespace Lexical.DataProviders
{
public class ExcelProvider
{
private static readonly ExcelProvider excelProvider = new ExcelProvider();
public static ExcelProvider Instance
{
get
{
return excelProvider;
}
}
public List<LexicalModel> Lexicals
{
get
{
return lexicals;
}
}
private Regex numbersRegex = new Regex(@"\A\d\*{0,1}\.[ ]{0,}");
private Regex defintionStyleRegex = new Regex(@"\[\w+-style\]\.[ ]");
private List<LexicalModel> lexicals;
public async Task ParseExcelDb()
{
var dir = Directory.GetCurrentDirectory();
var path = Path.Combine(dir, "Assets", "LexicalExcel.xlsx");
var excel = new ExcelQueryFactory(path);
excel.AddMapping("Parameters", "Parametr");
var data = excel.Worksheet<ExcelDbModel>().ToList();
this.lexicals = new List<LexicalModel>();
foreach (var excelDbModel in data) {
var lexical = new LexicalModel();
var definitions = new List<Definition>();
var translation = new Translation();
var splitted = excelDbModel.Parameters.Split(new[] { Environment.NewLine, "\n" }, StringSplitOptions.RemoveEmptyEntries);
var list = new List<string>(splitted);
for (int i = 0; i < list.Count; i++)
{
var splittedText = list[i];
string nextSplittedText = null;
if (i + 1 < list.Count)
{
nextSplittedText = list[i + 1];
}
if (this.numbersRegex.IsMatch(splittedText) || i == 0)
{
var definitionText = splittedText;
var number = this.numbersRegex.Match(definitionText).Value;
var definition = new Definition();
if (number.Contains("*"))
{
definition.IsStar = true;
}
if (this.defintionStyleRegex.IsMatch(definitionText))
{
var match = this.defintionStyleRegex.Match(splittedText).Value.Trim();
definitionText = this.defintionStyleRegex.Replace(splittedText, "");
definition.Style = match.Replace("[", string.Empty)
.Replace("-style]", string.Empty); }
if (nextSplittedText != null && nextSplittedText.Trim().StartsWith("-"))
{
i++;
definition.Example = nextSplittedText;
}
definition.DefinitionText = definitionText;
definitions.Add(definition);
}
else
{
var translationEndIndex = 0;
var rightTranslate = list.Skip(i - 1).FirstOrDefault(a => a.Contains("Правильний переклад"));
if (rightTranslate != null)//если нашло, то запоминаем его
{
translationEndIndex = -2;
lexical.RightTranslation = rightTranslate;
}
translation.TranslationText = string.Join(Environment.NewLine,
list.Skip(i).Take(list.Count - 1 + translationEndIndex));
translation.TranslationText = translation.TranslationText.Replace("#", "");
break;
}
}
lexical.Definitions = definitions;
lexical.Translation = translation;
if (excelDbModel.Name.Contains("#"))
{
lexical.IsFalseLexicalParallel = true;
}
var declinations = excelDbModel.Sklonenie.Split(new string[] { ";", " " },
StringSplitOptions.RemoveEmptyEntries);
lexical.Declesions = new List<Declesion>(declinations.Select(a => new Declesion { Word = a }));
lexical.MainWord = excelDbModel.Name.Replace("#", "");
lexicals.Add(lexical);
}
}
}
}
ViewModels\LexicalViewModel.cs:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Lexical.Core;
using Lexical.DataProviders;
using Lexical.Models;
using Lexical.Models.DbModels;
using Microsoft.Win32;
namespace Lexical.ViewModels
{
public class LexicalViewModel : ViewModel
{
private static readonly Dictionary<string, string> styleReplaceDictionary = new Dictionary<string, string>()
{
{"техн", "технічному"},
{"тех", "технічному"},
{"літ", "літературному"},
{"політ", "політичному"},
{"юрид", "юридичному"},
{"програм", "програмному"},
{"программ", "програмному"},
{"спорт", "спортивному"},
{"муз", "музичному"},
{"екон", "економічному"},
{"воєн", "воєнному"},
{"лінгв", "лінгвістичному"},
{"фіз", "фізичному"},
{"матем", "математичному"},
{"мед", "медичному"}
};
private string[] separators = new[] { ",", ".", "-", " ", ":", ";", Environment.NewLine };
private LexicalComparer comparer = new LexicalComparer();
private string text;
private string styleText;
public LexicalViewModel()
{
this.OpenFile = new RelayCommand(this.OpenFileExecute);
}
public RelayCommand OpenFile { get; protected set; }
public string Text
{
get
{
return text;
}
set
{
text = value;
this.Raise();
}
}
public string StyleText
{
get
{
return styleText;
}
set
{
styleText = value;
this.Raise();
}
}
private int trueCount;
public int TrueCount
{
get { return trueCount; }
set
{
trueCount = value;
this.Raise();
}
}
private int falseCount;
public int FalseCount
{
get { return falseCount; }
set
{
falseCount = value;
this.Raise();
}
}
private List<LexicalModel> lexicals;
public List<LexicalModel> Lexicals
{
get { return lexicals; }
set
{
lexicals = value;
this.Raise();
}
}
protected override async void InitializeViewModel(object obj)
{
this.BusyCounter++;
var param = NavigationProvider.Provider.Parameter as FileStream;
if (param != null)
{
using (var reader = new StreamReader(param))
{
this.text = await reader.ReadToEndAsync();
}
NavigationProvider.Provider.Parameter = null;
}
if (!string.IsNullOrWhiteSpace(this.text))
{
var splitted = this.text.Split(this.separators, StringSplitOptions.RemoveEmptyEntries);//вытаскиваем все слова из файла
var parts = this.SplitArray(5, splitted.Distinct());
var lexicals = ExcelProvider.Instance.Lexicals;
var tasks = new List<Task<List<LexicalModel>>>();
foreach (var part in parts)
{
var part1 = part;
var task = Task.Run(() =>
{
var result = new List<LexicalModel>();
for (int i = 0; i < part1.Count; i++)
{
var item = part1[i];
var lm = lexicals.FirstOrDefault(a => a.Declesions.Any(b => item.ToLower().Contains(b.Word.ToLower())));
if (lm != null)
{
result.Add(lm);
}
}
result = result.Distinct(this.comparer).ToList();
return result;
});
tasks.Add(task);
}
var matchedLexicalsParts = await Task.WhenAll(tasks);
var matchedLexicals = matchedLexicalsParts.SelectMany(a => a).Distinct(this.comparer).ToList();
var styles = matchedLexicals.SelectMany(a => a.Definitions.Select(b => b.Style)).Where(a => a != null);
var style = styles.GroupBy(a => a).Select(x => new { Key = x.Key, Count = x.Count() }).OrderByDescending(a => a.Count).FirstOrDefault();
if (style != null)
{
var formattedStyle = this.GetFullStyle(style.Key);
var lexicalWithStyle = (from ml in matchedLexicals
from dg in ml.Definitions
where dg.Style != null && dg.Style.Contains(style.Key)
select ml).ToList();
foreach (var lexicalModel in lexicalWithStyle)
{
var definitionsWithStyle = lexicalModel.Definitions.Where(a => a.Style != null && a.Style.Contains(style.Key));
lexicalModel.Definitions = definitionsWithStyle.ToList();
}
matchedLexicals = lexicalWithStyle;
this.StyleText = string.Format("Переважно текст у \"{0}\" стилі", formattedStyle);
}
else
{
this.StyleText = string.Format("Не вдалося встановити стиль текста");
}
foreach (var matchedLexical in matchedLexicals)
{
foreach (var declesion in matchedLexical.Declesions)
{
var pattern = string.Format(@"(?<start>\W|\A)(?<word>{0})(?<end>[\W])", declesion.Word);
var matches = Regex.Matches(this.Text, pattern, RegexOptions.IgnoreCase).Cast<Match>().Select(a => a.Value).Distinct();
var enumerable = matches as string[] ?? matches.ToArray();
for (var i = 0; i < enumerable.Length; i++)
{
var match = enumerable[i];
var replace = "\\W*";
enumerable[i] = Regex.Replace(match, replace, "");
}
matches = enumerable.Distinct();
foreach (var match in matches)
{
var matchPattern = string.Format(@"(?<start>\W|\A)(?<word>{0})(?<end>[\W])", match);
var prefix = !matchedLexical.IsFalseLexicalParallel ? "True" : "False";
var tag = prefix + "Lexical";
var newItem = "${start}" + "<" + tag + ">" + match + "</" + tag + ">" + "$" + "{end}";
this.text = Regex.Replace(this.text, matchPattern, newItem);
//var ds = text;
}
}
}
this.FalseCount = matchedLexicals.Count(a => a.IsFalseLexicalParallel);//считаем кол-во ложных ЛП
this.TrueCount = matchedLexicals.Count(a => !a.IsFalseLexicalParallel);//колво ЛП
this.Raise("Text");
this.Lexicals = matchedLexicals.OrderBy(a=>a.MainWord).ToList();
}
this.BusyCounter--;
}
private string GetFullStyle(string style) {
string result = style;
var tempStyle = style.Replace(".", "");
if (styleReplaceDictionary.ContainsKey(tempStyle))
{
result = styleReplaceDictionary[tempStyle];
}
return result;
}
private List<List<T>> SplitArray<T>(int partsCount, IEnumerable<T> sourceArray)
{
var splitted = new List<List<T>>();
var enumerable = sourceArray as T[] ?? sourceArray.ToArray();
var take = enumerable.Length / partsCount;
for (var i = 0; i < partsCount + 1; i++)
{
var list = new List<T>(enumerable.Skip(i * take).Take(take));
if (list.Any())
{
splitted.Add(list);
}
}
return splitted;
}
private void OpenFileExecute(object obj)
{
if (!this.IsBusy)
{
var dialog = new OpenFileDialog();
var fileChecked = dialog.ShowDialog();
if (fileChecked.HasValue && fileChecked.Value)
{
var file = dialog.OpenFile();
NavigationProvider.Provider.Parameter = file;
//чистим все заполнения
this.Text = null;
this.Lexicals = null;
this.StyleText = null;
this.TrueCount = 0;
this.FalseCount = 0;
this.InitializeViewModel(null);
}
}}}}
ViewModels\MainViewModel.cs:
using System.Threading.Tasks;
using Lexical.Core;
using Lexical.DataProviders;
using Lexical.Models;
using Microsoft.Win32;
namespace Lexical.ViewModels
{
public class MainViewModel : ViewModel
{
public MainViewModel()
{
this.OpenFile = new RelayCommand(this.OpenFileExecute);
}
public RelayCommand OpenFile { get; protected set; }
private void OpenFileExecute(object obj)
{
if (!this.IsBusy)
{
var dialog = new OpenFileDialog();
var fileChecked = dialog.ShowDialog();
if (fileChecked.HasValue && fileChecked.Value)
{
var file = dialog.OpenFile();
NavigationProvider.Provider.Navigate(NavigationSource.Lexical, file);
}
}
}
protected override async void InitializeViewModel(object obj)
{
this.BusyCounter++;
await Task.Run(() => ExcelProvider.Instance.ParseExcelDb());
this.BusyCounter--;
}
}
}
ViewModels\ViewModel.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Windows.Media;
using Lexical.Core;
namespace Lexical.ViewModels
{
public class ViewModel : INotifyPropertyChanged
{
private string _literatureSource;
public string LiteratureSource
{
get { return _literatureSource; }
set
{
_literatureSource = value;
this.Raise("LiteratureSource");
}
}
#region Inotify
public event PropertyChangedEventHandler PropertyChanged;
public void Raise([CallerMemberName] string property = "")
{
var handl = this.PropertyChanged;
if (handl != null)
{
handl.Invoke(this, new PropertyChangedEventArgs(property));
}
}
#endregion
public ICommand InitializeCommand { get; set; }
public ICommand TestCommand { get; set; }
private short busyCounter;
public ViewModel()
{
this.InitializeCommand = new RelayCommand(this.InitializeViewModel);
}
public short BusyCounter
{
get
{
return this.busyCounter;
}
set
{
this.busyCounter = value;
this.Raise("IsBusy");
}
}
public bool IsBusy
{
get
{
if (busyCounter < 0) throw new ArgumentOutOfRangeException("счетчик
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.