Skip to content

Commit bc53d7c

Browse files
authored
Merge branch 'develop' into feature/M2O3-151
2 parents 85bdbdd + a781852 commit bc53d7c

15 files changed

Lines changed: 21370 additions & 103 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,3 +334,4 @@ pyvenv.cfg
334334
/enf/
335335
jq/jq
336336
.output*
337+
rdf-differ-ws/

Makefile

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,18 @@ TARGET_SDS_FILES_JSON_LOCATION=.assets.sdsSection
5757
RESPEC_OUTPUT_DIR?=${OUTPUT_FOLDER_PATH}/respec
5858
RESPEC_SDS_OUTPUT_DIR=${RESPEC_OUTPUT_DIR}/sds
5959

60+
# Variables for merge-owl-shacl
61+
MERGE_ONTOLOGY_FILE?=test/diffing-files/ePO_core-4.1.0.ttl
62+
MERGE_SHAPES_FILE?=test/diffing-files/ePO_core_shapes-4.1.0.ttl
63+
MERGE_OUTPUT_FILE?=${OUTPUT_FOLDER_PATH}/ePO_core_combined-1.0.ttl
64+
65+
# Variables for RDF diff
66+
RDF_DIFF_FILE1?=test/diffing-files/ePO_core-4.1.0.ttl
67+
RDF_DIFF_FILE2?=test/diffing-files/ePO_core-4.2.0.ttl
68+
RDF_DIFF_OUTDIR?=${OUTPUT_FOLDER_PATH}
69+
RDF_DIFF_AP?=owl-core-en-only
70+
RDF_DIFF_TEMPLATE?=html
71+
6072
# download saxon library
6173
get-saxon: saxon/saxon.jar
6274

@@ -594,6 +606,87 @@ generate-html-docs-from-rdf: get-widoco
594606
@echo ${WIDOCO_RDF_INPUT_FILE_PATH}
595607
@java -jar widoco/widoco.jar -ontFile ${WIDOCO_RDF_INPUT_FILE_PATH} -outFolder ${WIDOCO_OUTPUT_FOLDER_PATH} -getOntologyMetadata -uniteSections -webVowl
596608

609+
# Merge OWL ontology and SHACL shapes files
610+
# Usage:
611+
# make merge-owl-shacl [MERGE_ONTOLOGY_FILE=test/diffing-files/ePO_core-4.1.0.ttl] [MERGE_SHAPES_FILE=test/diffing-files/ePO_core_shapes-4.1.0.ttl] [MERGE_OUTPUT_FILE=${OUTPUT_FOLDER_PATH}/ePO_core_combined-1.0.ttl]
612+
# where:
613+
# MERGE_ONTOLOGY_FILE: Path to the OWL ontology file (default: test/diffing-files/ePO_core-4.1.0.ttl)
614+
# MERGE_SHAPES_FILE: Path to the SHACL shapes file (default: test/diffing-files/ePO_core_shapes-4.1.0.ttl)
615+
# MERGE_OUTPUT_FILE: Path to the output file (default: ${OUTPUT_FOLDER_PATH}/ePO_core_combined-1.0.ttl)
616+
merge-owl-shacl: get-jena-cli-tools get-rdf-differ
617+
@if [ -z "${MERGE_ONTOLOGY_FILE}" ] || [ -z "${MERGE_SHAPES_FILE}" ]; then \
618+
echo "Error: MERGE_ONTOLOGY_FILE and MERGE_SHAPES_FILE are required"; \
619+
exit 1; \
620+
fi
621+
@if [ ! -f "rdf-differ-ws/bash/merge-owl-shacl.sh" ]; then \
622+
echo "Error: rdf-differ-ws/bash/merge-owl-shacl.sh not found"; \
623+
exit 1; \
624+
fi
625+
@if [ -z "${MERGE_OUTPUT_FILE}" ]; then \
626+
cd rdf-differ-ws && PATH="${ABSOLUTE_MODEL2OWL_FOLDER}/jena/apache-jena/bin:$$PATH" bash ./bash/merge-owl-shacl.sh "../${MERGE_ONTOLOGY_FILE}" "../${MERGE_SHAPES_FILE}"; \
627+
else \
628+
cd rdf-differ-ws && PATH="${ABSOLUTE_MODEL2OWL_FOLDER}/jena/apache-jena/bin:$$PATH" bash ./bash/merge-owl-shacl.sh "../${MERGE_ONTOLOGY_FILE}" "../${MERGE_SHAPES_FILE}" "../${MERGE_OUTPUT_FILE}"; \
629+
fi
630+
631+
# Get rdf-differ-ws repository
632+
get-rdf-differ:
633+
@if [ ! -d "rdf-differ-ws" ]; then \
634+
git clone --depth 1 --branch 2.1.0-beta https://github.com/meaningfy-ws/rdf-differ-ws.git; \
635+
rm -rf rdf-differ-ws/.git; \
636+
if ! grep -q "^rdf-differ-ws/" .gitignore 2>/dev/null; then \
637+
echo "rdf-differ-ws/" >> .gitignore; \
638+
echo "✅ Added rdf-differ-ws/ to .gitignore"; \
639+
fi; \
640+
fi
641+
642+
# Start RDF Differ services (Traefik and Docker services)
643+
start-rdf-differ-services: get-rdf-differ
644+
@echo "Starting Traefik for user-friendly network routing..."
645+
@cd rdf-differ-ws && make start-traefik
646+
@echo "🔎 Running Docker containers after start-traefik:"
647+
@docker ps
648+
@echo "Starting RDF Differ Docker services..."
649+
@cd rdf-differ-ws && make start-services
650+
@echo "🔎 Running containers after start-services:"
651+
@docker ps
652+
@echo "⏳ Waiting 5 seconds for rdf-differ-ws container group (via Traefik) to be ready..."
653+
@sleep 5
654+
655+
# Stop RDF Differ services and Traefik
656+
stop-rdf-differ-services:
657+
@if [ -d "rdf-differ-ws" ]; then \
658+
cd rdf-differ-ws && make stop-services && make stop-traefik; \
659+
echo "🔎 Running containers after stopping services and Traefik:"; \
660+
docker ps; \
661+
fi
662+
663+
# Run RDF diff workflow
664+
# Usage:
665+
# make run-rdf-diff [RDF_DIFF_FILE1=test/diffing-files/ePO_core-4.1.0.ttl] [RDF_DIFF_FILE2=test/diffing-files/ePO_core-4.2.0.ttl] \
666+
# [RDF_DIFF_OUTDIR=${OUTPUT_FOLDER_PATH}] [RDF_DIFF_AP=owl-core-en-only] [RDF_DIFF_TEMPLATE=html]
667+
# where:
668+
# RDF_DIFF_FILE1: Path to the first RDF file (default: test/diffing-files/ePO_core-4.1.0.ttl)
669+
# RDF_DIFF_FILE2: Path to the second RDF file (default: test/diffing-files/ePO_core-4.2.0.ttl)
670+
# RDF_DIFF_OUTDIR: Output directory for diff results (default: ${OUTPUT_FOLDER_PATH}, which is "output")
671+
# RDF_DIFF_AP: Application profile (default: owl-core-en-only)
672+
# RDF_DIFF_TEMPLATE: Output template format (default: html)
673+
run-rdf-diff: start-rdf-differ-services
674+
@echo "FILE1: ${RDF_DIFF_FILE1}"
675+
@echo "FILE2: ${RDF_DIFF_FILE2}"
676+
@echo "OUTDIR: ${RDF_DIFF_OUTDIR}"
677+
@echo "AP: ${RDF_DIFF_AP}"
678+
@echo "TEMPLATE: ${RDF_DIFF_TEMPLATE}"
679+
@cd rdf-differ-ws && bash ./bash/rdf-differ.sh --old ../${RDF_DIFF_FILE1} --new ../${RDF_DIFF_FILE2} --output ../${RDF_DIFF_OUTDIR} --profile ${RDF_DIFF_AP} --template ${RDF_DIFF_TEMPLATE}
680+
@echo "🔎 First few lines of the diff report:"
681+
@if [ -f "${RDF_DIFF_OUTDIR}/diff.${RDF_DIFF_TEMPLATE}" ]; then \
682+
head ${RDF_DIFF_OUTDIR}/diff.${RDF_DIFF_TEMPLATE}; \
683+
else \
684+
echo "No diff report found at ${RDF_DIFF_OUTDIR}/diff.${RDF_DIFF_TEMPLATE}"; \
685+
echo "Checking for diff files in ${RDF_DIFF_OUTDIR}:"; \
686+
ls -la ${RDF_DIFF_OUTDIR}/diff.* 2>/dev/null || echo "No diff files found"; \
687+
fi
688+
@$(MAKE) stop-rdf-differ-services
689+
597690
SHELL=/bin/bash -o pipefail
598691
BUILD_PRINT = \e[1;34mSTEP:
599692

src/html-model-glossary.xsl

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,16 @@
3030
fn:namespace-uri(//*:XMI) = 'http://www.omg.org/spec/XMI/20131001'">
3131
<body>
3232
<main class="container-fluid">
33-
<div id="toc" class="tocify">
34-
<div class="text-center">
35-
<p>
33+
<div class="content-wrapper">
34+
<nav class="toc" aria-label="Table of contents">
35+
<div class="text-center mb-3">
3636
<strong>Table of contents</strong>
37-
</p>
37+
</div>
38+
</nav>
39+
<div class="content">
40+
<xsl:call-template name="glossary"/>
3841
</div>
39-
</div>
40-
<div class="container">
41-
<xsl:call-template name="glossary"/>
42+
<div class="toc-spacer"></div>
4243
</div>
4344
</main>
4445
<xsl:call-template name="footer"/>

src/html-model-glossary/fragments/footer.xsl

Lines changed: 164 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -18,51 +18,178 @@
1818

1919

2020
<xsl:template name="footer">
21-
<footer class="text-center">
22-
<br/><br/>
23-
<p> This document is generated automatically by the <a
24-
href="https://github.com/costezki/model2owl" target="_blank">model2owl tool</a>
21+
<footer class="text-center mt-5 py-4 border-top">
22+
<p class="mb-2"> This document is generated automatically by the <a
23+
href="https://github.com/costezki/model2owl" target="_blank" class="text-decoration-none">model2owl tool</a>
2524
developed in the context of <a
2625
href="https://interoperable-europe.ec.europa.eu/collection/eprocurement/solution/eprocurement-ontology">the
2726
eProcurement Ontology initiative</a>.</p>
28-
<p>The template of this report is based on the <a
29-
href="https://github.com/thomaspark/pubcss">PubCSS library</a>.</p>
30-
<p>&#169; <xsl:value-of select="f:getMetadataValue('conventionReportCopyrightText')"/></p>
27+
<p class="mb-2">The template of this report is based on the <a
28+
href="https://github.com/thomaspark/pubcss" class="text-decoration-none">PubCSS library</a>.</p>
29+
<p class="mb-0 text-muted">&#169; <xsl:value-of select="f:getMetadataValue('conventionReportCopyrightText')"/></p>
3130
</footer>
32-
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
3331

34-
<script src="static/js/jquery-3.4.1.min.js"></script>
35-
<script src="static/js/jquery-ui.min.js"></script>
36-
<script src="static/js/bootstrap.min.js"></script>
37-
<script src="static/js/jquery.tocify.min.js"></script>
38-
<script type="text/javascript" src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.min.js"></script>
39-
<script type="text/javascript" src="https://cdn.datatables.net/buttons/1.6.4/js/dataTables.buttons.min.js"></script>
40-
<script type="text/javascript" src="https://cdn.datatables.net/buttons/1.6.4/js/buttons.print.min.js"></script>
32+
<!-- Go to top button -->
33+
<button id="goToTop" class="go-to-top" aria-label="Go to top" title="Go to top">
34+
<span>&#8593;</span>
35+
</button>
36+
37+
<!-- jQuery 3.7.1 -->
38+
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
39+
40+
<!-- Bootstrap 5 JS Bundle -->
41+
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
42+
43+
<!-- Tocbot -->
44+
<script src="https://cdn.jsdelivr.net/npm/tocbot@4.12.3/dist/tocbot.min.js"></script>
45+
46+
<!-- DataTables -->
47+
<script type="text/javascript" src="https://cdn.datatables.net/1.13.8/js/jquery.dataTables.min.js"></script>
48+
<script type="text/javascript" src="https://cdn.datatables.net/1.13.8/js/dataTables.bootstrap5.min.js"></script>
4149

4250
<script>
43-
$(function () {
44-
//Calls the tocify method on your HTML div.
45-
$("#toc").tocify({
46-
selectors: "h2",
47-
theme: "bootstrap",
48-
hashGenerator: "pretty",
49-
ignoreSelector: ".skip-toc"
50-
});
51-
});
52-
53-
</script>
54-
<script>
55-
$(document).ready(function () {
56-
57-
$("table.display").DataTable({
58-
buttons: [],
59-
"lengthMenu": [[-1], ["All"]],
60-
responsive: {
61-
details: true
62-
}
63-
});
64-
51+
<![CDATA[
52+
document.addEventListener('DOMContentLoaded', function() {
53+
// Initialize Tocbot
54+
if (document.querySelector('.toc')) {
55+
// Ensure headings have IDs for proper scrolling
56+
document.querySelectorAll('.content h1, .content h2').forEach(function(heading, index) {
57+
if (!heading.id) {
58+
var id = heading.textContent.toLowerCase()
59+
.replace(/[^\w\s-]/g, '')
60+
.replace(/\s+/g, '-')
61+
.replace(/-+/g, '-')
62+
.trim();
63+
if (!id) {
64+
id = 'heading-' + index;
65+
}
66+
heading.id = id;
67+
}
68+
});
69+
70+
tocbot.init({
71+
tocSelector: '.toc',
72+
contentSelector: '.content',
73+
headingSelector: 'h1, h2',
74+
smoothScroll: true,
75+
scrollSmooth: true,
76+
scrollSmoothDuration: 420,
77+
scrollSmoothOffset: 20,
78+
headingsOffset: 20,
79+
collapseDepth: 0,
80+
orderedList: false
81+
});
82+
}
83+
84+
// Initialize DataTables
85+
if (typeof jQuery !== 'undefined' && jQuery.fn.DataTable) {
86+
jQuery('table.display').each(function() {
87+
var table = jQuery(this).DataTable({
88+
lengthMenu: [[-1], ["All"]],
89+
pageLength: -1,
90+
responsive: true,
91+
order: [],
92+
language: {
93+
search: "Search:",
94+
lengthMenu: "Show _MENU_ entries",
95+
info: "Showing _START_ to _END_ of _TOTAL_ entries",
96+
infoEmpty: "No entries to show",
97+
infoFiltered: "(filtered from _MAX_ total entries)"
98+
},
99+
dom: '<"row"<"col-sm-12 col-md-6"l><"col-sm-12 col-md-6"f>>rt<"row"<"col-sm-12 col-md-5"i><"col-sm-12 col-md-7"p>>'
100+
});
101+
102+
// Ensure search input is type="search" for native clear button
103+
var searchInput = jQuery(this).closest('.dataTables_wrapper').find('.dataTables_filter input');
104+
var searchLabel = jQuery(this).closest('.dataTables_wrapper').find('.dataTables_filter label');
105+
106+
if (searchInput.length) {
107+
// Force type="search" for all browsers
108+
searchInput.attr('type', 'search');
109+
// For Firefox, ensure the input has the search type attribute
110+
if (searchInput[0]) {
111+
searchInput[0].type = 'search';
112+
}
113+
114+
// Add custom clear button for Firefox (and as fallback for other browsers)
115+
var clearButton = jQuery('<span class="custom-clear-button" style="display: none; cursor: pointer; margin-left: 4px; padding: 2px 6px; color: #666; font-size: 16px; line-height: 1; opacity: 0.6;">&times;</span>');
116+
searchInput.after(clearButton);
117+
118+
// Show/hide clear button based on input value
119+
function toggleClearButton() {
120+
if (searchInput.val() && searchInput.val().length > 0) {
121+
clearButton.show();
122+
} else {
123+
clearButton.hide();
124+
}
125+
}
126+
127+
// Initial state
128+
toggleClearButton();
129+
130+
// Update on input
131+
searchInput.on('input keyup', function() {
132+
toggleClearButton();
133+
});
134+
135+
// Clear button click handler
136+
clearButton.on('click', function(e) {
137+
e.preventDefault();
138+
e.stopPropagation();
139+
searchInput.val('');
140+
table.search('').draw();
141+
searchInput.focus();
142+
clearButton.hide();
143+
});
144+
145+
// Make the entire label clickable to focus the input
146+
searchLabel.on('click', function(e) {
147+
// Only focus if clicking on the label, not the input itself
148+
if (e.target === this || jQuery(e.target).is('label')) {
149+
searchInput.focus();
150+
}
151+
});
152+
153+
// Handle clear button click for better browser compatibility
154+
searchInput.on('search', function() {
155+
if (this.value === '') {
156+
table.search('').draw();
157+
toggleClearButton();
158+
}
159+
});
160+
161+
// Also handle input event for immediate clearing
162+
searchInput.on('input', function() {
163+
if (this.value === '') {
164+
table.search('').draw();
165+
}
166+
});
167+
}
168+
});
169+
}
170+
171+
// Go to top button functionality
172+
var goToTopButton = document.getElementById('goToTop');
173+
if (goToTopButton) {
174+
// Show/hide button based on scroll position
175+
window.addEventListener('scroll', function() {
176+
if (window.pageYOffset > 300) {
177+
goToTopButton.style.display = 'flex';
178+
} else {
179+
goToTopButton.style.display = 'none';
180+
}
181+
});
182+
183+
// Smooth scroll to top on click
184+
goToTopButton.addEventListener('click', function() {
185+
window.scrollTo({
186+
top: 0,
187+
behavior: 'smooth'
188+
});
189+
});
190+
}
65191
});
192+
]]>
66193
</script>
67194
</xsl:template>
68195

src/html-model-glossary/fragments/header.xsl

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,28 @@
2121
<meta name="author" content="Publications Office of the European Union"/>
2222
<meta name="viewport" content="width=device-width, initial-scale=1"/>
2323

24-
<link rel="stylesheet" href="static/css/jquery-ui.min.css"/>
25-
<link rel="stylesheet" href="static/css/bootstrap.min.css"/>
24+
<!-- Google Fonts - Roboto -->
25+
<link rel="preconnect" href="https://fonts.googleapis.com"/>
26+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="anonymous"/>
27+
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;600;700&amp;display=swap" rel="stylesheet"/>
28+
29+
<!-- Bootstrap 5 CSS -->
30+
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous"/>
31+
32+
<!-- PubCSS -->
2633
<link rel="stylesheet" href="static/css/pubcss-acm-sig.css"/>
27-
<!-- <link rel="stylesheet" media="screen" href="static/css/screen.css"/>
28-
<link rel="stylesheet" media="print" href="static/css/print.css"/>-->
34+
35+
<!-- Tocbot CSS -->
36+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tocbot@4.12.3/dist/tocbot.css"/>
37+
38+
<!-- DataTables CSS -->
39+
<link href="https://cdn.datatables.net/1.13.8/css/dataTables.bootstrap5.min.css" rel="stylesheet"/>
40+
41+
<!-- Custom styles -->
2942
<link rel="stylesheet" href="static/css/toc_adjustments.css"/>
30-
<link href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.min.css" rel="stylesheet"/>
43+
<link rel="stylesheet" href="static/css/glossary.css"/>
3144

3245
<link rel="shortcut icon" href=""/>
33-
<style>
34-
#toc {
35-
font-size: 1.2em;
36-
width: 10%;
37-
}
38-
@media print{@page {size: landscape}}
39-
40-
</style>
4146
<title>Model glossary</title>
4247
</head>
4348
</xsl:template>

0 commit comments

Comments
 (0)