diff --git a/README.md b/README.md index 0f5b4dc..f5e197b 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,35 @@ # Feedr -Open syndication feed files from desktop. \ No newline at end of file +Feedr is a syndication utility with simple functionality, to open syndication +files directly from your desktop. + +## Functionality + +With a click, Feed will open and render given XML based syndication files of +type Atom Syndication Format, RDF, and RSS. + +## Customization + +CSS and XSL stylesheets can be changed, by adding custom CSS and XSL files to +`.local/share/feedr/css/stylesheet.css` and `.local/share/feedr/xsl/stylesheet.xsl` +respectively. + +## Note + +Your browser of choice must support XSLT. + +## Recommendations + +It is recommended to install one of these browsers: + +- Falkon https://falkon.org +- Otter Browser https://otter-browser.org +- qutebrowser https://qutebrowser.org + +## License + +Feedr is subjected to the license MIT. + +## Author + +Schimon Jehudah Zachary diff --git a/css/stylesheet-rtl.css b/css/stylesheet-rtl.css new file mode 100644 index 0000000..9d015f5 --- /dev/null +++ b/css/stylesheet-rtl.css @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2016 - 2017 Schimon Jehuda. Released under MIT license + * Feeds rendered using this XSLT stylesheet, or it's derivatives, must + * include https://sjehuda.github.io/ in attribute name='generator' of + * element inside of html element + */ + +#feed { + direction: rtl; +} + +#logo { + float: left; + margin-left: -5px; +} +.geolocation > a { + padding-right: 6px; +} + +.image { + float: right; + /* margin: 20px auto auto 40px; */ + margin-left: 40px; + margin-right: auto; +} diff --git a/css/stylesheet.css b/css/stylesheet.css new file mode 100644 index 0000000..4f0db3f --- /dev/null +++ b/css/stylesheet.css @@ -0,0 +1,303 @@ +/* + +TODO + +pubsub: news.movim.eu + node: fake-news + item: fdef84f5-e3e1-41ea-9b68-af4bb9130f77 + title: #14October2023EpochEclipse + date: Fri, 15 Jan 2021 20:24:46 + +*/ + +* { + color: #eee; + max-width: 100%; +} + +/* +a { + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} +*/ + +body { + background: #000; +} + +code, pre { + overflow: auto; + max-height: 100%; + max-width: 100%; } + +img, svg, video { + display: block; + max-height: 500px; + width: auto; + height: auto; +} + +h1#title, h2#subtitle, #actions, #references { + text-align: center; + text-transform: uppercase; + line-height: 140%; +} + +h5.related > a { + margin-right: 5px; + text-decoration: none; + user-select: none; + +} + +h3.title > a { + display: block; + padding-top: 50px; +} + +#actions, #references { + border-bottom: 1px solid #eee; + line-height: 150%; + padding: 10px; + user-select: none; +} + +#actions > *, #references * { + letter-spacing: 5px; + margin: 5px; + text-decoration: none; +} + +#header, #menu { + line-height: 120%; + padding-bottom: 20px; +} + +#menu > h3 { + padding-left: 2%; +} + +#menu > ol > li { + padding: 5px; +} + +#references { + margin-top: 5em; + border-top: 1px solid #eee; +} + +#articles { + min-height: 80vh; + display: flex; +} + +#articles #journal { + margin-left: 2%; + margin-right: 2%; + margin-top: 2%; + min-width: 350px; + padding-bottom: 0.67em; + width: 20%; +} + +#journal { + margin: auto; + padding-top: 50px; +} + +#articles > ul { + margin: auto; + margin-left: 2%; + margin-top: 2%; +} + +#articles #journal ol, +#articles #journal ul { + /* height: 500px; */ + line-height: 160%; + overflow: auto; + word-wrap: break-word; +} + +#articles div.content { + font-size: 120%; + line-height: 200%; + margin: auto; + padding-left: 2%; + padding-right: 10%; + /* text-align: justify; */ + word-wrap: break-word; +} + +#articles div.entry { + padding-bottom: 0.67em; +} + +#articles div.entry h1 { + font-size: 115%; /* 2vw */ +} + +#articles div.entry h2 { + font-size: 1.5vw; +} + +#selection-page { + background: #000; + bottom: 0; + left: 0; + line-height: 200%; + overflow: overlay; + position: fixed; + right: 0; + text-align: center; + top: 0; +} + +#selection-page p { + margin-left: 10%; + margin-right: 10%; +} + +#selection-page span { + display: inline-grid; + margin: 2% +} + +#selection-page img { + height: 128px; + margin-bottom: 20%; + margin-top: 20%; + width: 128px; +} + +#selection-page #selection { + margin-bottom: 2%; +} + +#selection-page #return { + /* font-style: italic; */ + margin: auto; +} + +#selection-link, #selection-page #return { + cursor: pointer; + text-decoration: underline; +} + +.content[type='text'] { + white-space: pre-wrap; +} + +#articles div.entry span.tags { + display: inline-flex; + /* display: ruby; */ + flex-wrap: wrap; +} + +#articles div.entry span.tags > div { + margin: 5px; +} + +.enclosures { + cursor: help; + direction: ltr; + margin: 5px auto 15px 1%; + padding: 15px; + padding: 1em; + /* background: #222; + border: 1px solid GrayText; + border-radius: 4px; + border-radius: .5em; + color: #525c66; + border-left: double; + max-width: 40%; */ +} + +.enclosure a { + margin: 3px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.enclosure > span[icon='atom']:after, +.enclosure > span[icon='html5']:after, +.enclosure > span[icon='rss']:after { + content: '📰'; + margin:3px; +} + +.enclosure > span.audio:after { + content: ' (Audio file) '; +} + +.enclosure > span[icon='audio']:after{ + content: '🎼️'; + margin: 3px; +} + +.enclosure > span:after { + content: ' (Document file) '; +} + +.enclosure > span[icon]:after { + content: '📄️'; + margin: 3px; +} + +.enclosure > span.executable:after{ + content: ' (Executable file) '; +} + +.enclosure > span[icon='executable']:after { + content: '📦️'; + margin: 3px; +} + +.enclosure > span.image:after { + content: ' (Image file) '; +} + +.enclosure > span[icon='image']:after { + content: '🖼️'; + margin: 3px; +} + +.enclosure > span.video:after { + content: ' (Video file) '; +} + +.enclosure > span[icon='video']:after { + content: '📽️'; + margin:3px; +} + +#note, #small { + line-height: 30px; + margin: auto; + margin-top: 0.67em; + max-width: 80%; + padding: 10px; + text-align: center; + user-select: none; +} + +#small { + font-size: 80%; +} + +@media (max-width: 1550px) { + #articles { + display: unset; + } + + #articles #journal { + margin-right: unset; + min-width: unset; + width: unset; + } +} diff --git a/feedr.sh b/feedr.sh new file mode 100644 index 0000000..db8aac4 --- /dev/null +++ b/feedr.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +# Check if the correct number of arguments is provided +if [ $# -ne 1 ]; then + echo "Usage: $0 XML_FILE" + exit 1 +fi + +function browser() { + local URL="$1"; + xdg-open $URL || sensible-browser $URL || x-www-browser $URL || gnome-open $URL; +} + + +# Get the XML file and stylesheet file from the arguments +XML_FILE="$1" +XML_FILENAME=$(basename $XML_FILE) + +# Create a temporary directory +TEMPORARY_DIRECTORY="/tmp/feedr" +if [ ! -f "$TEMPORARY_DIRECTORY" ]; then + mkdir $TEMPORARY_DIRECTORY/ + mkdir $TEMPORARY_DIRECTORY/css/ + mkdir $TEMPORARY_DIRECTORY/xsl/ +fi + +# Check whether a custom stylesheet is present +STYLESHEET_DIRECTORY="$HOME/.local/share/feedr" +cp -rf "$STYLESHEET_DIRECTORY/css/" "$TEMPORARY_DIRECTORY/" +cp -rf "$STYLESHEET_DIRECTORY/xsl/" "$TEMPORARY_DIRECTORY/" + +if [ ! -f "$STYLESHEET_DIRECTORY" ]; then + STYLESHEET_DIRECTORY="/usr/share/feedr" +fi + +# Copy stylesheets to temporary directory +cp -rf "$STYLESHEET_DIRECTORY/css/" "$TEMPORARY_DIRECTORY/" +cp -rf "$STYLESHEET_DIRECTORY/xsl/" "$TEMPORARY_DIRECTORY/" + +# Restructure file with xmllint +XML_FILE_TMP="$TEMPORARY_DIRECTORY/$XML_FILENAME.xml" +xmllint --format "$XML_FILE" > "$XML_FILE_TMP" +if ! grep -q xml-stylesheet "$XML_FILE_TMP"; then + sed -i '1a ' "$XML_FILE_TMP" + + # Move modified content back to the original file + #mv "$XML_FILE_TMP" "$XML_FILE" + + # Print a confirmation message + echo "Stylesheet instruction added to $XML_FILE." +fi + +export WEBKIT_DISABLE_DMABUF_RENDERER=1 + +#badwolf "$XML_FILE_TMP" +#chrome --new-window "$XML_FILE_TMP" +#falkon "$XML_FILE_TMP" --new-window +#firefox --new-window "$XML_FILE_TMP" +#luakit "$XML_FILE_TMP" +otter-browser "$XML_FILE_TMP" +qutebrowser "$XML_FILE_TMP" +#xdg-open "$XML_FILE_TMP" diff --git a/xsl/atom_as_xhtml.xsl b/xsl/atom_as_xhtml.xsl new file mode 100644 index 0000000..901737b --- /dev/null +++ b/xsl/atom_as_xhtml.xsl @@ -0,0 +1,536 @@ + + + + + + + + + + + + + + + + + + + + + + + + + <xsl:choose> + <xsl:when test='atom:title and not(atom:title="") and count(atom:entry) > 1'> + <xsl:value-of select='atom:title'/> + </xsl:when> + <xsl:when test='atom:entry'> + <xsl:value-of select='atom:entry/atom:title'/> + </xsl:when> + <xsl:otherwise>StreamBurner</xsl:otherwise> + </xsl:choose> + + + + + + + + +