Skip to content
Snippets Groups Projects
Commit c88d9b55 authored by Frank Steinberg's avatar Frank Steinberg
Browse files

First steps towards a web online translation editor.

parent b88e0b01
No related branches found
No related tags found
No related merge requests found
......@@ -2,7 +2,7 @@
DEFILES = $(shell ls de/*.xml)
FIXFILES = $(shell ls fix/*.xml)
default: bjcp-2015-styleguide-orig.xml bjcp-2015-styleguide-de.xml bjcp-2015-styleguide-orig.html bjcp-2015-styleguide-de.html
default: bjcp-2015-styleguide-orig.xml bjcp-2015-styleguide-de.xml bjcp-2015-styleguide-orig.html bjcp-2015-styleguide-de.html bjcp-2015-styleguide-de-edit.html
cache/2015_Guidelines_Beer.docx:
@if [ ! -d cache ] ; then mkdir cache ; fi
......@@ -32,6 +32,10 @@ bjcp-2015-styleguide-de.html: xsl/bjcp-2015-styleguide-html.xsl bjcp-2015-styleg
@xsltproc xsl/bjcp-2015-styleguide-html.xsl bjcp-2015-styleguide-de.xml > bjcp-2015-styleguide-de.html
@echo "built $@"
bjcp-2015-styleguide-de-edit.html: xsl/bjcp-2015-styleguide-html.xsl bjcp-2015-styleguide-de.xml
@xsltproc --stringparam edit yes xsl/bjcp-2015-styleguide-html.xsl bjcp-2015-styleguide-de.xml > bjcp-2015-styleguide-de-edit.html
@echo "built $@"
format:
@for f in de/*.xml ; do xmllint --format $$f | sed -e 's/ standalone="yes"//' > cache/tmp.xml ; cmp -s cache/tmp.xml $$f ; if [ $$? -ne 0 ] ; then cat cache/tmp.xml > $$f ; echo "reformatted $$f" ; fi ; rm cache/tmp.xml ; done
......@@ -50,6 +54,7 @@ clean:
@rm -f bjcp-2015-styleguide-de.xml
@rm -f bjcp-2015-styleguide-orig.html
@rm -f bjcp-2015-styleguide-de.html
@rm -f bjcp-2015-styleguide-de-edit.html
@echo "cleanup done"
distclean: clean
......
styleguide {
font-family: Helvetica, Arial, Geneva, sans-serif;
font-size: 8pt;
}
styleguide chapter table {
font-size: 8pt;
}
styleguide p.list-item {
list-style-type: decimal;
}
styleguide category, styleguide subcategory {
font-size: 9pt;
margin-top:1em;
margin-bottom:1em;
margin-left:0em;
display: list-item;
list-style-position: inside;
}
styleguide p {
margin-top:1em;
}
styleguide b {
font-weight: bold;
}
styleguide i {
font-style: italic;
}
styleguide u {
text-decoration: underline;
}
styleguide category:before, styleguide subcategory:before {
content: attr(id);
}
styleguide name {
display: inline-block;
margin-bottom:1em;
}
styleguide description {
font-size: 8pt;
margin-left:1em;
display: block;
}
styleguide description p {
margin-top: 0;
}
styleguide overall-impression:before {
content: "Overall Impression: ";
}
styleguide aroma:before {
content: "Aroma: ";
}
styleguide appearance:before {
content: "Appearance: ";
}
styleguide flavor:before {
content: "Flavor: ";
}
styleguide mouthfeel:before {
content: "Mouthfeel: ";
}
styleguide comments:before {
content: "Comments: ";
}
styleguide history:before {
content: "History: ";
}
styleguide characteristic-ingredients:before {
content: "Characteristic Ingredients: ";
}
styleguide style-comparison:before {
content: "Style Comparison: ";
}
styleguide entry-instructions:before {
content: "Entry Instructions: ";
}
styleguide specs:before {
content: "Vital Statistics: ";
}
styleguide commercial-examples:before {
content: "Commercial Examples: ";
}
styleguide tags:before {
content: "Tags: ";
}
styleguide strength-classifications:before {
content: "Strength Classifications: ";
}
styleguide overall-impression,
styleguide aroma,
styleguide appearance,
styleguide flavor,
styleguide mouthfeel,
styleguide comments,
styleguide history,
styleguide characteristic-ingredients,
styleguide style-comparison,
styleguide specs,
styleguide entry-instructions,
styleguide commercial-examples,
styleguide tags,
styleguide strength-classifications {
position: relative;
margin-left: 1em;
display: block;
font-size: 8pt;
}
styleguide overall-impression:before,
styleguide aroma:before,
styleguide appearance:before,
styleguide flavor:before,
styleguide mouthfeel:before,
styleguide comments:before,
styleguide history:before,
styleguide characteristic-ingredients:before,
styleguide style-comparison:before,
styleguide specs:before,
styleguide entry-instructions:before,
styleguide commercial-examples:before,
styleguide tags:before,
styleguide strength-classifications:before {
font-weight: bold;
}
styleguide specs div.ibu:before {
content: "IBU: ";
}
styleguide specs div.srm:before {
content: "SRM: ";
}
styleguide specs div.og:before {
content: "OG: ";
}
styleguide specs div.fg:before {
content: "FG: ";
}
styleguide specs div.abv:before {
content: "ABV: ";
}
styleguide specs div {
display: inline-block;
}
styleguide specs div * {
border: 1px solid;
display: inline-block;
width: 9em;
}
.pell-content{
border-bottom: 1px solid black;
}
div#editor button[title="save"],
div#editor button[title="cancel"] {
width: 70px;
}
div#editor {
display: none;
position: fixed;
width: 100%;
top: 0;
left: 0;
right: 0;
text-align: center;
font-family: Helvetica, Arial, Geneva, sans-serif;
font-size: 8pt;
}
div#editor-inner {
text-align: left;
margin: 50 auto;
padding: 5px;
width: 80%;
z-index: 2;
border: 2px solid black;
background: #ddd;
}
div#editor-inner input {
background: white;
}
div#markup {
font-family: courier;
font-size: 7pt;
}
div#render {
font-size: 7pt;
}
*[onclick] {
cursor: pointer;
}
const editor = document.getElementById("editor");
const pell = window.pell;
const pelleditor = document.getElementById("pelleditor");
const markup = document.getElementById("markup");
pell.init({
element: pelleditor,
actions: [
'bold',
'italic',
'underline',
{
name: 'link',
result: () => {
const idref = window.prompt('Enter the target category ID');
if (idref) {
var selection = document.getSelection();
if (selection == "") {
text = window.prompt('Enter link text (optional)');
pell.exec('insertHTML', '<a href="#' + idref + '">' + text + '</a>');
} else {
//pell.exec('insertHTML', '<a idref="#' + idref + '">' + text + '</a>');
pell.exec('createLink', "#" + idref);
}
}
}
},
{
name: 'save',
icon: '<div style="background-color:pink;">save</div>',
title: 'save',
result: () => {
editor.style.display = "none";
}
},
{
name: 'cancel',
icon: '<div style="background-color:pink;">cancel</div>',
title: 'cancel',
result: () => {
editor.style.display = "none";
}
},
],
onChange: (html) => {
x = html;
x = x.replace(/&nbsp;/g, " ");
x = x.replace(/<div>/g, " ");
x = x.replace(/<\/div>/g, " ");
x = x.replace(/<br>/g, " ");
x = x.replace(/ */g, " ");
markup.innerText = x;
render.innerHTML = x;
}
})
function doedit(elem) {
pelleditor.content.innerHTML = elem.innerHTML;
editor.style.display = "block";
markup.innerText = elem.innerHTML;
render.innerHTML = elem.innerHTML;
}
.pell {
border: 1px solid rgba(10, 10, 10, 0.1);
box-sizing: border-box; }
.pell-content {
background: white;
box-sizing: border-box;
/*height: 200px;*/
outline: 0;
/*overflow-y: auto;*/
padding: 10px; }
.pell-actionbar {
background-color: #ddd;
border-bottom: 1px solid rgba(10, 10, 10, 0.1); }
.pell-button {
background-color: transparent;
border: none;
cursor: pointer;
height: 30px;
outline: 0;
width: 30px;
vertical-align: bottom; }
.pell-button-selected {
background-color: #F0F0F0; }
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.pell = {})));
}(this, (function (exports) { 'use strict';
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var defaultParagraphSeparatorString = 'defaultParagraphSeparator';
var formatBlock = 'formatBlock';
var addEventListener = function addEventListener(parent, type, listener) {
return parent.addEventListener(type, listener);
};
var appendChild = function appendChild(parent, child) {
return parent.appendChild(child);
};
var createElement = function createElement(tag) {
return document.createElement(tag);
};
var queryCommandState = function queryCommandState(command) {
return document.queryCommandState(command);
};
var queryCommandValue = function queryCommandValue(command) {
return document.queryCommandValue(command);
};
var exec = function exec(command) {
var value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
return document.execCommand(command, false, value);
};
var defaultActions = {
bold: {
icon: '<b>B</b>',
title: 'Bold',
state: function state() {
return queryCommandState('bold');
},
result: function result() {
return exec('bold');
}
},
italic: {
icon: '<i>I</i>',
title: 'Italic',
state: function state() {
return queryCommandState('italic');
},
result: function result() {
return exec('italic');
}
},
underline: {
icon: '<u>U</u>',
title: 'Underline',
state: function state() {
return queryCommandState('underline');
},
result: function result() {
return exec('underline');
}
},
strikethrough: {
icon: '<strike>S</strike>',
title: 'Strike-through',
state: function state() {
return queryCommandState('strikeThrough');
},
result: function result() {
return exec('strikeThrough');
}
},
heading1: {
icon: '<b>H<sub>1</sub></b>',
title: 'Heading 1',
result: function result() {
return exec(formatBlock, '<h1>');
}
},
heading2: {
icon: '<b>H<sub>2</sub></b>',
title: 'Heading 2',
result: function result() {
return exec(formatBlock, '<h2>');
}
},
paragraph: {
icon: '&#182;',
title: 'Paragraph',
result: function result() {
return exec(formatBlock, '<p>');
}
},
quote: {
icon: '&#8220; &#8221;',
title: 'Quote',
result: function result() {
return exec(formatBlock, '<blockquote>');
}
},
olist: {
icon: '&#35;',
title: 'Ordered List',
result: function result() {
return exec('insertOrderedList');
}
},
ulist: {
icon: '&#8226;',
title: 'Unordered List',
result: function result() {
return exec('insertUnorderedList');
}
},
code: {
icon: '&lt;/&gt;',
title: 'Code',
result: function result() {
return exec(formatBlock, '<pre>');
}
},
line: {
icon: '&#8213;',
title: 'Horizontal Line',
result: function result() {
return exec('insertHorizontalRule');
}
},
link: {
icon: '&#128279;',
title: 'Link',
result: function result() {
var url = window.prompt('Enter the link URL');
if (url) exec('createLink', url);
}
},
image: {
icon: '&#128247;',
title: 'Image',
result: function result() {
var url = window.prompt('Enter the image URL');
if (url) exec('insertImage', url);
}
}
};
var defaultClasses = {
actionbar: 'pell-actionbar',
button: 'pell-button',
content: 'pell-content',
selected: 'pell-button-selected'
};
var init = function init(settings) {
var actions = settings.actions ? settings.actions.map(function (action) {
if (typeof action === 'string') return defaultActions[action];else if (defaultActions[action.name]) return _extends({}, defaultActions[action.name], action);
return action;
}) : Object.keys(defaultActions).map(function (action) {
return defaultActions[action];
});
var classes = _extends({}, defaultClasses, settings.classes);
var defaultParagraphSeparator = settings[defaultParagraphSeparatorString] || 'div';
var actionbar = createElement('div');
actionbar.className = classes.actionbar;
appendChild(settings.element, actionbar);
var content = settings.element.content = createElement('div');
content.contentEditable = true;
content.className = classes.content;
content.oninput = function (_ref) {
var firstChild = _ref.target.firstChild;
if (firstChild && firstChild.nodeType === 3) exec(formatBlock, '<' + defaultParagraphSeparator + '>');else if (content.innerHTML === '<br>') content.innerHTML = '';
settings.onChange(content.innerHTML);
};
content.onkeydown = function (event) {
if (event.key === 'Enter' && queryCommandValue(formatBlock) === 'blockquote') {
setTimeout(function () {
return exec(formatBlock, '<' + defaultParagraphSeparator + '>');
}, 0);
}
};
appendChild(settings.element, content);
actions.forEach(function (action) {
var button = createElement('button');
button.className = classes.button;
button.innerHTML = action.icon;
button.title = action.title;
button.setAttribute('type', 'button');
button.onclick = function () {
return action.result() && content.focus();
};
if (action.state) {
var handler = function handler() {
return button.classList[action.state() ? 'add' : 'remove'](classes.selected);
};
addEventListener(content, 'keyup', handler);
addEventListener(content, 'mouseup', handler);
addEventListener(button, 'click', handler);
}
appendChild(actionbar, button);
});
if (settings.styleWithCSS) exec('styleWithCSS');
exec(defaultParagraphSeparatorString, defaultParagraphSeparator);
return settings.element;
};
var pell = { exec: exec, init: init };
exports.exec = exec;
exports.init = init;
exports['default'] = pell;
Object.defineProperty(exports, '__esModule', { value: true });
})));
......@@ -7,6 +7,10 @@
<xsl:param name="edit">no</xsl:param>
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
......@@ -17,169 +21,45 @@
<xsl:element name="title">
<xsl:text>BJCP 2015 Styleguide</xsl:text>
</xsl:element>
<xsl:element name="style">
styleguide {
font-family: Helvetica, Arial, Geneva, sans-serif;
font-size: 8pt;
}
styleguide chapter table {
font-size: 8pt;
}
styleguide p.list-item {
list-style-type: decimal;
}
styleguide category, styleguide subcategory {
font-size: 9pt;
margin-top:1em;
margin-bottom:1em;
margin-left:0em;
display: list-item;
list-style-position: inside;
}
styleguide p {
margin-top:1em;
}
styleguide b {
font-weight: bold;
}
styleguide i {
font-style: italic;
}
styleguide u {
text-decoration: underline;
}
styleguide category:before, styleguide subcategory:before {
content: attr(id);
}
styleguide name {
display: inline-block;
margin-bottom:1em;
}
styleguide description {
font-size: 8pt;
margin-left:1em;
display: block;
}
styleguide description p {
margin-top: 0;
}
styleguide overall-impression:before {
content: "Overall Impression: ";
}
styleguide aroma:before {
content: "Aroma: ";
}
styleguide appearance:before {
content: "Appearance: ";
}
styleguide flavor:before {
content: "Flavor: ";
}
styleguide mouthfeel:before {
content: "Mouthfeel: ";
}
styleguide comments:before {
content: "Comments: ";
}
styleguide history:before {
content: "History: ";
}
styleguide characteristic-ingredients:before {
content: "Characteristic Ingredients: ";
}
styleguide style-comparison:before {
content: "Style Comparison: ";
}
styleguide entry-instructions:before {
content: "Entry Instructions: ";
}
styleguide specs:before {
content: "Vital Statistics: ";
}
styleguide commercial-examples:before {
content: "Commercial Examples: ";
}
styleguide tags:before {
content: "Tags: ";
}
styleguide strength-classifications:before {
content: "Strength Classifications: ";
}
styleguide overall-impression,
styleguide aroma,
styleguide appearance,
styleguide flavor,
styleguide mouthfeel,
styleguide comments,
styleguide history,
styleguide characteristic-ingredients,
styleguide style-comparison,
styleguide specs,
styleguide entry-instructions,
styleguide commercial-examples,
styleguide tags,
styleguide strength-classifications {
position: relative;
margin-left: 1em;
display: block;
font-size: 8pt;
}
styleguide overall-impression:before,
styleguide aroma:before,
styleguide appearance:before,
styleguide flavor:before,
styleguide mouthfeel:before,
styleguide comments:before,
styleguide history:before,
styleguide characteristic-ingredients:before,
styleguide style-comparison:before,
styleguide specs:before,
styleguide entry-instructions:before,
styleguide commercial-examples:before,
styleguide tags:before,
styleguide strength-classifications:before {
font-weight: bold;
}
styleguide specs div.ibu:before {
content: "IBU: ";
}
styleguide specs div.srm:before {
content: "SRM: ";
}
styleguide specs div.og:before {
content: "OG: ";
}
styleguide specs div.fg:before {
content: "FG: ";
}
styleguide specs div.abv:before {
content: "ABV: ";
}
styleguide specs div {
display: inline-block;
}
styleguide specs div * {
border: 1px solid;
display: inline-block;
width: 9em;
}
<xsl:element name="link">
<xsl:attribute name="rel">stylesheet</xsl:attribute>
<xsl:attribute name="type">text/css</xsl:attribute>
<xsl:attribute name="href">bjcp-styleguide.css</xsl:attribute>
</xsl:element>
<xsl:element name="link">
<xsl:attribute name="rel">stylesheet</xsl:attribute>
<xsl:attribute name="type">text/css</xsl:attribute>
<xsl:attribute name="href">pell.css</xsl:attribute>
</xsl:element>
<xsl:if test="not($edit = 'no')">
<xsl:element name="link">
<xsl:attribute name="rel">stylesheet</xsl:attribute>
<xsl:attribute name="type">text/css</xsl:attribute>
<xsl:attribute name="href">edit.css</xsl:attribute>
</xsl:element>
</xsl:if>
</xsl:element>
<xsl:element name="body">
<xsl:apply-templates select="." mode="copy"/>
<xsl:if test="not($edit = 'no')">
<div id="editor">
<div id="editor-inner">
Your Author ID: <input type="text" name="author" id="author" />
<div id="pelleditor"></div>
</div>
<div>Markup:<div id="markup"></div></div>
<div>Preview:<div id="render"></div></div>
</div>
<div/>
<xsl:element name="script">
<xsl:attribute name="src">pell.js</xsl:attribute>
<xsl:text> </xsl:text>
</xsl:element>
<xsl:element name="script">
<xsl:attribute name="src">edit.js</xsl:attribute>
<xsl:text> </xsl:text>
</xsl:element>
</xsl:if>
</xsl:element>
</xsl:element>
</xsl:template>
......@@ -257,6 +137,9 @@ styleguide specs div * {
<xsl:variable name="href">
<xsl:value-of select="@href"/>
</xsl:variable>
<xsl:variable name="idref">
<xsl:value-of select="translate(@href,'#','')"/>
</xsl:variable>
<xsl:element name="{local-name(.)}">
<xsl:attribute name="href">
<xsl:value-of select="$href"/>
......@@ -266,7 +149,7 @@ styleguide specs div * {
<xsl:value-of select="./text()"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="//bjcp:styleguide//*[@id=$href]/bjcp:name"/>
<xsl:value-of select="//bjcp:styleguide//bjcp:*[@id=$idref]/bjcp:name"/>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
......@@ -283,6 +166,20 @@ styleguide specs div * {
<xsl:template match="bjcp:name|bjcp:description|bjcp:overall-impression|bjcp:aroma|bjcp:appearance|bjcp:flavor|bjcp:mouthfeel|bjcp:comments|bjcp:history|bjcp:characteristic-ingredients|bjcp:style-comparison|bjcp:entry-instructions|bjcp:commercial-examples" mode="copy">
<xsl:element name="{local-name(.)}">
<xsl:apply-templates select="@*" mode="copy"/>
<xsl:if test="not($edit = 'no')">
<xsl:attribute name="onclick">
<xsl:text>doedit(this);</xsl:text>
</xsl:attribute>
</xsl:if>
<xsl:apply-templates mode="copy"/>
</xsl:element>
</xsl:template>
<xsl:template match="@id" mode="copy">
<xsl:attribute name="id">
<xsl:choose>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment