feat: add translator

This commit is contained in:
Zhicheng Wang 2017-07-28 22:40:56 +08:00
parent a529ec5a81
commit a5fc2f430c
7 changed files with 69 additions and 4 deletions

View File

@ -43,7 +43,7 @@ Angular 初学者可能希望跟随下面的常见学习路径。
1. {@a architecture}Read the [Architecture](guide/architecture) overview for the big picture.
{@a architecture}阅读[架构](guide/architecture)了解大局。
阅读[架构](guide/architecture)了解大局。
1. [The Root Module](guide/appmodule) introduces the `NgModule` class that tells Angular how to compile and run your application.

View File

@ -1,7 +1,7 @@
import {
Component, ComponentFactory, ComponentFactoryResolver, ComponentRef,
DoCheck, ElementRef, EventEmitter, Injector, Input, OnDestroy,
Output, ViewEncapsulation
Output, ViewEncapsulation, HostListener
} from '@angular/core';
import { EmbeddedComponents } from 'app/embedded/embedded.module';
@ -111,6 +111,23 @@ export class DocViewerComponent implements DoCheck, OnDestroy {
private selectorToContentPropertyName(selector: string) {
return selector.replace(/-(.)/g, (match, $1) => $1.toUpperCase()) + 'Content';
}
@HostListener('click', ['$event'])
toggleTranslationOrigin($event: MouseEvent): void {
const element = $event.target as Element;
if (element.hasAttribute('translation-result')) {
const origin = element.nextElementSibling;
if (!origin) {
return;
}
if (origin.getAttribute('translation-origin') === 'on') {
origin.setAttribute('translation-origin', 'off');
} else {
origin.setAttribute('translation-origin', 'on');
}
}
}
}
class DisplayedDoc {

View File

@ -0,0 +1,7 @@
[translation-origin=off] {
display: none;
}
[translation-origin=on] {
border-top: 1px dashed #0273D4;
}

View File

@ -13,6 +13,8 @@
@import './1-layouts/layouts-dir';
@import'./2-modules/modules-dir';
@import 'translator';
// import additional scss
// ********************************************************* //

View File

@ -1,6 +1,8 @@
const remark = require('remark');
const html = require('remark-html');
const {markAndSwap} = require('./translator');
/**
* @dgService renderMarkdown
* @description
@ -18,7 +20,7 @@ module.exports = function renderMarkdown() {
.use(html);
return function renderMarkdownImpl(content) {
return renderer.processSync(content).toString();
return markAndSwap(renderer.processSync(content).toString());
};
/**
@ -206,4 +208,4 @@ function createOpenMatcher(elementNameMatcher) {
function createCloseMatcher(elementNameMatcher) {
return `</${elementNameMatcher}>`;
}
}

View File

@ -0,0 +1,24 @@
function mark(text) {
return text.replace(/<(h\d|header|p|a)([\s\S]*?)>([\s\S]+?)<\/\1>/gi, function ($0, $1, $2, $3) {
const suffix = isTranslation($3) ? 'result' : 'origin=off';
return `<${$1} translation-${suffix} ${$2}>${$3}</${$1}>`;
});
}
function swap(text) {
return text.replace(/<(\w+)( translation-origin\b[\s\S]*?)<\/\1>(\s*)<\1( translation-result\b[\s\S]*?)<\/\1>/gi, '<$1$4</$1>$3<$1$2</$1>');
}
function markAndSwap(text) {
return swap(mark(text));
}
function isTranslation(text) {
return text && /[\u2E80-\u2EFF\u2F00-\u2FDF\u3000-\u303F\u31C0-\u31EF\u3200-\u32FF\u3300-\u33FF\u3400-\u4DBF\u4DC0-\u4DFF\u4E00-\u9FBF\uF900-\uFAFF\uFE30-\uFE4F\uFF00-\uFFEF]/.test(text);
}
module.exports = {
mark,
swap,
markAndSwap,
};

View File

@ -0,0 +1,13 @@
const { expect } = require('chai');
const { mark, swap } = require('./translator');
it('mark translation results and origins', () => {
expect(mark('<h1>AngularJS to Angular</h1>\n<h1>从 AngularJS 到 Angular 快速参考</h1>'))
.equal('<h1 translation-origin=off >AngularJS to Angular</h1>\n<h1 translation-result >从 AngularJS 到 Angular 快速参考</h1>');
});
it('swap result and origin', () => {
expect(swap('<h1 translation-origin=off >AngularJS to Angular</h1>\n<h1 translation-result >从 AngularJS 到 Angular 快速参考</h1>'))
.equal('<h1 translation-result >从 AngularJS 到 Angular 快速参考</h1>\n<h1 translation-origin=off >AngularJS to Angular</h1>');
});