Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -126,29 +126,15 @@ def check_for_fragment(url):
|
|
| 126 |
return '#:~:text=' in url
|
| 127 |
|
| 128 |
def copy_to_clipboard_js(text, button_id):
|
| 129 |
-
"""Generate JavaScript for copying text to clipboard
|
| 130 |
-
#
|
| 131 |
-
escaped_text = json.dumps(text
|
| 132 |
return f"""
|
| 133 |
-
<div>
|
| 134 |
-
<textarea id="copy_text_{button_id}" style="display: none;">{escaped_text}</textarea>
|
| 135 |
-
<button onclick="copyToClipboard_{button_id}()" class="copy-button">Copy to Clipboard</button>
|
| 136 |
-
<span id="copy_status_{button_id}" style="margin-left: 10px; font-weight: bold;"></span>
|
| 137 |
-
</div>
|
| 138 |
<script>
|
| 139 |
function copyToClipboard_{button_id}() {{
|
| 140 |
-
|
| 141 |
-
const textElement = document.getElementById('copy_text_{button_id}');
|
| 142 |
-
const textToCopy = textElement ? textElement.value : '';
|
| 143 |
-
if (!textToCopy) {{
|
| 144 |
-
console.error('No text to copy for {button_id}');
|
| 145 |
-
const statusElement = document.getElementById('copy_status_{button_id}');
|
| 146 |
-
if (statusElement) statusElement.innerHTML = 'No text to copy';
|
| 147 |
-
return;
|
| 148 |
-
}}
|
| 149 |
if (navigator.clipboard) {{
|
| 150 |
navigator.clipboard.writeText(textToCopy).then(function() {{
|
| 151 |
-
console.log('Text copied successfully for {button_id}: ' + textToCopy);
|
| 152 |
const statusElement = document.getElementById('copy_status_{button_id}');
|
| 153 |
if (statusElement) {{
|
| 154 |
statusElement.innerHTML = 'Copied!';
|
|
@@ -157,17 +143,22 @@ def copy_to_clipboard_js(text, button_id):
|
|
| 157 |
}}, 2000);
|
| 158 |
}}
|
| 159 |
}}, function(err) {{
|
| 160 |
-
console.error('Copy failed for {button_id}: ', err);
|
| 161 |
const statusElement = document.getElementById('copy_status_{button_id}');
|
| 162 |
-
if (statusElement)
|
|
|
|
|
|
|
|
|
|
| 163 |
}});
|
| 164 |
}} else {{
|
| 165 |
-
console.error('Clipboard API not supported');
|
| 166 |
const statusElement = document.getElementById('copy_status_{button_id}');
|
| 167 |
-
if (statusElement)
|
|
|
|
|
|
|
| 168 |
}}
|
| 169 |
}}
|
| 170 |
</script>
|
|
|
|
|
|
|
| 171 |
"""
|
| 172 |
|
| 173 |
# --- Live Clock JavaScript ---
|
|
@@ -317,14 +308,22 @@ with tabs[0]:
|
|
| 317 |
# HTML Citation - Start of Text
|
| 318 |
with col_html1:
|
| 319 |
st.markdown("### Citation (Start of Text)")
|
| 320 |
-
|
| 321 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 322 |
|
| 323 |
# HTML Citation - End of Text
|
| 324 |
with col_html2:
|
| 325 |
st.markdown("### Citation (End of Text)")
|
| 326 |
-
|
| 327 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 328 |
|
| 329 |
# Citation Hash Details
|
| 330 |
st.markdown("### Citation Hash Details (for Verification)")
|
|
|
|
| 126 |
return '#:~:text=' in url
|
| 127 |
|
| 128 |
def copy_to_clipboard_js(text, button_id):
|
| 129 |
+
"""Generate JavaScript for copying text to clipboard with proper escaping."""
|
| 130 |
+
# Escape special characters for JavaScript string
|
| 131 |
+
escaped_text = json.dumps(text).strip('"').replace('</', '<\\/') # Properly escape for JS
|
| 132 |
return f"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 133 |
<script>
|
| 134 |
function copyToClipboard_{button_id}() {{
|
| 135 |
+
const textToCopy = `{escaped_text}`;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 136 |
if (navigator.clipboard) {{
|
| 137 |
navigator.clipboard.writeText(textToCopy).then(function() {{
|
|
|
|
| 138 |
const statusElement = document.getElementById('copy_status_{button_id}');
|
| 139 |
if (statusElement) {{
|
| 140 |
statusElement.innerHTML = 'Copied!';
|
|
|
|
| 143 |
}}, 2000);
|
| 144 |
}}
|
| 145 |
}}, function(err) {{
|
|
|
|
| 146 |
const statusElement = document.getElementById('copy_status_{button_id}');
|
| 147 |
+
if (statusElement) {{
|
| 148 |
+
statusElement.innerHTML = 'Copy failed';
|
| 149 |
+
}}
|
| 150 |
+
console.error('Could not copy text: ', err);
|
| 151 |
}});
|
| 152 |
}} else {{
|
|
|
|
| 153 |
const statusElement = document.getElementById('copy_status_{button_id}');
|
| 154 |
+
if (statusElement) {{
|
| 155 |
+
statusElement.innerHTML = 'Clipboard API not supported';
|
| 156 |
+
}}
|
| 157 |
}}
|
| 158 |
}}
|
| 159 |
</script>
|
| 160 |
+
<button onclick="copyToClipboard_{button_id}()" class="copy-button">Copy to Clipboard</button>
|
| 161 |
+
<span id="copy_status_{button_id}" style="margin-left: 10px; font-weight: bold;"></span>
|
| 162 |
"""
|
| 163 |
|
| 164 |
# --- Live Clock JavaScript ---
|
|
|
|
| 308 |
# HTML Citation - Start of Text
|
| 309 |
with col_html1:
|
| 310 |
st.markdown("### Citation (Start of Text)")
|
| 311 |
+
html_citation_start = citation_link_start
|
| 312 |
+
|
| 313 |
+
st.markdown('<div class="rendered-citation">', unsafe_allow_html=True)
|
| 314 |
+
st.markdown(html_citation_start, unsafe_allow_html=True)
|
| 315 |
+
st.markdown(copy_to_clipboard_js(html_citation_start.replace('`', '\\`'), "html_start"), unsafe_allow_html=True)
|
| 316 |
+
st.markdown('</div>', unsafe_allow_html=True)
|
| 317 |
|
| 318 |
# HTML Citation - End of Text
|
| 319 |
with col_html2:
|
| 320 |
st.markdown("### Citation (End of Text)")
|
| 321 |
+
html_citation_end = citation_link_end
|
| 322 |
+
|
| 323 |
+
st.markdown('<div class="rendered-citation">', unsafe_allow_html=True)
|
| 324 |
+
st.markdown(html_citation_end, unsafe_allow_html=True)
|
| 325 |
+
st.markdown(copy_to_clipboard_js(html_citation_end.replace('`', '\\`'), "html_end"), unsafe_allow_html=True)
|
| 326 |
+
st.markdown('</div>', unsafe_allow_html=True)
|
| 327 |
|
| 328 |
# Citation Hash Details
|
| 329 |
st.markdown("### Citation Hash Details (for Verification)")
|