Skip to content

Commit 43a4af3

Browse files
author
Thomas Hanke
committed
changed highlight view to use start end as url variables
1 parent 35ff6e1 commit 43a4af3

5 files changed

Lines changed: 88 additions & 129 deletions

File tree

ckanext/markdown_view/assets/markdown_view.js

Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ function cleanMathExpression(expression) {
99
// Replace \right} with \right)
1010
expression = expression.replace(/\\right\\}/g, '\\right)');
1111
return expression;
12-
}
12+
}
1313
marked.use("marked-extended-tables", "gfm");
1414
const renderer = new marked.Renderer();
1515
renderer.image = function (href, title, text) {
@@ -19,52 +19,50 @@ renderer.paragraph = function (text) {
1919
return `<p class="text-break"/>${text}</p>`;
2020
};
2121
marked.use({ renderer });
22-
// Override function
23-
// const tokenizer = {
24-
// codespan(src) {
25-
// const match = src.match(/^\$+([^\$\n]+?)\$+/);
26-
// if (match) {
27-
// return {
28-
// type: 'codespan',
29-
// raw: match[0],
30-
// text: match[1].trim()
31-
// };
32-
// }
33-
34-
// // return false to use original codespan tokenizer
35-
// return false;
36-
// }
37-
// };
38-
// marked.use({ tokenizer });
39-
// fetch("{{ resource_view.get('page_url') or resource.get('url') }}") // The path to the raw Markdown file
40-
// .then(response => response.blob()) // Unwrap to a blob...
41-
// .then(blob => blob.text()) // ...then to raw text...
42-
// .then(markdown => { // ...then pass the raw text into marked.parse
43-
// document.getElementById("markdown_content").innerHTML = DOMPurify.sanitize(marked.parse(markdown.replace(/^[\u200B\u200C\u200D\u200E\u200F\uFEFF]/, "")));
44-
// });
45-
const pageUrl = document.getElementById('markdown_content').getAttribute('data-page-url');
46-
fetch(pageUrl) // Path to raw Markdown file
47-
.then(response => response.blob()) // Unwrap to a blob...
48-
.then(blob => blob.text()) // Convert to text
49-
.then(markdown => {
50-
// Sanitize and clean up the markdown text before parsing
51-
// markdown = markdown.replace(/[^\x20-\x7E\x0A\x0D]/g, ''); // Remove non-printable characters
5222

23+
24+
const pageUrl = document.getElementById('markdown_content').getAttribute('data-page-url');
25+
fetch(pageUrl) // Path to raw Markdown file
26+
.then(response => response.blob()) // Unwrap to a blob...
27+
.then(blob => blob.text()) // Convert to text
28+
.then(markdown => {
5329
// Clean the markdown for math expressions
54-
markdown = markdown.replace(/\$\$[\s\S]*?\$\$/g, match => cleanMathExpression(match)); // Clean block math
55-
markdown = markdown.replace(/\$[\s\S]*?\$/g, match => cleanMathExpression(match)); // Clean inline math
56-
30+
// markdown = markdown.replace(/\$\$[\s\S]*?\$\$/g, match => cleanMathExpression(match)); // Clean block math
31+
// markdown = markdown.replace(/\$[\s\S]*?\$/g, match => cleanMathExpression(match)); // Clean inline math
5732
// Parsing the Markdown text into HTML
58-
let parsedHTML = marked.parse(markdown.replace(/^[\u200B\u200C\u200D\u200E\u200F\uFEFF]/, ""));
33+
// let parsedHTML = marked.parse(markdown.replace(/^[\u200B\u200C\u200D\u200E\u200F\uFEFF]/, ""));
34+
let parsedHTML;
35+
// Überprüfen, ob start und end gesetzt und unterschiedlich sind
36+
if (typeof start === 'number' && typeof end === 'number' && start < end) {
37+
// Teile den Markdown-Text in drei Teile
38+
const beforeSlice = markdown.slice(0, start);
39+
const highlightedSlice = markdown.slice(start, end);
40+
const afterSlice = markdown.slice(end);
41+
42+
// Render die Teile
43+
let parsedBefore = marked.parse(beforeSlice.replace(/^[\u200B\u200C\u200D\u200E\u200F\uFEFF]/, ""));
44+
let parsedHighlighted = `<div class="highlight">${marked.parse(highlightedSlice)}</div>`;
45+
let parsedAfter = marked.parse(afterSlice.replace(/^[\u200B\u200C\u200D\u200E\u200F\uFEFF]/, ""));
5946

60-
// Sanitize the generated HTML content
61-
parsedHTML = DOMPurify.sanitize(parsedHTML);
47+
// Sanitize the generated HTML content
48+
parsedBefore = DOMPurify.sanitize(parsedBefore);
49+
parsedHighlighted = DOMPurify.sanitize(parsedHighlighted);
50+
parsedAfter = DOMPurify.sanitize(parsedAfter);
51+
52+
// Kombiniere die Teile
53+
parsedHTML = parsedBefore + parsedHighlighted + parsedAfter;
54+
} else {
55+
// Wenn start und end nicht gültig sind, rendere den gesamten Markdown
56+
parsedHTML = marked.parse(markdown.replace(/^[\u200B\u200C\u200D\u200E\u200F\uFEFF]/, ""));
57+
parsedHTML = DOMPurify.sanitize(parsedHTML);
58+
}
6259

6360
// Inject sanitized HTML into the page
6461
const contentDiv = document.getElementById("markdown_content");
6562
contentDiv.innerHTML = parsedHTML;
66-
})
67-
.catch(error => console.error("Failed to load Markdown content:", error));
63+
64+
})
65+
.catch(error => console.error("Failed to load Markdown content:", error));
6866
document.addEventListener("DOMContentLoaded", function () {
6967
//replace font location
7068
const styleSheets = document.styleSheets;
Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,42 @@
11
marked_tables:
2-
output: markdown_view/marked_tables.js
2+
output: markdown_view/%(version)s_marked_tables.js
33
contents:
44
- index.umd.min.js
55

66
purify:
7-
output: markdown_view/purify.js
7+
output: markdown_view/%(version)s_markdown_view/purify.js
88
contents:
99
- purify.min.js
1010

1111
katex:
12-
output: markdown_view/katex.js
12+
output: markdown_view/%(version)s_markdown_view/katex.js
1313
contents:
1414
- katex.min.js
1515

1616
katex_autorender:
17-
output: markdown_view/katex_autorender.js
17+
output: markdown_view/%(version)s_markdown_view/katex_autorender.js
1818
contents:
1919
- auto-render.min.js
2020

2121
katex_css:
22-
output: markdown_view/katex.css
22+
output: markdown_view/%(version)s_markdown_view/katex.css
2323
contents:
2424
- katex.min.css
2525

2626
markdown_view_css:
27-
output: markdown_view/markdown_view.css
27+
output: markdown_view/%(version)s_markdown_view/markdown_view.css
2828
contents:
2929
- markdown_view.css
3030

3131
marked:
32-
output: markdown_view/marked.js
32+
output: markdown_view/%(version)s_markdown_view/marked.js
3333
contents:
3434
- marked.min.js
3535

3636
markdown_view:
37-
output: markdown_view/markdown_view.js
37+
output: markdown_view/%(version)s_markdown_view/markdown_view.js
3838
contents:
3939
- markdown_view.js
4040
filters: rjsmin
41-
extra:
42-
preload:
43-
- markdown_view/purify
44-
- markdown_view/marked
45-
- markdown_view/marked_tables
46-
- markdown_view/markdown_view_css
47-
- markdown_view/katex
48-
- markdown_view/katex_css
49-
- markdown_view/katex_autorender
41+
42+
Lines changed: 26 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,30 @@
1-
<link rel="stylesheet" href="/markdown_view.css" />
2-
<form method="post" id="highlight-form" class="hidden">
3-
{{ h.csrf_input() }}
4-
<label for="highlight">highlight:</label>
5-
<input type="text" name="highlight" id="highlight" placeholder='Enter markdown text to highlight...'
6-
maxlength='3000' minlength='10'>
7-
<input type="submit">
8-
</form>
9-
<div id="markdown_content" class="row">
10-
<span id="markdown_content1"></span><span id="markdown_content2" class="inline highlight"></span><span
11-
id="markdown_content3"></span>
12-
</div>
1+
{% extends "page.html" %}
2+
3+
{%- block page %}
4+
<script>
5+
const start = {{ start_index }};
6+
const end = {{ end_index }};
7+
</script>
138

14-
<div id="markdown_content" class="row">
15-
<span id="markdown_content1" class="inline"></span><span id="markdown_content2"
16-
class="inline highlight"></span><span id="markdown_content3" class="inline"></span>
9+
{% if start_index is none and end_index is none %}
10+
<form method="post" id="highlight-form" class="hidden">
11+
{{ h.csrf_input() }}
12+
<label for="highlight">highlight:</label>
13+
<input type="text" name="highlight" id="highlight" placeholder='Enter markdown text to highlight...'
14+
maxlength='3000' minlength='10'>
15+
<input type="submit">
16+
</form>
17+
{% endif %}
18+
<div id="markdown_content" data-page-url="{{resource.get('url') }}">
1719
</div>
1820

19-
<script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.1.5/purify.min.js"
20-
integrity="sha512-JatFEe90fJU2nrgf27fUz2hWRvdYrSlTEV8esFuqCtfiqWN8phkS1fUl/xCfYyrLDQcNf3YyS0V9hG7U4RHNmQ=="
21-
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
22-
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/12.0.2/marked.min.js"
23-
integrity="sha512-xeUh+KxNyTufZOje++oQHstlMQ8/rpyzPuM+gjMFYK3z5ILJGE7l2NvYL+XfliKURMpBIKKp1XoPN/qswlSMFA=="
24-
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
25-
<script src="
26-
https://cdn.jsdelivr.net/npm/marked-extended-tables@1.0.8/lib/index.umd.min.js
27-
"></script>
28-
<script>
29-
marked.use("marked-extended-tables", "gfm");
30-
const renderer = new marked.Renderer();
31-
renderer.image = function (href, title, text) {
32-
return `<img class="img-fluid" src="${href}" alt="${text}" title="${title}" />`; // for local references
33-
};
34-
renderer.paragraph = function (text) {
35-
return `<p class="text-break"/>${text}</p>`;
36-
};
37-
marked.use({ renderer });
38-
// Override function
39-
const tokenizer = {
40-
codespan(src) {
41-
const match = src.match(/^\$+([^\$\n]+?)\$+/);
42-
if (match) {
43-
return {
44-
type: 'codespan',
45-
raw: match[0],
46-
text: match[1].trim()
47-
};
48-
}
21+
{% asset 'markdown_view/purify' %}
22+
{% asset 'markdown_view/marked' %}
23+
{% asset 'markdown_view/marked_tables' %}
24+
{% asset 'markdown_view/markdown_view_css' %}
25+
{% asset 'markdown_view/katex' %}
26+
{% asset 'markdown_view/katex_css' %}
27+
{% asset 'markdown_view/katex_autorender' %}
28+
{% asset 'markdown_view/markdown_view' %}
4929

50-
// return false to use original codespan tokenizer
51-
return false;
52-
}
53-
};
54-
marked.use({ tokenizer });
55-
sliceString = "{{ highlight }}";
56-
fetch("{{ resource.get('url') }}")
57-
.then(response => response.blob())
58-
.then(blob => blob.text())
59-
.then(markdown => {
60-
const sliceIndex = markdown.indexOf(sliceString); // find the index of the slice string
61-
const beforeSlice = markdown.substring(0, sliceIndex); // extract the part before the slice string
62-
const afterSlice = markdown.substring(sliceIndex + sliceString.length); // extract the part after the slice string
63-
console.log(sliceIndex); // do whatever you want with the sliced parts
64-
const sliceDiv = document.getElementById("markdown_content2");
65-
document.getElementById("markdown_content1").innerHTML = DOMPurify.sanitize(marked.parse(beforeSlice, { breaks: true }));
66-
sliceDiv.innerHTML = DOMPurify.sanitize(marked.parse(sliceString, { breaks: true }));
67-
document.getElementById("markdown_content3").innerHTML = DOMPurify.sanitize(marked.parse(afterSlice, { breaks: true }));
68-
window.scrollTo({
69-
top: sliceDiv.offsetTop,
70-
behavior: "smooth"
71-
});
72-
});
73-
</script>
30+
{% endblock -%}
Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
{% asset 'markdown_view/markdown_view' %}
2-
31
<div id="markdown_content" data-page-url="{{ resource_view.get('page_url') or resource.get('url') }}">
4-
</div>
2+
</div>
3+
{% asset 'markdown_view/purify' %}
4+
{% asset 'markdown_view/marked' %}
5+
{% asset 'markdown_view/marked_tables' %}
6+
{% asset 'markdown_view/markdown_view_css' %}
7+
{% asset 'markdown_view/katex' %}
8+
{% asset 'markdown_view/katex_css' %}
9+
{% asset 'markdown_view/katex_autorender' %}
10+
{% asset 'markdown_view/markdown_view' %}

ckanext/markdown_view/views.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ def get(self, pkg_id: str, id: str):
1616
from ckanext.markdown_view.plugin import DEFAULT_FORMATS
1717

1818
resource = {}
19+
start_index = int(request.args.get("start", 0)) # Startindex aus den URL-Parametern
20+
end_index = int(request.args.get("end", 0)) # Endindex aus den URL-Parametern
1921
try:
2022
resource = toolkit.get_action("resource_show")({}, {"id": id})
2123
except (toolkit.ObjectNotFound, toolkit.NotAuthorized):
@@ -27,7 +29,10 @@ def get(self, pkg_id: str, id: str):
2729
# base.abort(422, "Not a Markdown File")
2830
return base.render(
2931
"markdown_view/highlight.html",
30-
extra_vars={"resource": resource},
32+
extra_vars={"resource": resource,
33+
"start_index": start_index,
34+
"end_index": end_index,
35+
},
3136
)
3237

3338
def post(self, pkg_id: str, id: str):

0 commit comments

Comments
 (0)