Here is a pipemenu for displaying your chromium bookmarks.
Commented throughout. Depends on Perl module JSON::Tiny.
I encase the bookark URL itself within a <[!CDATA[ ]]> block and
encode any HTML entities in bookmark/folder titles as some kind of basic
sanity checking before output. Just to keep things kosher.
#!/usr/bin/perl# openbox-chromium 1.01-beta - openbox chrome browser bookmarks pipemenu# Copyright (C) 2018 http://openbox.org/wiki/User:Spoiledbroth## This program is free software: you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation, either version 3 of the License, or# (at your option) any later version.## This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU General Public License for more details.# === DEPENDENCIES: ===# JSON::Tiny - http://search.cpan.org/~davido/JSON-Tiny-0.58/lib/JSON/Tiny.podusestrict;usewarnings;useJSON::Tinyqw(decode_json);useIO::File;useHTML::Entitiesqw(encode_entities);# === CONFIGURATION: ===# $bookmarks - Location of your chromium/google-chrome bookmarks.# You can try "find ~/.config -name Bookmarks" if you're having finding it.# $browser - browser command, either x-www-browser, chromium or google-chrome# $maxlength - upper limit of characters for bookmark titlesmy$bookmarks="./config/chromium/Profile 1/Bookmarks";my$browser="chromium";my$maxlength=35;# Lets open up that bookmarks filemy$file=do{local$/=undef;openmy$fh,"<",$bookmarksordie"could not open $bookmarks: $!";<$fh>};# Now, get the bookmark JSON into a referencemy$data=decode_json$file;# Remove sync transaction infos... causes the script to blow up.delete$data->{'roots'}->{'sync_transaction_version'};# Cast that reference to a hash of the 'roots' entries in the bookmark file.my%json=%{$data->{'roots'}};# ... so we only loop over what we need, essentially.# Build the Openbox menu headerprint"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"."<openbox_pipe_menu>\n";# Main program loop...foreach(keys%json){traversal($data->{'roots'}->{$_});}# End of menuprint"</openbox_pipe_menu>\n";# Recursion function for bookmark "folders"subtraversal{my($obtained)=@_;# If the entry is a folder with >0 children, build an entry and recurseif(($obtained->{'type'}eq"folder")&&(0+@{$obtained->{'children'}}!=0)&&($obtainedne"sync_transaction_version")){build_entry($obtained);my@children=@{$obtained->{'children'}};foreachmy$i(0..$#children){#delete $children[$i]->{'sync_transaction_version'}traversal($children[$i]);}print"</menu>\n";# I'm not perfect...# Else, we need to build an entry for a URL.}elsif($obtained->{'type'}eq"url"){build_entry($obtained);}return;}# Function to build the menu (seperation of concerns)subbuild_entry{my($entry)=@_;if($entry->{'type'}eq"folder"){# print case for bookmark folderprint" <menu id=\"".$entry->{'id'}."\" label=\"".encode_entities($entry->{'name'})."\">\n";}elsif($entry->{'type'}eq"url"){# print case for bookmark linkmy$truncated=scalar$entry->{'name'};$truncated=~s/^(.{1,$maxlength})(.+)?/$1 . (defined $2 ? "..." : "")/e;print" <item label=\"".encode_entities($truncated)."\">\n"." <action name=\"Execute\">\n"." <execute>\n"." ".$browser." <![CDATA[".$entry->{'url'}."]]>\n"." </execute>\n"." </action>\n"." </item>\n";}return;}