32 Commits

Author SHA1 Message Date
matic_t
d513ec8eaa add support for lexeme_id on comp 2020-08-20 08:29:50 -07:00
Luka Kavčič
5fe2bb62bb Merge pull request 'mt-additional-xml-shema-support' (#6) from mt-additional-xml-shema-support into master
Reviewed-on: #6
2020-08-14 09:32:33 +00:00
matic_t
85bf0473e5 logs + comment for upcoming work 2020-08-12 06:22:39 -07:00
matic_t
8049f5ed95 translationContainerList implementation 2020-08-12 06:18:00 -07:00
matic_t
48c51c38de handling new entries 2020-08-12 06:17:29 -07:00
matic_t
094cc7afcf Merge branch 'master' of https://gitea.cjvt.si/lexonomy/lexonomy_custom_editor into mt-additional-xml-shema-support 2020-08-11 23:14:33 -07:00
matic_t
410054cdd6 grammar example with saved entry_xml 2020-08-11 07:41:47 -07:00
matic_t
ec811028ab explanationList 2020-08-10 08:38:08 -07:00
matic_t
752ec44d43 fixing double_list_getter 2020-08-07 01:34:47 -07:00
matic_t
83396ef8a0 ups 2020-08-06 05:40:26 -07:00
matic_t
efe4d07464 required audio support #1351 2020-08-06 05:39:24 -07:00
matic_t
1770932a14 language on explanation support + explanation as new model + homonymy refactored as a double list 2020-08-06 03:47:52 -07:00
matic_t
2b2a2c4bd9 Merge pull request 'mt-additional-xml-shema-support' (#5) from mt-additional-xml-shema-support into master
Reviewed-on: #5
2020-08-05 10:04:53 +00:00
matic_t
a07b35c6a8 Merge branch 'master' of https://gitea.cjvt.si/lexonomy/lexonomy_custom_editor into mt-additional-xml-shema-support 2020-08-04 07:07:58 -07:00
matic_t
ad83665b0d explanationList 2020-08-04 07:00:53 -07:00
Luka Kavčič
0c62cbe4d8 Merge pull request 'lk-collocation-structure-fix' (#4) from lk-collocation-structure-fix into master
Reviewed-on: #4
2020-08-04 10:17:28 +00:00
a7f85accce fix unwanted line change 2020-08-04 10:05:36 +02:00
3926d1a199 Feature#1405 and Bug#1399 2020-08-04 09:48:17 +02:00
matic_t
964dc3f788 Explanation list support 2020-07-23 05:40:39 -07:00
matic_t
8b7c282fdf sloleks supported in components 2020-07-23 01:38:51 -07:00
matic_t
6f157eeea1 update build_and_upload.sh.template with unlink 2020-07-16 04:21:38 -07:00
matic_t
ed8bb37b15 Merge branch 'master' of https://gitea.cjvt.si/lexonomy/lexonomy_custom_editor into mt-homonymy-support 2020-07-16 03:50:04 -07:00
matic_t
9c007f6dd6 upsy daisys 2020-07-16 03:46:48 -07:00
matic_t
b010414bfe support homonymy inside modal 2020-07-16 03:22:54 -07:00
matic_t
fb9a809c02 modal supports editing name and value 2020-07-16 01:43:26 -07:00
matic_t
6f9142b046 Added support for name attribute 2020-07-16 01:31:16 -07:00
matic_t
a22490c0fc homonymy basic implementation 2020-07-15 04:17:58 -07:00
matic_t
b764d59602 Merge pull request 'Readme + skripta za upload na VPS' (#1) from mt-initial-setup into master
Reviewed-on: #1
2020-07-10 11:15:13 +00:00
b17510ffe7 improving build, correct phony targets and more correct and verbose download_structure_conversions 2020-07-08 21:52:44 +02:00
5396868601 mid component should be colocation, not headword,
Also, readd structureName and handle unknown structure when importing ske collocation
2020-07-08 21:52:44 +02:00
8cb63eaa1d mid component should be colocation, not headword 2020-07-08 21:21:24 +02:00
6e1f3bd16a saving example_id correctly (see import of corpus example) 2020-07-08 21:21:10 +02:00
25 changed files with 531 additions and 331 deletions

2
.gitignore vendored
View File

@@ -10,5 +10,5 @@ build/*
# using kdev4, works fairly nicely! # using kdev4, works fairly nicely!
.kdev4 .kdev4
**/*.kdev4 **/*.kdev4
remote

View File

@@ -1,5 +1,3 @@
.PHONY: all release build transcrypt copy $(RES_LESS_FILE) $(RES_PY_FILE) $(RES_HTML_FILE) $(RES_XML_FILE)
SRC_FOLDER=$(CURDIR)/../src SRC_FOLDER=$(CURDIR)/../src
RES_FOLDER=$(CURDIR)/../res RES_FOLDER=$(CURDIR)/../res
@@ -20,6 +18,7 @@ RES_PY_FILE=$(SRC_FOLDER)/$(PY_FILE)
RES_HTML_FILE=$(RES_FOLDER)/$(HTML_FILE) RES_HTML_FILE=$(RES_FOLDER)/$(HTML_FILE)
RES_XML_FILE=$(RES_FOLDER)/$(XML_FILE) RES_XML_FILE=$(RES_FOLDER)/$(XML_FILE)
.PHONY: all release build transcrypt copy $(RES_LESS_FILE) $(RES_PY_FILE) $(RES_HTML_FILE) $(RES_XML_FILE) $(CONV_FILE)
.DEFAULT_GOAL := all .DEFAULT_GOAL := all
all: BR_FLAGS := $(BR_FLAGS) --debug all: BR_FLAGS := $(BR_FLAGS) --debug

View File

@@ -4,10 +4,10 @@
############################################################################# #############################################################################
# Alter these variables # Alter these variables
#USERNAME= vps_sign_in(probably name@lexonomy.cjvt.si #USERNAME=vps_sign_in(probably name@lexonomy.cjvt.si
#VPS_PASSWORD= vps password #VPS_PASSWORD=vps password
#VPS_USERNAME= user name inside vps(probably name from @lexonomy) #VPS_USERNAME=user name inside vps(probably name from @lexonomy)
#API_KEY= $(cat path/to/api/token/file) #API_KEY=$(cat path/to/api/token/file)
# Exit if no argument is passed on run # Exit if no argument is passed on run
if [[ -z "$1" ]]; then if [[ -z "$1" ]]; then
@@ -24,4 +24,4 @@ tar czf - ./config.json ./bundle.js ./local.js ./main.css ./main.html | ssh $USE
# Create a simlink on VPS that will enable specific plugin on https://lexonomy.cjvt.si/ # Create a simlink on VPS that will enable specific plugin on https://lexonomy.cjvt.si/
# Routes must be absolute or it doesn't work. # Routes must be absolute or it doesn't work.
ssh -t $USERNAME -p $VPS_PASSWORD "sudo ln -s /home/$VPS_USERNAME/plugins/$PLUGIN_NAME /home/ozbolt/plugins/$PLUGIN_NAME" ssh -t $USERNAME -p $VPS_PASSWORD "sudo -s unlink /home/ozbolt/plugins/$PLUGIN_NAME || true && sudo ln -s /home/$VPS_USERNAME/plugins/$PLUGIN_NAME /home/ozbolt/plugins/$PLUGIN_NAME"

View File

@@ -3,15 +3,19 @@
# fail if any command fails # fail if any command fails
set -e set -e
OUT_FILE=conversions.csv
if [[ -z "${API_KEY}" ]]; then if [[ -z "${API_KEY}" ]]; then
echo "API_KEY not defined, should be api key to CJVT's gitea" echo "API_KEY not defined, should be api key to CJVT's gitea"
exit 1 exit 1
fi fi
OUT_FILE=conversions.csv if [ -f $OUT_FILE ]; then
TEMP_FILE=$(mktemp) echo "file for conversion of SKE collocations: '$OUT_FILE' already exists, skipping."
exit 0
fi
rm -r $OUT_FILE TEMP_FILE=$(mktemp)
curl -s "https://gitea.cjvt.si/api/v1/repos/generic/data_admin/contents/resources/structure_conversions.csv?token=$API_KEY" -o $TEMP_FILE curl -s "https://gitea.cjvt.si/api/v1/repos/generic/data_admin/contents/resources/structure_conversions.csv?token=$API_KEY" -o $TEMP_FILE
echo "wc: $(wc $TEMP_FILE)" echo "wc: $(wc $TEMP_FILE)"

View File

@@ -156,16 +156,7 @@
vertical-align: super; vertical-align: super;
font-size: 0.7em; font-size: 0.7em;
} }
.translation-explanation:not(:empty) {
font-style: italic;
&:before {
content: '[';
}
&:after {
content: ']';
}
}
} }
.translation-add { .translation-add {
@@ -175,6 +166,20 @@
} }
} }
.explanations:not(:empty) {
font-style: italic;
&:not(.solo) {
&:before {
content: '[';
}
&:after {
content: ']';
}
}
}
.example { .example {
clear: left; clear: left;
margin-left: 1em; margin-left: 1em;

View File

@@ -4,7 +4,12 @@
<head> <head>
<status>LBS</status> <status>LBS</status>
<headword> <headword>
<lemma>aplikativen</lemma> <lemma>aplikativen3</lemma>
<homonymy>
<homonymyFeature name="pronunciation">bolníšnica</homonymyFeature>
<homonymyFeature name="blahblah">xyz</homonymyFeature>
<homonymyFeature name="bluhbluh">abc</homonymyFeature>
</homonymy>
</headword> </headword>
<grammar> <grammar>
<category>pridevnik</category> <category>pridevnik</category>

View File

@@ -5,13 +5,12 @@ from model.tags import export_tag
def export_to_xml(model): def export_to_xml(model):
xml_document = export_entry(model.entry) xml_document = export_entry(model.entry)
serializer = __new__(XMLSerializer()) serializer = __new__(XMLSerializer())
return serializer.serializeToString(xml_document); return serializer.serializeToString(xml_document)
def export_entry(entry): def export_entry(entry):
parser = __new__(DOMParser()) parser = __new__(DOMParser())
doc = parser.parseFromString("<entry />", "text/xml") doc = parser.parseFromString("<entry />", "text/xml")
entry_xml = doc.firstChild entry_xml = doc.firstChild
# create head # create head
@@ -24,12 +23,28 @@ def export_entry(entry):
headword = doc.createElement("headword") headword = doc.createElement("headword")
headword_lemma = doc.createElement("lemma") headword_lemma = doc.createElement("lemma")
# headword_lemma = entry.original_xml.querySelector("head headword lemma")
headword_lemma.textContent = entry.headword headword_lemma.textContent = entry.headword
if entry.headword_type is not None: if entry.headword_type is not None:
headword_lemma.setAttribute("type", entry.headword_type) headword_lemma.setAttribute("type", entry.headword_type)
if entry.headword_audio is not None:
headword_lemma.setAttribute("audio", entry.headword_audio)
headword.appendChild(headword_lemma) headword.appendChild(headword_lemma)
head.appendChild(headword) head.appendChild(headword)
homonymy = doc.createElement("homonymy")
headword.appendChild(homonymy)
for hFeature in entry.homonymy:
feature = doc.createElement("homonymyFeature")
feature.textContent = hFeature.value
# Can't use hFeature.name, because Python has name reserver and so it becomes py_name in JS
feature.setAttribute("name", hFeature["name"])
homonymy.appendChild(feature)
# if({}) works uncorrectly in transcrypt # if({}) works uncorrectly in transcrypt
if len(entry.lexical_unit) > 0: if len(entry.lexical_unit) > 0:
lexunit = doc.createElement("lexicalUnit") lexunit = doc.createElement("lexicalUnit")
@@ -42,11 +57,18 @@ def export_entry(entry):
lexunit.appendChild(lexeme) lexunit.appendChild(lexeme)
head.appendChild(lexunit) head.appendChild(lexunit)
# Example of keeping original xml and adding changes to it only
grammar_category = entry.original_xml.querySelector("head grammar category")
if grammar_category is None:
grammar = doc.createElement("grammar") grammar = doc.createElement("grammar")
grammar_category = doc.createElement("category") grammar_category = doc.createElement("category")
grammar_category.textContent = entry.grammar
grammar.appendChild(grammar_category) grammar.appendChild(grammar_category)
head.appendChild(grammar) entry.original_xml.querySelector("head").appendChild(grammar_category)
grammar_category.textContent = entry.grammar
head.appendChild(entry.original_xml.querySelector("head grammar"))
if len(entry.measure) > 0: if len(entry.measure) > 0:
measure_list = doc.createElement("measureList") measure_list = doc.createElement("measureList")
@@ -115,7 +137,9 @@ def export_sense(doc, sense):
for example in sense.examples: for example in sense.examples:
example_container = example.export(doc) example_container = example.export(doc)
export_translation_list(doc, example, example_container) translation_container_list = doc.createElement("translationContainerList")
export_translation_list(doc, example, translation_container_list)
example_container.appendChild(translation_container_list)
example_container_list.appendChild(example_container) example_container_list.appendChild(example_container)
return sense_xml return sense_xml
@@ -136,16 +160,27 @@ def export_translation(doc, translation):
actual_t.textContent = translation.translation actual_t.textContent = translation.translation
actual_t.setAttribute("targetLang", translation.targetLang) actual_t.setAttribute("targetLang", translation.targetLang)
if translation.audio:
actual_t.setAttribute("audio", translation.audio)
if translation.source: if translation.source:
actual_t.setAttribute("source", translation.source) actual_t.setAttribute("source", translation.source)
translation_xml.appendChild(actual_t) translation_xml.appendChild(actual_t)
explanation = doc.createElement("explanation") if len(translation.explanationList) > 0 :
explanation.textContent = translation.explanation explanationList = _export_explanation_list(doc, translation.explanationList)
translation_xml.appendChild(explanation) translation_xml.appendChild(explanationList)
return translation_xml return translation_xml
def _export_explanation_list(doc, lst):
result = doc.createElement('explanationList')
for explanation in lst:
result.appendChild(explanation.export(doc))
return result
def _export_label_list(doc, lst): def _export_label_list(doc, lst):
result = doc.createElement("labelList") result = doc.createElement("labelList")

View File

@@ -34,12 +34,23 @@ def build_structure_conversions():
structure_conversions.append((__new__(RegExp(vfrom, 'u')), vto_name, vto_id)) structure_conversions.append((__new__(RegExp(vfrom, 'u')), vto_name, vto_id))
def convert_structure(structure): def convert_structure(structure, type):
if structure_conversions is None: if structure_conversions is None:
build_structure_conversions() build_structure_conversions()
for vfrom, vto_name, vto_id in structure_conversions: for vfrom, vto_name, vto_id in structure_conversions:
match = structure.match(vfrom) match = structure.match(vfrom)
# fix for ids 65, 66, 67 which instead matched with 64
if match and vto_id == '64' and '-s' in type:
vto_name = 's0-vp-s0'
vto_id = '65'
elif match and vto_id == '64' and '-g' in type:
vto_name = 'gg-vp-gg'
vto_id = '66'
elif match and vto_id == '64' and '-r' in type:
vto_name = 'r-vp-r'
vto_id = '67'
if match: if match:
# we need to remove replace alias here as we want to use javascript's one # we need to remove replace alias here as we want to use javascript's one
__pragma__('noalias', 'replace') __pragma__('noalias', 'replace')
@@ -49,4 +60,4 @@ def convert_structure(structure):
return result, vto_id return result, vto_id
window.console.log("Unknown structure: ", structure) window.console.log("Unknown structure: ", structure)
return None return 'N/A', '/'

View File

@@ -1,11 +1,11 @@
from message.simple_messages import NoReset, Reset, ModalNotOkClose, ClickMessage, DataChgClickMessage, KeyboardPress, NoAction from message.simple_messages import NoReset, Reset, ModalNotOkClose, ClickMessage, DataChgClickMessage, KeyboardPress, NoAction
from message.translation_edit import EditTranslation, MoveRight, MoveLeft, BinTranslation from message.translation_edit import EditTranslation, MoveRight, MoveLeft, BinTranslation
from message.show_messages import ShowEntryLabelsEdit, ShowEditTranslation, ShowSenseLabelEdit, ShowSenseDefinitionEdit, ShowCommentEdit, ShowAddTranslation, ShowExampleEdit, ShowVariantsEdit, ShowRelatedEntriesEdit from message.show_messages import ShowEntryLabelsEdit, ShowEditTranslation, ShowSenseLabelEdit, ShowSenseDefinitionEdit, ShowCommentEdit, ShowAddTranslation, ShowExampleEdit, ShowVariantsEdit, ShowHomonymyEdit, ShowRelatedEntriesEdit
from message.simple_edits import EditSenseLabel, EditSenseDefinition, EditComment, AddSenseLabel, AddSense, AddExampleTranslation, DoChosenExamples, AddToLabelList, AddToGenericList, EditVariants, EditRelatedEntries, EditEntryLabels, ExampleClusterEdit, ExampleClusterAdd from message.simple_edits import EditSenseLabel, EditSenseDefinition, EditComment, AddSenseLabel, AddSense, AddExampleTranslation, DoChosenExamples, AddToLabelList, AddToGenericList, EditVariants, EditHomonymy, EditRelatedEntries, EditEntryLabels, ExampleClusterEdit, ExampleClusterAdd
from message.show_menu import ShowTranslationMenu, ShowSenseMenu, ShowExampleMenu from message.show_menu import ShowTranslationMenu, ShowSenseMenu, ShowExampleMenu
from message.sense_edit import SenseMoveUp, SenseMoveDown, SenseBin, AddMultiwordExample from message.sense_edit import SenseMoveUp, SenseMoveDown, SenseBin, AddMultiwordExample
from message.example_edit import ExampleMoveUp, ExampleMoveDown, ExampleBin, ExampleRoleChange, ExampleComponentSpace, ExampleComponentAdd, ExampleComponentRemove, EditExampleText, ToggleExamples, ToggleClusters from message.example_edit import ExampleMoveUp, ExampleMoveDown, ExampleBin, ExampleRoleChange, ExampleComponentSpace, ExampleComponentAdd, ExampleComponentRemove, EditExampleText, ToggleExamples, ToggleClusters
from message.delete_messages import DeleteComment, DeleteVariants, DeleteRelatedEntries, DeleteEntryLabels from message.delete_messages import DeleteComment, DeleteVariants, DeleteHomonymy, DeleteRelatedEntries, DeleteEntryLabels
from message.ske_messages import ShowSkeModal, SearchInSkeModal, SkeInsert from message.ske_messages import ShowSkeModal, SearchInSkeModal, SkeInsert
from message.message import msg, delayed_msg from message.message import msg, delayed_msg

View File

@@ -9,6 +9,24 @@ def generic_list_getter():
result.append(result_candidate) result.append(result_candidate)
return result return result
# Formats data from inputs to name-value objects
def double_list_getter(firstParameter, secondParameter, allowEmptyField = False):
result = []
for row in document.getElementsByClassName("double-list-row"):
firstValue = row.querySelector("." + firstParameter + "-input").value
secondValue = row.querySelector("." + secondParameter + "-input").value
if (allowEmptyField is False and '' in [firstValue, secondValue]):
continue
if (allowEmptyField is True and all('' == value or value.isspace() for value in [firstValue, secondValue])):
continue
result.append({firstParameter: firstValue, secondParameter: secondValue})
return result
def label_list_getter(): def label_list_getter():
result = [] result = []
for row in document.getElementsByClassName("label-list-row"): for row in document.getElementsByClassName("label-list-row"):

View File

@@ -18,6 +18,14 @@ class DeleteRelatedEntries(DeleteVariants):
pass pass
class DeleteHomonymy(NoReset):
def update_model(self, model):
for el in document.getElementsByClassName("list-adder-input"):
el.value = ""
class DeleteEntryLabels(NoReset): class DeleteEntryLabels(NoReset):
def update_model(self, model): def update_model(self, model):
for sel in document.getElementsByClassName("label-value"): for sel in document.getElementsByClassName("label-value"):

View File

@@ -30,6 +30,12 @@ class ShowVariantsEdit(ClickMessage):
model.modal_set(lambda: modals.edit_variants(model.entry)) model.modal_set(lambda: modals.edit_variants(model.entry))
class ShowHomonymyEdit(ClickMessage):
def update_model(self, model):
model.entry.make_copy()
model.modal_set(lambda: modals.edit_homonymy(model.entry))
class ShowRelatedEntriesEdit(ClickMessage): class ShowRelatedEntriesEdit(ClickMessage):
def update_model(self, model): def update_model(self, model):
model.entry.make_copy() model.entry.make_copy()

View File

@@ -88,6 +88,11 @@ class EditVariants(Message):
variants = common_accessors.generic_list_getter() variants = common_accessors.generic_list_getter()
model.entry.variants = variants model.entry.variants = variants
class EditHomonymy(Message):
def update_model(self, model):
homonymy = common_accessors.double_list_getter("value", "name")
model.entry.homonymy = homonymy
class EditRelatedEntries(Message): class EditRelatedEntries(Message):
def update_model(self, model): def update_model(self, model):

View File

@@ -26,6 +26,7 @@ class SkeExample:
self.mid = "" self.mid = ""
self.s_id = "" self.s_id = ""
self.gf2_good = None self.gf2_good = None
self.gf2_check = False
@staticmethod @staticmethod
def fromLine(line): def fromLine(line):
@@ -58,7 +59,7 @@ class SkeCollocation:
def __init__(self, data): def __init__(self, data):
self.word = data.word self.word = data.word
self.frequency = data.count self.frequency = data.count
self.structure_name, self.structure_id = convert_structure(data.gramrel) self.structure_name, self.structure_id = convert_structure(data.gramrel, data.lempos)
self.other = {"score": data.score, "cm": data.cm} self.other = {"score": data.score, "cm": data.cm}
@@ -140,7 +141,7 @@ class SkeModal(ClickMessage):
elif type(data) is list: elif type(data) is list:
window.console.log(data) window.console.log(data)
# check if gf2 examples are loaded or not # check if gf2 examples are loaded or not
if data[0].gf2_good is None: if not data[0].gf2_check and type(data[0]) is SkeExample:
# we get the data, we have to match it with available data on our gf2 examples API # we get the data, we have to match it with available data on our gf2 examples API
match_gf2_examples(data, page_num, search_term, ske_index) match_gf2_examples(data, page_num, search_term, ske_index)
@@ -161,12 +162,18 @@ class SkeModalGf2Update(SkeModal):
example.gf_good = False example.gf_good = False
data_dict[example.s_id] = example data_dict[example.s_id] = example
bad_response = dict(response_data["bad"])
for gf_sid, gf_data in bad_response.items():
data_dict[gf_sid].gf2_good = None
data_dict[gf_sid].gf2_check = True
good_response = dict(response_data["good"]) good_response = dict(response_data["good"])
for gf_sid, gf_data in good_response.items(): for gf_sid, gf_data in good_response.items():
data_dict[gf_sid].left = gf_data.left data_dict[gf_sid].left = gf_data.left
data_dict[gf_sid].mid = gf_data.mid data_dict[gf_sid].mid = gf_data.mid
data_dict[gf_sid].right = gf_data.right data_dict[gf_sid].right = gf_data.right
data_dict[gf_sid].gf2_good = True data_dict[gf_sid].gf2_good = True
data_dict[gf_sid].gf2_check = True
# changed data_dict, now we can redraw! # changed data_dict, now we can redraw!
# just let it do its thing in update_model # just let it do its thing in update_model
@@ -217,10 +224,12 @@ class SkeInsert(DataChgClickMessage):
console.log("You really should not be here, my lady") console.log("You really should not be here, my lady")
continue continue
model.reset()
def _as_corpus_example(self, example): def _as_corpus_example(self, example):
new_example = Example() new_example = Example()
new_example.inner = CorpusExample() new_example.inner = CorpusExample()
new_example.inner.other_attributes["exampleId"] = example.s_id new_example.inner.other_attributes["example_id"] = example.s_id
new_example.inner.cluster = ExampleClusters.first_empty_cluster() new_example.inner.cluster = ExampleClusters.first_empty_cluster()
lex_left = ComponentLexeme() lex_left = ComponentLexeme()
@@ -229,7 +238,7 @@ class SkeInsert(DataChgClickMessage):
lex_mid = ComponentLexeme() lex_mid = ComponentLexeme()
lex_mid.text = example["mid"] lex_mid.text = example["mid"]
lex_mid.role = "headword" lex_mid.role = "collocation"
lex_right = ComponentLexeme() lex_right = ComponentLexeme()
lex_right.text = example["right"] lex_right.text = example["right"]
@@ -243,6 +252,7 @@ class SkeInsert(DataChgClickMessage):
new_collocation.inner = MultiwordExample() new_collocation.inner = MultiwordExample()
new_collocation.inner.other_attributes["structure_id"] = example.structure_id new_collocation.inner.other_attributes["structure_id"] = example.structure_id
new_collocation.inner.other_attributes["structureName"] = example.structure_name
new_collocation.inner.other_attributes["logDice"] = example.other["score"] new_collocation.inner.other_attributes["logDice"] = example.other["score"]
new_collocation.inner.other_attributes["frequency"] = example.frequency new_collocation.inner.other_attributes["frequency"] = example.frequency
new_collocation.inner.type = "collocation" new_collocation.inner.type = "collocation"
@@ -253,7 +263,7 @@ class SkeInsert(DataChgClickMessage):
lex_mid = ComponentLexeme() lex_mid = ComponentLexeme()
lex_mid.text = example.word lex_mid.text = example.word
lex_mid.role = "headword" lex_mid.role = "collocation"
lex_right = ComponentLexeme() lex_right = ComponentLexeme()
lex_right.text = "" lex_right.text = ""

View File

@@ -4,6 +4,7 @@ import message.common_accessors as common_accessors
from browser import document, window from browser import document, window
from model.translation import Translation from model.translation import Translation
from model.sense import Sense from model.sense import Sense
from model.explanation import Explanation
@@ -13,8 +14,14 @@ class EditTranslation(DataChgClickMessage):
self.old_cluster_idx = self.get_arg(1, int) self.old_cluster_idx = self.get_arg(1, int)
self.translation.translation = document.getElementById("etv").value self.translation.translation = document.getElementById("etv").value
self.translation.explanation = document.getElementById("ete").value # This could be dangerous if double_list_getter is getting data from any other list as well.
explanations = common_accessors.double_list_getter('value', 'language', True)
self.translation.explanationList = []
for entry in explanations:
explanation = Explanation()
explanation.value = entry.value
explanation.language = entry.language
self.translation.explanationList.append(explanation)
# common_accessors.label_list_getter() # common_accessors.label_list_getter()
self.translation.tags = common_accessors.label_list_getter() self.translation.tags = common_accessors.label_list_getter()

View File

@@ -2,3 +2,4 @@ from model.model import Model
from model.sense import Sense from model.sense import Sense
from model.translation import Translation from model.translation import Translation
from model.example import Example from model.example import Example
from model.explanation import Explanation

View File

@@ -12,7 +12,9 @@ class Entry(Data):
def __init__(self): def __init__(self):
self.status = "" self.status = ""
self.headword = "" self.headword = ""
self.homonymy = []
self.headword_type = None self.headword_type = None
self.headword_audio = None
self.grammar = "" self.grammar = ""
self.comment = "" self.comment = ""
self.variants = [] self.variants = []
@@ -21,19 +23,24 @@ class Entry(Data):
self.measure = {} self.measure = {}
self.labels = [] self.labels = []
self.senses = [] self.senses = []
self.original_xml = None
def import_xml(self, entry_xml): def import_xml(self, entry_xml):
self.original_xml = entry_xml.cloneNode(True)
status = entry_xml.querySelector("head status") status = entry_xml.querySelector("head status")
headword = entry_xml.querySelector("head headword lemma") headword = entry_xml.querySelector("head headword lemma")
grammar = entry_xml.querySelector("head grammar category") grammar = entry_xml.querySelector("head grammar category")
comment = entry_xml.querySelector("head comment") comment = entry_xml.querySelector("head comment")
self.status = status.textContent if status else "" self.status = status.textContent if status else ""
self.headword = headword.textContent if headword else "" self.headword = headword.textContent if headword else ""
self.headword_type = headword.getAttribute("type") if headword else None self.headword_type = headword.getAttribute("type") if headword and headword.hasAttribute("type") else None
self.headword_audio = headword.getAttribute("audio") if headword and headword.hasAttribute("audio") else None
self.grammar = grammar.textContent if grammar else "" self.grammar = grammar.textContent if grammar else ""
self.comment = comment.textContent if comment else "" self.comment = comment.textContent if comment else ""
self.variants = [v.textContent for v in entry_xml.querySelectorAll("head variantList variant")] self.variants = [v.textContent for v in entry_xml.querySelectorAll("head variantList variant")]
self.homonymy = [{"value": v.textContent, "name": v.getAttribute("name")} for v in entry_xml.querySelectorAll("head headword homonymy homonymyFeature ")]
self.related_entries = [re.textContent for re in entry_xml.querySelectorAll("head relatedEntryList relatedEntry")] self.related_entries = [re.textContent for re in entry_xml.querySelectorAll("head relatedEntryList relatedEntry")]
lex_unit = entry_xml.querySelector("lexical_unit lexeme,lexicalUnit lexeme") lex_unit = entry_xml.querySelector("lexical_unit lexeme,lexicalUnit lexeme")
@@ -80,7 +87,8 @@ class Entry(Data):
h("button.normal", clk(M.ShowVariantsEdit), "Variante"), h("button.normal", clk(M.ShowVariantsEdit), "Variante"),
h("button.success", clk(M.ShowRelatedEntriesEdit), "Povezano"), h("button.success", clk(M.ShowRelatedEntriesEdit), "Povezano"),
h("button.success", clk(M.ShowEntryLabelsEdit), "Oznake"), h("button.success", clk(M.ShowEntryLabelsEdit), "Oznake"),
h("button.normal", clk(M.ShowCommentEdit), "Opombe")] h("button.normal", clk(M.ShowCommentEdit), "Opombe"),
h("button.normal", clk(M.ShowHomonymyEdit), "Homonomije"),]
view_buttons = [] view_buttons = []
view_table = [] view_table = []
@@ -90,6 +98,11 @@ class Entry(Data):
else: else:
view_table.append((buttons[0], ", ".join(self.variants))) view_table.append((buttons[0], ", ".join(self.variants)))
if len(self.homonymy) == 0:
view_buttons.append(buttons[4])
else:
view_table.append((buttons[4], ", ".join((h["name"] + ": " + h.value) for h in self.homonymy)))
if len(self.related_entries) == 0: if len(self.related_entries) == 0:
view_buttons.append(buttons[1]) view_buttons.append(buttons[1])
else: else:

View File

@@ -19,11 +19,10 @@ class ComponentLexeme(Data):
else: else:
self.text = xml.textContent self.text = xml.textContent
self.role = xml.getAttribute("role") self.role = xml.getAttribute("role")
if xml.hasAttribute("space"): if xml.hasAttribute("space"):
self.no_space = xml.getAttribute("space") == "false" self.no_space = xml.getAttribute("space") == "false"
for oth_attr in ["lexical_unit_lexeme_id", "slolex", "kol"]: for oth_attr in ["lexeme_id", "lexical_unit_lexeme_id", "slolex", "kol", "sloleks"]:
if xml.hasAttribute(oth_attr): if xml.hasAttribute(oth_attr):
self.other_attributes[oth_attr] = xml.getAttribute(oth_attr) self.other_attributes[oth_attr] = xml.getAttribute(oth_attr)
@@ -33,7 +32,6 @@ class ComponentLexeme(Data):
def export(self, doc): def export(self, doc):
if self.role is None: if self.role is None:
return doc.createTextNode(self.text) return doc.createTextNode(self.text)
result = doc.createElement("comp") result = doc.createElement("comp")
result.setAttribute("role", self.role) result.setAttribute("role", self.role)
result.textContent = self.text result.textContent = self.text

View File

@@ -40,7 +40,7 @@ class Example(Data):
return example return example
def import_xml(self, example_xml): def import_xml(self, example_xml):
self.translations = from_container_list(example_xml.querySelectorAll("translationContainer")) self.translations = from_container_list(example_xml.querySelectorAll("translationContainerList translationContainer"))
if example_xml.hasAttribute("modified"): if example_xml.hasAttribute("modified"):
self.edited = example_xml.getAttribute("modified") == "true" self.edited = example_xml.getAttribute("modified") == "true"

21
src/model/explanation.py Normal file
View File

@@ -0,0 +1,21 @@
from model.data import Data
from lib.snabbdom import h
class Explanation(Data):
def __init__(self):
self.value = ""
self.language = ""
def import_dom(self, explanation_dom):
self.value = explanation_dom.textContent if explanation_dom else ""
self.language = explanation_dom.getAttribute("language") if explanation_dom.hasAttribute("language") else ""
def export(self, doc):
result = doc.createElement("explanation")
result.textContent = self.value
if self.language != "": result.setAttribute('language', self.language)
return result

View File

@@ -18,14 +18,14 @@ class Sense(Data):
def import_xml(self, sense_xml, idx): def import_xml(self, sense_xml, idx):
self.original_idx = idx self.original_idx = idx
for definition in sense_xml.querySelectorAll("definitionList definition"): for definition in sense_xml.querySelectorAll("definitionList definition"):
key = definition.getAttribute("type") key = definition.getAttribute("type")
self.definition[key] = definition.textContent self.definition[key] = definition.textContent
self.labels = import_label_list("sense > labelList label", sense_xml) self.labels = import_label_list("sense > labelList label", sense_xml)
self.translations = from_container_list( self.translations = from_container_list(
sense_xml.querySelectorAll("translationContainerList translationContainer")) sense_xml.querySelectorAll('sense > translationContainerList translationContainer'))
for example_xml in sense_xml.querySelectorAll("exampleContainerList exampleContainer"): for example_xml in sense_xml.querySelectorAll("exampleContainerList exampleContainer"):
example = Example() example = Example()
example.import_xml(example_xml) example.import_xml(example_xml)

View File

@@ -1,4 +1,5 @@
from model.tags import import_label_list from model.tags import import_label_list
from model.explanation import Explanation
from model.data import Data from model.data import Data
from lib.snabbdom import h from lib.snabbdom import h
@@ -32,7 +33,8 @@ class Translation(Data):
self.translation = "" self.translation = ""
self.source = "" self.source = ""
self.targetLang = "" self.targetLang = ""
self.explanation = "" self.audio = ""
self.explanationList = set()
self.tags = [] self.tags = []
def import_xml(self, translation_xml): def import_xml(self, translation_xml):
@@ -42,12 +44,16 @@ class Translation(Data):
self.translation = translation.textContent self.translation = translation.textContent
self.source = translation.getAttribute("source") if translation.hasAttribute("source") else "" self.source = translation.getAttribute("source") if translation.hasAttribute("source") else ""
self.targetLang = translation.getAttribute("targetLang") if translation.hasAttribute("targetLang") else "" self.targetLang = translation.getAttribute("targetLang") if translation.hasAttribute("targetLang") else ""
self.audio = translation.getAttribute("audio") if translation.hasAttribute("audio") else ""
explanationList = translation_xml.querySelectorAll("explanationList explanation")
for explanation_dom in explanationList:
explanation = Explanation()
explanation.import_dom(explanation_dom)
self.explanationList.append(explanation)
explanation = translation_xml.querySelector("explanation")
self.explanation = explanation.textContent if explanation else ""
self.tags = import_label_list("labelList label", translation_xml) self.tags = import_label_list("labelList label", translation_xml)
def view(self, model): def view(self, model):
elements = [] elements = []
@@ -61,8 +67,10 @@ class Translation(Data):
if self.source: if self.source:
elements.append(h("span.translation-source", {}, self.source)) elements.append(h("span.translation-source", {}, self.source))
explanation_class = ".translation-explanation" if self.translation else "" if (self.explanationList):
elements.append(h("span{}".format(explanation_class), {}, self.explanation)) explanation_class = ".explanations" if self.translation else ".explanations.solo"
explanations = [explanation.value for explanation in self.explanationList]
elements.append(h("span{}".format(explanation_class), {}, ", ".join(explanations)))
return h("div.translation-div", {"on": {"click": M.msg(M.ShowTranslationMenu, self) }}, elements) return h("div.translation-div", {"on": {"click": M.msg(M.ShowTranslationMenu, self) }}, elements)
@@ -73,6 +81,6 @@ class Translation(Data):
# next two are not checked as the also can not be deleted via gui # next two are not checked as the also can not be deleted via gui
# result = result and self.source == "" # result = result and self.source == ""
# result = result and self.targetLang == "" # result = result and self.targetLang == ""
result = result and self.explanation == "" result = result and len(self.explanationList) == 0
result = result and len(self.tags) == 0 result = result and len(self.tags) == 0
return result return result

View File

@@ -47,6 +47,47 @@ def generic_list_editor(title, element_list_getter):
content.append(h("button", {"on": {"click": message.msg(message.AddToGenericList, element_list_getter)}}, "+")) content.append(h("button", {"on": {"click": message.msg(message.AddToGenericList, element_list_getter)}}, "+"))
return content return content
def homonymy_editor(title, current_labels):
def split_line2(left, right):
cls = "flex.two{}".format(".double-list-row")
return h("div.{}".format(cls), {}, [
h("div.half", {}, left), h("div.half", {}, right)])
content = [h("p", {}, title)]
for i, feature in enumerate(current_labels()):
name = []
value = []
name.append(h("label", {"attrs": {"for": i}}, "Name:"))
name.append(h("input.name-input", {"props": {"type": "text", "value": feature["name"], "id": i}}, ""))
value.append(h("label", {"attrs": {"for": i + "-value"}}, "Value:"))
value.append(h("input.value-input", {"props": {"type": "text", "value": feature["value"], "id": i + "-value"}}, ""))
content.append(split_line2(name, value))
content.append(h("button", {"on": {"click": message.msg(message.AddToGenericList, current_labels)}}, "+"))
return content
def explanation_editor(title, current_labels):
def split_line2(left, right):
cls = "flex.two{}".format(".double-list-row")
return h("div.{}".format(cls), {}, [
h("div.four-fifth", {}, left), h("div.fifth", {}, right)])
content = [h("p", {}, title)]
for i, explanation in enumerate(current_labels()):
language = []
value = []
language.append(h("label", {"attrs": {"for": i}}, "Language:"))
language.append(h("input.language-input", {"props": {"type": "text", "value": explanation["language"], "id": i}}, ""))
value.append(h("label", {"attrs": {"for": i + "-value"}}, "Value:"))
value.append(h("input.value-input", {"props": {"type": "text", "value": explanation["value"], "id": i + "-value"}}, ""))
content.append(split_line2(value, language))
content.append(h("button", {"on": {"click": message.msg(message.AddToGenericList, current_labels)}}, "+"))
return content
def label_list_editor(current_labels, add_label_message_class): def label_list_editor(current_labels, add_label_message_class):
def split_line3(left, center, right, is_llr=True): def split_line3(left, center, right, is_llr=True):

View File

@@ -19,10 +19,9 @@ def edit_translation(translation, parent, cluster_idx, num_clusters, cls):
# first line: transalation itself # first line: transalation itself
content.extend([ content.extend([
split_line2("Prevedek:", split_line2("Prevedek:", h("textarea#etv", {"props": {"value": translation.translation}}, ""))])
h("textarea#etv", {"props": {"value": translation.translation}}, "")),
split_line2("Razlaga:", content.extend(explanation_editor("Razlage:", lambda: translation.explanationList))
h("textarea#ete", {"props": {"value": translation.explanation}}, ""))])
# cluster number # cluster number
options = [h("option", {"props": {"selected": idx == cluster_idx}}, str(idx + 1)) for idx in range(num_clusters + 1)] options = [h("option", {"props": {"selected": idx == cluster_idx}}, str(idx + 1)) for idx in range(num_clusters + 1)]
@@ -99,6 +98,12 @@ def edit_variants(entry):
return modal_template(content, "Add or remove variants", (message.EditVariants,), (message.DeleteVariants,)) return modal_template(content, "Add or remove variants", (message.EditVariants,), (message.DeleteVariants,))
def edit_homonymy(entry):
hget = lambda: entry.copy().homonymy
content = homonymy_editor("Homonymy", hget)
return modal_template(content, "Add or remove homonymy features", (message.EditHomonymy,), (message.DeleteHomonymy,))
def edit_related_entries(entry): def edit_related_entries(entry):
reget = lambda: entry.copy().related_entries reget = lambda: entry.copy().related_entries
content = generic_list_editor("Related entries", reget) content = generic_list_editor("Related entries", reget)