v2 : no more dependy to jquery, signet generates <table> instead of <ol>
This commit is contained in:
parent
dd65be059f
commit
8abd7f50d1
@ -1,80 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# needs a better name
|
||||
|
||||
# - - - - - - - - - - - - - - - - ARGS - - - - - - - - - - - - - - - - -
|
||||
show_help() {
|
||||
echo "Usage:"
|
||||
echo "1. Copy the desired Url to your clipboard"
|
||||
echo "2. ./edit_bookmarks_dmenu.sh BOOKMARKS"
|
||||
echo "Options:"
|
||||
echo " --help Display this help message"
|
||||
exit 1
|
||||
}
|
||||
if [ "$#" -eq 0 ]; then
|
||||
echo "Nothing happened, I need a file of bookmarks to edit."
|
||||
show_help
|
||||
fi
|
||||
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case "$1" in
|
||||
--help)
|
||||
show_help
|
||||
;;
|
||||
-*)
|
||||
echo "Error: Unknown option: $1" >&2
|
||||
show_help
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
dmenu_style() {
|
||||
local font='junicode-18'
|
||||
local normal_bg='#000000'
|
||||
local normal_fg='#FFFFFF'
|
||||
local selected_bg='#AAAAAA'
|
||||
local selected_fg='#000000'
|
||||
echo "-fn $font -nb $normal_bg -nf $normal_fg -sb $selected_bg -sf $selected_fg"
|
||||
}
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --
|
||||
|
||||
# TODO : process multiple files of BOOKMARKS at once
|
||||
BOOKMARKS=$1
|
||||
|
||||
URL=$(xclip -o -selection clipboard)
|
||||
|
||||
# The curl for Name: is a blocking process and will pause the programm
|
||||
# in case internet shuts :^)
|
||||
|
||||
# TODO :
|
||||
# add description, tags and color in one field with symbols such as :
|
||||
# § this is a description. § comma, separated, tags § color
|
||||
|
||||
# If the given string ressembles to a url, continue.
|
||||
# https://stackoverflow.com/questions/21115121/how-to-test-if-string-matches-a-regex-in-posix-shell-not-bash
|
||||
# URL_REGEX="^(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]*[-A-Za-z0-9+&@#/%=~_|]"
|
||||
if printf "$URL" | grep -q http; then
|
||||
# TODO : incrementing id replacing <ol> list counter
|
||||
#PREV_URL_COUNT=$(grep "URL: " $BOOKMARKS | wc -l)
|
||||
#ID: $((PREV_URL_COUNT + 1))
|
||||
# TODO : add the bookmark in reverse, last in first first on the stack
|
||||
# maybe using tac instead of cat ?
|
||||
cat <<- EOF >> $BOOKMARKS
|
||||
|
||||
URL: $(printf $URL)
|
||||
Name: $(curl $URL | awk -v RS='</title>' '\
|
||||
/<title>/ {gsub(/.*<title>/, ""); print}\
|
||||
' | tr -d '\n')
|
||||
Description: $(printf "" | dmenu -p "Enter a description: " $(dmenu_style))
|
||||
Tags: $(printf "" | dmenu -p "Enter comma separated tags: " $(dmenu_style))
|
||||
Date: $(date +%s)
|
||||
|
||||
EOF
|
||||
|
||||
else
|
||||
printf "Text in clipboard is not a url"
|
||||
exit
|
||||
fi
|
||||
|
||||
# what we used to need htmlq for :
|
||||
# name=$(curl $url | ~/.cargo/bin/htmlq title --text | sed -r '/^\s*$/d' | sed 's/^ *//g')
|
60
interface_dmenu.sh
Executable file
60
interface_dmenu.sh
Executable file
@ -0,0 +1,60 @@
|
||||
#!/bin/bash
|
||||
|
||||
# - - - - - - - - - - - - - - - - ARGS - - - - - - - - - - - - - - - - -
|
||||
show_help() {
|
||||
printf "
|
||||
Usage:
|
||||
1. Copy the desired URL to your clipboard
|
||||
2. ./interface_dmenu.sh BOOKMARKS
|
||||
Options:
|
||||
--help Display this help message"
|
||||
exit 1
|
||||
}
|
||||
if [ "$#" -eq 0 ]; then
|
||||
printf "Nothing happened, I need a file of bookmarks to edit."
|
||||
show_help
|
||||
fi
|
||||
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case "$1" in
|
||||
--help)
|
||||
show_help
|
||||
;;
|
||||
-*)
|
||||
printf "Error: Unknown option: $1" >&2
|
||||
show_help
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
dmenu_style() {
|
||||
local font='junicode-18'
|
||||
local normal_bg='#000000'
|
||||
local normal_fg='#FFFFFF'
|
||||
local selected_bg='#AAAAAA'
|
||||
local selected_fg='#000000'
|
||||
echo "-fn $font -nb $normal_bg -nf $normal_fg -sb $selected_bg -sf $selected_fg"
|
||||
}
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --
|
||||
|
||||
URL=$(xclip -o -selection clipboard)
|
||||
|
||||
if [ "${URL#"http"}" != "$URL" ]; then
|
||||
DESC=$(dmenu -p "$URL · description →" $(dmenu_style))
|
||||
TAGS=$(dmenu -p "$URL · $DESC · tags →" $(dmenu_style))
|
||||
|
||||
cat <<- EOF > signet
|
||||
URL: $URL
|
||||
Description: $DESC
|
||||
Tags: $TAGS
|
||||
Date: $(date +%g/%m/%d)
|
||||
|
||||
EOF
|
||||
|
||||
./edit.sh
|
||||
|
||||
else
|
||||
printf "Text in clipboard is not a url"
|
||||
exit
|
||||
fi
|
64
script.js
64
script.js
@ -1,59 +1,19 @@
|
||||
//document.addEventListener("keydown", function(event) {
|
||||
// var keyPressed = event.key.toLowerCase();
|
||||
//
|
||||
// if (keyPressed === 'p') {
|
||||
// const val = Math.round(Math.random()*255)
|
||||
// document.querySelector('body').style.background = `rgba(${val},${val /2},${val})`
|
||||
// console.log("The 'P' key was pressed");
|
||||
// }
|
||||
//});
|
||||
const textarea = document.querySelector('textarea')
|
||||
|
||||
// Barre de recherche
|
||||
$(document).ready(function () {
|
||||
$('li').addClass('active')
|
||||
$('textarea').on('input', function () {
|
||||
var userInput = $(this).val().toLowerCase();
|
||||
|
||||
$('li').each(function () {
|
||||
var listItemText = $(this).text().toLowerCase();
|
||||
if (listItemText.includes(userInput)) {
|
||||
$(this).addClass('active');
|
||||
} else {
|
||||
$(this).removeClass('active');
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
// On convertit les dates au format AA-MM-JJ
|
||||
function formatDateFromEpoch(epochTime) {
|
||||
const date = new Date(epochTime * 1000);
|
||||
|
||||
const YY = date.getFullYear().toString()
|
||||
const MM = ('0' + (date.getMonth() + 1)).slice(-2)
|
||||
const DD = ('0' + date.getDate()).slice(-2)
|
||||
|
||||
if(epochTime == ''){
|
||||
|
||||
return `N/A`;
|
||||
}
|
||||
|
||||
return `${YY}/${MM}/${DD}`;
|
||||
function updateValue(e) {
|
||||
let val = textarea.value.toLowerCase()
|
||||
document.querySelectorAll('.signets tr').forEach((e) => {
|
||||
var listItemText = e.innerHTML.toLowerCase();
|
||||
listItemText.includes(val) ?
|
||||
e.classList.remove('hidden') : e.classList.add('hidden')
|
||||
})
|
||||
}
|
||||
|
||||
const dates = document.querySelectorAll('h4')
|
||||
dates.forEach((date) => {
|
||||
date.innerHTML= formatDateFromEpoch(date.innerHTML)
|
||||
document.addEventListener("DOMContentLoaded", function(event) {
|
||||
textarea.addEventListener("input", updateValue);
|
||||
})
|
||||
|
||||
// On cache les descriptions si elles sont vides
|
||||
$('h2').each(function() {
|
||||
$(this).html() == '' ? $(this).hide() : $(this).show()
|
||||
})
|
||||
|
||||
// On colore les entrées qui ont un attribut 'color'
|
||||
$('[color]').each(function() {
|
||||
$(this).css('background', `linear-gradient(var(--background), ${$(this).attr('color')} `)
|
||||
document.querySelectorAll('[color]').forEach((e) => {
|
||||
e.style.background = `linear-gradient(var(--background), ${e.getAttribute('color')} `
|
||||
|
||||
})
|
||||
|
141
signet.sh
141
signet.sh
@ -31,7 +31,7 @@ while [ "$#" -gt 0 ]; do
|
||||
if [ -f "$1" ]; then
|
||||
break
|
||||
else
|
||||
echo "The file you provided doesn't seam to exist : $1"
|
||||
echo "The file provided doesn't seem to exist : $1"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
@ -40,77 +40,102 @@ while [ "$#" -gt 0 ]; do
|
||||
done
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --
|
||||
|
||||
# I thought about using recutils db from GNU but went back to plain text
|
||||
# DB=BOOKMARKS.rec
|
||||
DB=$1
|
||||
blanklineRecords_to_html()
|
||||
{
|
||||
awk -v RS= '
|
||||
{
|
||||
if ($0 != "") {
|
||||
id=""
|
||||
URL=""
|
||||
DESC=""
|
||||
TAGS=""
|
||||
DATE=""
|
||||
color=""
|
||||
|
||||
cat <<- EOF
|
||||
split($0, lines, "\n")
|
||||
for (i in lines) {
|
||||
if(lines[i] ~ /^[0-9]+$/ ) {
|
||||
id=lines[i]
|
||||
}
|
||||
split(lines[i], parts, ": ")
|
||||
field = parts[1]
|
||||
value = parts[2]
|
||||
|
||||
if(field ~ /^Color/ ) {color=value}
|
||||
if(field ~ /^URL/ ) {URL=value }
|
||||
if(field ~ /^Name/ ) {NAME=value }
|
||||
if(field ~ /^Description/ ) {DESC=value }
|
||||
if(field ~ /^Tags/ ) {TAGS=value }
|
||||
if(field ~ /^Date/ ) {DATE=value }
|
||||
|
||||
}
|
||||
|
||||
if(color != ""){
|
||||
printf "<tr color=\"%s\">", color
|
||||
}
|
||||
else{
|
||||
printf "%s", "<tr>"
|
||||
}
|
||||
printf "<td class=\"id\">%d</td>", id
|
||||
|
||||
printf "<td><a href=\"%s\">%s</a>\n", URL, NAME
|
||||
if(DESC != "") {printf "<p class=\"desc\">%s</p>\n", DESC}
|
||||
printf "</td>"
|
||||
|
||||
printf "<td><p class=\"tags\">%s</p></td>\n", TAGS
|
||||
printf "<td><date>%s</date></td>\n", DATE
|
||||
|
||||
print "</tr>"
|
||||
}
|
||||
} '
|
||||
}
|
||||
DB=$1
|
||||
cat <<- EOF
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<head>
|
||||
<title>⛵ → $(date "+%g-%m-%d, %H:%M")</title>
|
||||
<script defer src="jquery-3.7.1.slim.min.js"></script>
|
||||
<script defer src="script.js"></script>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<script defer src="script.js"></script>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="cc"></div>
|
||||
<textarea autofocus></textarea>
|
||||
</head>
|
||||
<body>
|
||||
<p>liens épinglés</p>
|
||||
<table class="PIN">
|
||||
$(
|
||||
cat $DB |\
|
||||
awk -v RS= '/PIN/ {print $0 "\n"}' | blanklineRecords_to_html
|
||||
)
|
||||
|
||||
</table>
|
||||
<hr>
|
||||
<textarea rows="1" autofocus placeholder="filtrer..."></textarea>
|
||||
<hr>
|
||||
<details>
|
||||
<summary>tags</summary>
|
||||
<nav>
|
||||
$(
|
||||
awk '/Tags: ./ {print tolower($0)}' $DB |\
|
||||
sed -e 's/tags: //' -e 's/,/\n/g' | sed 's/^ //g' |\
|
||||
sort | uniq -c | sort -nr |\
|
||||
awk '{print "<p count=\"" $1 "\">" $2 "</p>"}'
|
||||
sort | uniq -cd | sort -nr |\
|
||||
awk '{print "<button count=\"" $1 "\">" $2 "</button>"}'
|
||||
)
|
||||
</nav>
|
||||
<ol>
|
||||
</details>
|
||||
<hr>
|
||||
|
||||
<table class="signets">
|
||||
<thead><tr>
|
||||
<td>#</td>
|
||||
<td>Title, URL, description</td>
|
||||
<td>tags</td>
|
||||
<td>y/m/d<rtd>
|
||||
</tr></thead>
|
||||
$(
|
||||
awk -v RS= '!/Tags: .*hide/ {print $0 "\n"}' $DB |\
|
||||
awk -v RS= '
|
||||
{
|
||||
if ($0 != "") {
|
||||
split($0, lines, "\n")
|
||||
color = ""
|
||||
for (i in lines) {
|
||||
split(lines[i], parts, ": ")
|
||||
field = parts[1]
|
||||
value = parts[2]
|
||||
if (field == "Color") {
|
||||
color = value
|
||||
}
|
||||
vals[i] = value
|
||||
}
|
||||
URL=vals[1]
|
||||
NAME=vals[2]
|
||||
DESC=vals[3]
|
||||
TAGS=vals[4]
|
||||
DATE=vals[5]
|
||||
|
||||
print "<li>"
|
||||
print "<a href=\"" URL "\">"
|
||||
|
||||
if (color != "") {
|
||||
print "<section color=\"" color "\">"
|
||||
}
|
||||
else {
|
||||
print "<section>"
|
||||
}
|
||||
|
||||
print "<h4>" DATE "</h4>" \
|
||||
"<h1>" NAME "</h1>" \
|
||||
"<h5>" URL "</h5>" \
|
||||
"<h2>" DESC "</h2>" \
|
||||
"<h3>" TAGS "</h3>"
|
||||
|
||||
print "</section>"
|
||||
print "</a>"
|
||||
print "</li>"
|
||||
}
|
||||
} '
|
||||
cat $DB |\
|
||||
blanklineRecords_to_html
|
||||
)
|
||||
</ol>
|
||||
</table>
|
||||
<footer></footer>
|
||||
</body>
|
||||
</html>
|
||||
|
212
style.css
212
style.css
@ -1,24 +1,15 @@
|
||||
/* h1 → Name
|
||||
* h2 → Description
|
||||
* h3 → Tags
|
||||
* h4 → Date
|
||||
* h5 → Url
|
||||
*/
|
||||
:root {
|
||||
--font-size:22px;
|
||||
--font-size-s:calc(var(--font-size) / 1.5);
|
||||
--line-height:24px;
|
||||
--date-width:10ch;
|
||||
--gutter:0px;
|
||||
--padding:2px;
|
||||
:root{
|
||||
--font-size:12px;
|
||||
--line-height:16px;
|
||||
--gap:2px;
|
||||
--height:calc(var(--line-height) + var(--gap) * 2);
|
||||
--height:auto;
|
||||
--color:black;
|
||||
--selection:purple;
|
||||
--background:#FFF;
|
||||
--background-2:#FEFEFE;
|
||||
--background-bottom:black;
|
||||
--width-number:2em;
|
||||
--background:#FEFEFE;
|
||||
--link:purple;
|
||||
--text:black;
|
||||
--selection:lightyellow
|
||||
}
|
||||
/* https://github.com/psb1558/Junicode-font/releases */
|
||||
@font-face {
|
||||
font-family: Junicode;
|
||||
src: url("Junicode-CondLight.otf") format("opentype");
|
||||
@ -32,158 +23,53 @@
|
||||
font-family: Junicode, serif;
|
||||
font-variant-numeric: lining-nums;
|
||||
}
|
||||
h1,h2,h3,h4,h5,p, a {
|
||||
text-wrap:wrap;
|
||||
word-break: break-word;
|
||||
line-height:var(--line-height);
|
||||
padding:0;
|
||||
margin:0;
|
||||
font-weight:normal;
|
||||
font-size:var(--font-size);
|
||||
}
|
||||
h1,h2,h3,h5 {
|
||||
display:inline;
|
||||
}
|
||||
nav, section, textarea {
|
||||
padding: var(--padding) 0;
|
||||
}
|
||||
a{
|
||||
width:100%;
|
||||
display:block;
|
||||
color:var(--color);
|
||||
text-decoration:none;
|
||||
margin:auto;
|
||||
|
||||
textarea {width:100%;padding:0;margin:0;
|
||||
border:1px dotted black;
|
||||
height:var(--height)
|
||||
}
|
||||
h5 {
|
||||
text-decoration:underline }
|
||||
li:hover a {
|
||||
color:var(--selection)}
|
||||
|
||||
.PIN date, .PIN .tags, .PIN .id {display:none}
|
||||
|
||||
tr a{color:var(--text); text-decoration:none}
|
||||
tr a::after{
|
||||
margin-left:5px; content:attr(href); color:var(--link);
|
||||
text-decoration:underline}
|
||||
|
||||
textarea{
|
||||
position:fixed;
|
||||
top:0;
|
||||
left:5px;
|
||||
z-index:10;
|
||||
width:calc(100vw - 10px);
|
||||
font-size:var(--font-size);
|
||||
height:calc(var(--line-height) + var(--padding));
|
||||
}
|
||||
ol {
|
||||
margin:0;
|
||||
display:flex;
|
||||
gap:var(--gutter);
|
||||
flex-direction:column-reverse;
|
||||
li:hover a::after{display:block}
|
||||
|
||||
}
|
||||
body {
|
||||
tbody tr:hover {background:var(--selection)}
|
||||
|
||||
}
|
||||
footer {
|
||||
height:100vh;
|
||||
margin-top:50vh;
|
||||
background:linear-gradient( var(--background), var(--background-bottom));
|
||||
width:calc(100% + 20px - 2px);
|
||||
margin-left:-10px;
|
||||
margin-bottom:-10px;
|
||||
overflow:hidden;
|
||||
}
|
||||
li {
|
||||
font-size:var(--font-size);
|
||||
color:rgba(0,0,0,0);
|
||||
height:0;
|
||||
overflow:hidden
|
||||
}
|
||||
li * {opacity:0}
|
||||
.active:nth-of-type(2n){
|
||||
background:var(--background-2);
|
||||
|
||||
}
|
||||
li,textarea, nav {
|
||||
|
||||
box-sizing:border-box;
|
||||
border:none;
|
||||
|
||||
}
|
||||
.active * {opacity:1}
|
||||
.active {
|
||||
border-bottom: 1px solid black;
|
||||
td {line-height:var(--line-height);
|
||||
height:var(--height);
|
||||
display:list-item;
|
||||
color:var(--color);
|
||||
overflow:visible;
|
||||
}
|
||||
h1,h2,a {
|
||||
}
|
||||
h3{
|
||||
opacity:.5
|
||||
}
|
||||
section{
|
||||
padding-right:var(--date-width);
|
||||
height:calc(var(--font-size) + 2px) ;
|
||||
overflow:hidden;
|
||||
}
|
||||
section:hover{
|
||||
height:auto
|
||||
}
|
||||
section:hover h1, h2, h3, h5{
|
||||
display:inline
|
||||
}
|
||||
h1 {order: 0;
|
||||
|
||||
}
|
||||
h2 {
|
||||
font-style:italic}
|
||||
h5,h2,h3,h4 {
|
||||
order:3
|
||||
}
|
||||
|
||||
h3::before, h2::before, h1::after{content:'\00a0·\00a0';}
|
||||
|
||||
h4 {
|
||||
width:var(--date-width);
|
||||
width:fit-content;
|
||||
text-align: right;
|
||||
|
||||
position:absolute;
|
||||
right:10px;
|
||||
}
|
||||
html{background:white}
|
||||
nav p {display:inline;
|
||||
}
|
||||
nav p:not(:first-of-type)::before{
|
||||
content:'· '
|
||||
}
|
||||
nav p::after{
|
||||
font-size:var(--font-size-s);
|
||||
display:inline-block;
|
||||
transform:translateY(-7px);
|
||||
content:'\00a0(' attr(count) ')'
|
||||
}
|
||||
nav {
|
||||
border-top: 1px solid black;
|
||||
border-bottom: 1px solid black;
|
||||
margin-top:calc(var(--line-height) + 1px + var(--padding));
|
||||
height:calc(var(--line-height) + var(--padding) * 2);
|
||||
overflow:hidden;
|
||||
|
||||
}
|
||||
nav:hover {height:auto}
|
||||
#cc {
|
||||
display:absolute;
|
||||
position:fixed;
|
||||
top:0;
|
||||
left:0;
|
||||
z-index:10;
|
||||
height:100vh;
|
||||
width:100vw;
|
||||
pointer-events:none;
|
||||
background:linear-gradient(0deg, yellow, ivory);
|
||||
mix-blend-mode:multiply;
|
||||
|
||||
/* A color correction pass, enable it by removing this line ↓ */
|
||||
display:none
|
||||
padding: var(--gap) 5px;
|
||||
word-break:break-word;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse:collapse;
|
||||
border: 1px dotted black;
|
||||
}
|
||||
|
||||
hr{ border:none;
|
||||
border-bottom: 1px solid black;
|
||||
}
|
||||
|
||||
button::after {
|
||||
content:" "attr(count);
|
||||
position:absolute;
|
||||
transform:translate(1px, -5px)
|
||||
}
|
||||
|
||||
button{background:transparent;border:none}
|
||||
|
||||
p{margin:0;display:inline}
|
||||
.desc {opacity:.5}
|
||||
|
||||
td:last-of-type {text-align:center;min-width:8ch}
|
||||
td:first-of-type {text-align:center;width:4ch}
|
||||
td:nth-of-type(3) {text-align:center}
|
||||
|
||||
.hidden{display:none}
|
||||
tr,table {min-width:100%}
|
||||
|
Loading…
Reference in New Issue
Block a user