In the middle of the desert you can say anything you want
For one-off HTML exports, found the plugin KosmosisDire/obsidian-webpage-export: Export html from single files, canvas pages, or whole vaults. Direct access to the exported HTML files allows you to publish your digital garden anywhere. Focuses on flexibility, features, and style parity.
It exports both the vault and individual pages, and adds things like toc on the left and toggles and optionally file browsing. Much better than the other pandoc-based export plugin that I could not get to work reliably for exporting good-looking HTML
TL;DR clone to unencrypted directory
error: unable to create file datasets/processed/GitHub-Mensch-Animal_Finetuned/data/val/labels/1713256557366,hintergrund-meister-lampe-geht-das-licht-aus-vom-rueckgang-der-arten-tierische-und-pflanzliche-neubuerger-108~v-16x9@2dM-ad6791ade5eb8b5c935dd377130b903c4b5781d8.txt: File name too long
error: cannot stat ‘datasets/processed/GitHub-Mensch-Animal_Finetuned/data/val/images/1713256557366,hintergrund-meister-lampe-geht-das-licht-aus-vom-rueckgang-der-arten-tierische-und-pflanzliche-neubuerger-108~v-16x9@2dM-ad6791ade5eb8b5c935dd377130b903c4b5781d8.jpg’: File name too long
The usual solution1 is to set longpaths = true
in git config or during clone (git clone -c core.longpaths=true <repo-url>
)
Didn’t solve this for me.
BUT apparently my encrypted $HOME
has something to do with this, because filenames can get longer (?) in this case and go over the limit?.. git checkout-index: unable to create file (File name too long) - Stack Overflow
And one solution is to clone to /tmp
or whatever is not encrypted by encryptfs.
(And in my case I could rename these files in a commit in /tmp and after that it worked, as long as I don’t check out the revisions with the long filenames)
bitmap-trace
that has no centerline optionAutotrace is awesome!
This alone works really nicely:
autotrace -centerline AMPERSAND.png -output-file AMPERSAND.svg
Fish script for batch processing, courtesy of ChatGPT:
#!/usr/bin/fish
# Check if autotrace is installed
if not type -q autotrace
echo "autotrace is not installed. Please install it first."
exit 1
end
# Loop through each .png file provided as an argument
for file in $argv
# Check if the file extension is .png
if string match -r '\.png$' $file
# Set the output filename by replacing .png with .svg
set output_file (string replace -r '\.png$' '.svg' $file)
# Execute autotrace with centerline option
autotrace -centerline $file -output-file $output_file
# Confirmation message
echo "Processed $file to $output_file"
else
echo "Skipping $file: not a .png file"
end
end
And a more simple one:
#!/usr/bin/fish
for file in $argv
autotrace -centerline $file -output-file "$file.svg"
end
ChatGPT says this:
autotrace -centerline -input-format png -output-format svg -output-file traced_dejavu.svg -dpi 300 -error-threshold 0.5 -corner-threshold 85 -filter-iterations 2 -noise-removal 0.99 -line-threshold 0.5 -corner-surround 3
(et 1 is best)
Using the Command Line - Inkscape Wiki
inkscape action-list
shows all available actions
man inkscape
is the latest and best
inkscape AMPERSAND.png --export-type="svg" --export-area-page --batch-process
works but asks me about import options
inkscape --shell
, man page gives examples:
file-open:file1.svg; export-type:pdf; export-do; export-type:png; export-do
file-open:file2.svg; export-id:rect2; export-id-only; export-filename:rect_only.svg; export-do
OK this works for no questions about how to import it:
> file-open:AMPERSAND.png
> export-filename:AM.svg
> export-do
One control, play/pause.
const buttons = document.querySelectorAll('.play-pause-btn');
buttons.forEach(button => {
const audio = document.getElementById(button.dataset.audio);
button.addEventListener('click', () => {
if (audio.paused) {
// Pause all other audio files
document.querySelectorAll('audio').forEach(a => {
a.pause();
a.currentTime = 0; // Reset other audio files
});
document.querySelectorAll('.play-pause-btn').forEach(btn => {
btn.textContent = '▶';
});
// Play the clicked audio
audio.play();
button.textContent = '⏸︎';
} else {
audio.pause();
button.textContent = '▶';
}
});
// Reset button icon when audio ends
audio.addEventListener('ended', () => {
button.textContent = '▶';
});
});
Multiple players:
<div class="player-container">
<button class="play-pause-btn" data-audio="audio1">▶️</button>
<audio id="audio1" src="audio1.mp3"></audio>
</div>
<div class="player-container">
<button class="play-pause-btn" data-audio="audio2">▶️</button>
<audio id="audio2" src="audio2.mp3"></audio>
</div>
.player-container {
display: inline;
vertical-align: text-bottom;
align-items: center;
margin-bottom: 20px;
}
.play-pause-btn {
font-size: 32px;
background: none;
border: none;
cursor: pointer;
margin-right: 10px;
}
I missed an ability to recursively look for elements matching a condition in panflute, so:
def _recursively_find_elements(
element: Element | list[Element], condition: Callable
) -> list[Element]:
"""Return panflute element(s) and their descendants that match conditition.
"""
results = list()
def action(el, doc):
if condition(el):
results.append(el)
if not isinstance(element, list):
element = [element]
for e in element:
e.walk(action)
return results
# sample condition
def is_header(e) -> bool:
cond = e.tag == "Header" and e.level == 2 # and "data-pos" in e.attributes
return cond
Ah, to read:
ddoc = pf.convert_text(
markdown,
input_format="commonmark_x+raw_html+bracketed_spans+fenced_divs+sourcepos",
output_format="panflute",
)
To output readably:
pf.stringify(el).strip()
input_format
has to be commonmark[_x]+
sourcepos
sourcepos
isn’t too well documented, only w/ commonmark
el.attributes['data-pos']
a la 126:1-127:1
line_no
always matching what I expectdef _parse_data_pos(p: str) -> tuple[tuple[int, int], tuple[int, int]]:
"""Parse data-pos string to (line, char) for start and end.
Example: '126:1-127:1' -> ((126, 1), (127, 1))
Arguments:
p: data-pos string as generated by commonmark+sourcepos extension.
"""
start, end = p.split("-")
start_l, start_c = start.split(":")
end_l, end_ch = end.split(":")
return (int(start_l), int(start_c)), (int(end_l), int(end_ch))
Fish Shell function for sourcing standard .env files :
. (sed 's/^/export /' .env | psub)
(And yet another mention of Taskfile that I’ll definitely look into nowG)
I want to automatically get the PDF version of quarto/reveal presentations.
The usual way would be to open the presentation in export mode e
, then print with no margins through the usual print window.
I want to do this automatically as part of a CI/CD pipeliene.
selenium-print · PyPI / bubblegumsoldier/selenium-print uses selenium+chromium to do this.
As for the printing options available in Chrome, this looks relevant:
selenium-print/seleniumprint/drivers/chrome_pdf_driver.py at main · bubblegumsoldier/selenium-print
pdf = self.driver.execute_cdp_cmd("Page.printToPDF", {"printBackground": True})
OK, so it’s all a static option.
Chrome DevTools Protocol - Page domain has the other available options — which is what I need.
The rest of the code feels like a wrapper to this — maybe I can drop the entire library and just use these single bits?
TL;DR use your own personal settings, then “dev settings” (!), then create one but set the resource owner to the organization.
(As of 2024-10-14. Hard to find clear AND CORRECT documentation on this.)
Create access token for organization · community · Discussion #74701.
Gitlab mirroring didn’t work for me after trying for hours, I give up. CI/CD it is.