Browse Source

Simplify ALTO display code and harden the whole thing a bit against negative dimensions found in some pages in T2

better-rectangles
Tissevert 8 months ago
parent
commit
213ac16ba4
5 changed files with 71 additions and 108 deletions
  1. +1
    -0
      css/page.css
  2. +6
    -1
      js/Geometry/Segment.js
  3. +0
    -12
      js/XML.js
  4. +32
    -56
      js/XML/ALTO.js
  5. +32
    -39
      js/XML/ALTO/Element.js

+ 1
- 0
css/page.css View File

@ -3,6 +3,7 @@
position: absolute;
left: 50%;
transform: translateX(-50%);
overflow: hidden;
}
#page.ratio, #page.fitHeight {


+ 6
- 1
js/Geometry/Segment.js View File

@ -1,7 +1,8 @@
return {
contains: contains,
intersects: intersects,
make: make
make: make,
oNorm: oNorm
}
function contains(segmentA, segmentB) {
@ -20,3 +21,7 @@ function make(o) {
return {min: Math.min(o.from, o.to), max: Math.max(o.from, o.to)};
}
}
function oNorm(o, norm) {
return {o: 1*o + Math.min(0, 1*norm), norm: Math.abs(1*norm)};
}

+ 0
- 12
js/XML.js View File

@ -1,20 +1,8 @@
return {
appendTo: appendTo,
onNodes: onNodes,
parse: parse,
serialize: serialize
}
function appendTo(element) {
return function(e) {element.appendChild(e);};
}
function onNodes(nodeList, f) {
var result = [];
nodeList.forEach(function(node) {result.push(f(node));});
return result;
}
function parse(input) {
var domReader = new DOMParser();
return domReader.parseFromString(input, 'text/xml');


+ 32
- 56
js/XML/ALTO.js View File

@ -3,7 +3,6 @@ import {isScoria, toggleWord} from Scoria;
import Quality;
import GUI;
import * as Dom from UnitJS.Dom;
import {appendTo, onNodes} from XML;
import * as Zoom from Toolbar.Zoom;
return {
@ -12,63 +11,39 @@ return {
};
function display(ALTODoc) {
var page = Element.make(ALTODoc.querySelector('Page'));
Zoom.scaleTo(page.geometry());
var page = ALTODoc.querySelector('Page');
Zoom.scaleTo(Element.make(page).geometry);
Dom.clear(GUI.page);
onNodes(page.get('PrintSpace'), makePrintSpace())
.forEach(appendTo(GUI.page));
function makePrintSpace() {
return function(printSpace) {
var dom = Dom.make(
'div', {class: "PrintSpace", id: printSpace.getAttribute('ID')}
);
var element = Element.make(printSpace, dom);
onNodes(element.get('TextBlock'), makeTextBlock(element))
.forEach(appendTo(dom));
return dom;
};
}
GUI.page.appendChild(makeDomNode(page.querySelector('PrintSpace')));
}
function makeTextBlock(parentElement) {
return function(textBlock) {
var dom = Dom.make(
'div', {class: "TextBlock", id: textBlock.getAttribute('ID')}
);
var element = Element.make(textBlock, dom, parentElement);
onNodes(element.get('TextLine'), makeTextLine(element))
.forEach(appendTo(dom));
return dom;
};
function makeDomNode(xmlElement, parentElement) {
var element = Element.make(xmlElement);
var attributes = {class: [element.tag], id: element.get('ID')};
if(element.tag == 'String') {
setAttributes(element, attributes);
} else {
var children = makeChildren(xmlElement, element);
}
var dom = Dom.make(element.htmlTag, attributes, children);
element.position(dom, parentElement);
return dom;
}
function makeTextLine(parentElement) {
return function(textLine) {
var dom = Dom.make(
'p', {class: "TextLine", id: textLine.getAttribute('ID')}
);
var element = Element.make(textLine, dom, parentElement);
onNodes(element.get('String'), makeString(element))
.forEach(appendTo(dom));
return dom;
};
}
function makeChildren(xmlElement, element) {
var children = [];
xmlElement.querySelectorAll(element.childTag).forEach(function(child) {
children.push(makeDomNode(child, element));
});
return children;
}
function makeString(parentElement) {
return function(string) {
var wc = string.getAttribute('WC');
var id = string.getAttribute('ID');
var dom = Dom.make('span', {
class: ['String']
.concat(Quality.isLow(wc) ? 'lowQuality' : [])
.concat(isScoria(id) ? 'deleted' : []),
onClick: function(e) {toggleWord(e.target)},
id: id,
textContent: string.getAttribute('CONTENT')
});
return Element.make(string, dom, parentElement).dom();
};
}
function setAttributes(element, attributes) {
attributes.textContent = element.get('CONTENT');
attributes.class = attributes.class
.concat(Quality.isLow(element.get('WC')) ? 'lowQuality' : [])
.concat(isScoria(element.get('ID')) ? 'deleted' : []);
attributes.onClick = function(e) {toggleWord(e.target)};
}
function edit(ALTODoc) {
@ -78,10 +53,11 @@ function edit(ALTODoc) {
}
function editElement(xmlElement) {
if(xmlElement.tagName == 'String') {
return !isScoria(xmlElement.getAttribute('ID'));
var element = Element.make(xmlElement);
if(element.tag == 'String') {
return !isScoria(element.get('ID'));
} else {
editChildren(xmlElement, Element.schema[xmlElement.tagName]);
editChildren(xmlElement, element.childTag);
return xmlElement.children.length > 0;
}
}


+ 32
- 39
js/XML/ALTO/Element.js View File

@ -1,55 +1,48 @@
import scale from Toolbar.Zoom;
import oNorm from Geometry.Segment;
var schema = {
'PrintSpace': 'TextBlock',
'TextBlock': 'TextLine',
'TextLine': 'String'
'Page': {childTag: 'PrintSpace'},
'PrintSpace': {childTag: 'TextBlock', htmlTag: 'div'},
'TextBlock': {childTag: 'TextLine', htmlTag: 'div'},
'TextLine': {childTag: 'String', htmlTag: 'p'},
'String': {htmlTag: 'span'}
};
return {
make: make,
schema: schema,
make: make
};
function make(xmlElement, domElement, parentElement) {
var hPos = xmlElement.getAttribute('HPOS');
var vPos = xmlElement.getAttribute('VPOS');
var width = xmlElement.getAttribute('WIDTH');
var height = xmlElement.getAttribute('HEIGHT');
position();
function make(xmlElement) {
var x = oNorm(get('HPOS'), get('WIDTH'));
var y = oNorm(get('VPOS'), get('HEIGHT'));
return {
dom: dom,
geometry: geometry,
get: get
childTag: schema[xmlElement.tagName].childTag,
geometry: {
hPos: x.o,
vPos: y.o,
width: x.norm,
height: y.norm
},
get: get,
htmlTag: schema[xmlElement.tagName].htmlTag,
id: get('ID'),
position: position,
tag: xmlElement.tagName
};
function dom() {
return domElement;
function get(attribute) {
return xmlElement.getAttribute(attribute);
}
function geometry() {
return {
hPos: hPos,
vPos: vPos,
width: width,
height: height
};
}
function get(tag) {
return xmlElement.querySelectorAll(tag);
}
function position() {
if(domElement != undefined) {
var mother = parentElement ? parentElement.geometry() : {hPos: 0, vPos: 0};
scale(domElement, {
left: hPos - mother.hPos, /* due to absolute positioning in CSS, this needs to be */
top: vPos - mother.vPos, /* computed as an offset from the parentElement */
width: width,
height: height
}, 'left', 'top', 'width', 'height')
}
function position(domElement, parentElement) {
var mother = parentElement ? parentElement.geometry : {hPos: 0, vPos: 0};
scale(domElement, {
left: x.o - mother.hPos, /* due to absolute positioning in CSS, this needs to be */
top: y.o - mother.vPos, /* computed as an offset from the parentElement */
width: x.norm,
height: y.norm
}, 'left', 'top', 'width', 'height')
}
}

Loading…
Cancel
Save