Compare commits

..
47 Commits
Author SHA1 Message Date
Jérémy BenoistandGitHub 9632c4df8c Merge pull request #61 from j0k3r/github-actions
Ditch Travis to use GitHub Actions
2020-11-30 14:34:46 +01:00
Jeremy Benoist bd9ca1b2cd Ditch Travis to use GitHub Actions 2020-11-30 14:18:40 +01:00
Jérémy BenoistandGitHub 6c917794a7 Merge pull request #60 from jtojnar/patch-1
readability: stop tidy from wrapping noscript text
2020-11-16 12:02:02 +01:00
Jan TojnarandGitHub 7cea79c23a readability: stop tidy from wrapping noscript text
HTML 4.01 Strict only allows block-level elements within noscript, form and
blockquote. The `enclose-block-text` option fixes the instances when those
elements contain inline elements or text by wrapping the children in paragraphs.

HTML 5 has looser content model and allows noscript elements basically anywhere,
including paragraphs, making the noscript elements inherit the parent element’s
content model. This means that tidy will produce invalid HTML nesting paragraphs
for `p > noscript > text`, a structure that would be invalid on two counts
in HTML 4 Strict profile but is completely valid in HTML 5.

Popular WordPress image lazy-loading code produces precisely that structure
so tidy “corrects” it to invalid code. In a proper HTML parser, the produced
code would force close the outer paragraph, making the noscript element
its sibling instead of a child. The only reason this does not break Graby’s code
for stripping the lazy-loading HTML is that libxml2 contains a bug
counteracting this:

https://gitlab.gnome.org/GNOME/libxml2/-/issues/205

Since all three elements allow flow content in HTML 5, it does not make much
sense to enable this option any more. The only possible issues that could occur
is producing HTML code not conforming to 4.01 Strict but that was never guaranteed,
as our example shows, and having blockquotes contain text nodes not wrapped
in paragraphs, which might be expected by some ancient stylesheets
but that is only minor and easily fixable visual backwards incompatibility.
2020-11-14 22:13:53 +01:00
Jérémy BenoistandGitHub c6425cc28b Merge pull request #58 from j0k3r/fix/test-php8
Enable tests for PHP 8
2020-06-08 09:58:28 +02:00
Jeremy Benoist e6ad806460 Enable tests on PHP 8 2020-06-08 09:24:50 +02:00
Jérémy BenoistandGitHub 3fa88461a0 Merge pull request #57 from j0k3r/fix/html5-parser
Use a new deps for HTML5 parser
2020-06-08 07:59:42 +02:00
Jeremy Benoist 6a8ecf232f Use a new deps for HTML5 parser
`electrolinux/php-html5lib` was quite old and incompatible with the upcoming Composer 2.0.
Jumping to `masterminds/html5` for the same result. Also the lib is maintained.

Also:
- keep README in vendors
- use new Scrutinizer engine
- test with lower deps
- remove php-coveralls dev deps and download the phar during the CI build
2020-06-08 07:04:00 +02:00
Jérémy BenoistandGitHub 52b1ddba57 Merge pull request #55 from j0k3r/fix/cleanup-travis
Cleanup travis
2020-04-12 16:38:09 +02:00
Jeremy Benoist 90c625bb57 Cleanup travis 2020-04-12 16:30:02 +02:00
Jérémy BenoistandGitHub 4d1c3b1777 Merge pull request #54 from j0k3r/fix/phpstan
Fix PHPStan (again)
2020-01-06 14:26:41 +01:00
Jeremy Benoist d649b59414 Fixing PHPUnit versions 2020-01-06 14:22:15 +01:00
Jeremy Benoist 44bebfc3d6 Only install PHPStan when we need it
This is to avoid error when installing it on PHP < 7.1
2020-01-06 14:03:30 +01:00
Jeremy Benoist b1acc9ed73 Fix PHPStan (again)
Also cleanup
2019-11-19 14:09:29 +01:00
Jérémy BenoistandGitHub 9306996b47 Merge pull request #53 from j0k3r/openload.co
Add openload.co to media detection
2019-06-25 17:15:37 +02:00
Jeremy Benoist bb75b4f089 Fix PHPStan 2019-06-25 17:06:49 +02:00
Jeremy Benoist 11d2946904 Add openload.co to media detection 2019-06-25 16:54:38 +02:00
Jérémy BenoistandGitHub f808c1b0a2 Merge pull request #50 from j0k3r/fix/non-well-formed-numeric-value
Fix “A non well formed numeric value encountered”
2019-05-11 22:07:19 +02:00
Jeremy Benoist bb65caf864 Fix “A non well formed numeric value encountered” 2019-05-11 21:58:11 +02:00
Jérémy BenoistandGitHub de1b1d9775 Merge pull request #48 from Simounet/feature/out-removed-from-negative
\bout removed from negative content
2019-04-23 10:45:13 +02:00
Simounet 2e20f76195 \bout removed from negative content 2019-04-19 12:12:41 +02:00
Jérémy BenoistandGitHub 3c0289bf89 Merge pull request #46 from j0k3r/phpstan
Enable PHPStan
2019-02-07 16:08:33 +01:00
Jeremy Benoist 74d9cc605a Enable PHPStan 2019-02-07 15:51:31 +01:00
Jérémy BenoistandGitHub 6a0f3337a6 Merge pull request #45 from j0k3r/fix/update-fixer-rules
Update fixer rules
2019-02-04 11:29:55 +01:00
Jeremy Benoist 2dce2879bf Update fixer rules
Following graby, wallabag, etc.
2019-02-04 11:21:34 +01:00
Jérémy BenoistandGitHub 49ce4233fa Merge pull request #42 from Kdecherf/fix-tidy
tidy: use tidy_repair_string instead of tidy_parse_string+tidy_clean_repair
2019-02-04 11:17:13 +01:00
Kevin DecherfandJeremy Benoist 26c881d864 tidy: use tidy_repair_string instead of tidy_parse_string+tidy_clean_repair
A change released in tidy 5.6.0 breaks php-tidy when using
tidy_parse_string+tidy_clean_repair and wrap=0, incorrectly wrapping
every single word. Also it seems that $tidy->value should not be used to
retrieve the repaired html as far as it is undocumented and for internal
use.

We replace the call with tidy_repair_string which directly returns the
repaired string.

Relates to https://github.com/htacg/tidy-html5/issues/673
Relates to https://bugs.php.net/bug.php?id=75947

Tests pass.

Signed-off-by: Kevin Decherf <kevin@kdecherf.com>
2019-02-04 11:08:18 +01:00
Jérémy BenoistandGitHub db69fe59a2 Merge pull request #44 from j0k3r/fix/coveralls-upload
Update path to coveralls bin
2019-02-04 11:08:02 +01:00
Jeremy Benoist a78f01f656 Update path to coveralls bin 2019-02-04 11:01:47 +01:00
Jérémy BenoistandGitHub db4508003b Merge pull request #43 from Kdecherf/composer-bump
Composer bump, php-cs bump to v2, travis update
2019-02-04 10:50:17 +01:00
Kevin Decherf 15b12ea2d6 travis: remove PHP < 5.6 and related stuff, phpcs on 7.2, 7.3 not fail
Signed-off-by: Kevin Decherf <kevin@kdecherf.com>
2019-02-03 16:50:40 +01:00
Kevin Decherf 694f0308fe composer: bump dependencies, move to php-cs v2
Signed-off-by: Kevin Decherf <kevin@kdecherf.com>
2019-02-03 16:49:21 +01:00
Jérémy BenoistandGitHub bbe9021fe7 Merge pull request #36 from Kdecherf/failing-test
tests: fix possible typo in testPostFilters() leading to failure
2018-12-10 12:02:43 +01:00
Jérémy BenoistandGitHub 9dee4a240d Add some badges 2018-11-28 10:05:23 +01:00
Jérémy BenoistandGitHub eef6d6d456 Merge pull request #41 from j0k3r/testing-7.2-7.3
Updating to 7.2
2018-11-26 16:54:20 +01:00
Jeremy Benoist 30a577c617 Dumping HHVM 2018-11-26 16:42:28 +01:00
Jeremy Benoist 70b393a2a3 Remove custom stuff for 7.2 2018-11-26 16:41:42 +01:00
Jeremy Benoist 9ab6d0d9e8 Updating to 7.2 2018-11-26 16:33:38 +01:00
Jérémy BenoistandGitHub 8712db510e Merge pull request #40 from Simounet/giphy-allowed
Giphy added to allowed medias
2018-11-26 16:31:18 +01:00
Simounet 422c74f29c Giphy added to allowed medias 2018-11-20 19:27:41 +01:00
Jérémy BenoistandGitHub ed3393a79f Merge pull request #38 from Simounet/feature/media-added-to-positive
Media class added to positive candidates
2018-06-05 11:54:53 +00:00
Simounet 63cd304dba Media class added to positive candidates
Fix Mediapart images.
2018-06-05 13:26:39 +02:00
Jérémy BenoistandGitHub 43939f88d9 Merge pull request #37 from Kdecherf/footnotes-candidates
Keep elements with 'footnote' as possible candidates
2017-11-03 18:21:40 +02:00
Kevin Decherf 3a7350a8a7 tests: fix possible typo in testPostFilters() leading to failure
Signed-off-by: Kevin Decherf <kevin@kdecherf.com>
2017-11-01 16:46:01 +01:00
Kevin Decherf 4c68cc9f09 Keep elements with 'footnote' as possible candidates
Should fix https://github.com/wallabag/wallabag/issues/3100

Signed-off-by: Kevin Decherf <kevin@kdecherf.com>
2017-11-01 16:45:07 +01:00
Jérémy BenoistandGitHub 276684ab6d Merge pull request #35 from j0k3r/travis
Fix PHP 5.3 builds
2017-10-09 17:16:58 +02:00
Jeremy Benoist 163058aeff Fix PHP 5.3 builds 2017-10-09 16:58:21 +02:00
16 changed files with 1091 additions and 756 deletions
+3 -2
View File
@@ -4,9 +4,10 @@ root = true
; Unix-style newlines
[*]
end_of_line = LF
[*.php]
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
insert_final_newline = true
[.github/**.yml]
indent_size = 2
+2 -1
View File
@@ -4,6 +4,7 @@
/.scrutinizer.yml export-ignore
/.travis.yml export-ignore
/.php_cs export-ignore
/README.md export-ignore
/phpunit.xml.dist export-ignore
/phpstan.neon export-ignore
/.github export-ignore
/tests export-ignore
+53
View File
@@ -0,0 +1,53 @@
name: "CS"
on:
pull_request:
branches:
- master
push:
branches:
- master
env:
SYMFONY_PHPUNIT_VERSION: 7.5
jobs:
coding-standards:
name: "CS Fixer & PHPStan"
runs-on: "ubuntu-18.04"
strategy:
matrix:
php:
- "7.3"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
coverage: "none"
php-version: "${{ matrix.php }}"
tools: cs2pr, composer:v1
ini-values: "date.timezone=Europe/Paris"
env:
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: "Add PHPStan"
run: "composer require phpstan/phpstan phpstan/phpstan-phpunit --dev --no-progress --no-suggest"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v1"
with:
composer-options: "--optimize-autoloader --prefer-dist"
- name: "Run PHP CS Fixer"
run: "php vendor/bin/php-cs-fixer fix --verbose --dry-run --format=checkstyle | cs2pr"
- name: "Install PHPUnit for PHPStan"
run: "php vendor/bin/simple-phpunit install"
- name: "Run PHPStan"
run: "php vendor/bin/phpstan analyse --error-format=checkstyle | cs2pr"
@@ -0,0 +1,202 @@
name: "CI"
on:
pull_request:
branches:
- "master"
push:
branches:
- "master"
env:
fail-fast: true
jobs:
phpunit:
name: "PHPUnit (PHP ${{ matrix.php }})"
runs-on: "ubuntu-18.04"
strategy:
matrix:
php:
- "5.6"
- "7.0"
- "7.1"
- "7.2"
- "7.3"
- "7.4"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
with:
fetch-depth: 2
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
php-version: "${{ matrix.php }}"
coverage: "none"
tools: composer:v1
extensions: tidy
ini-values: "date.timezone=Europe/Paris"
env:
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: "Force PHPUnit version"
if: matrix.php >= '7.2'
run: "echo $SYMFONY_PHPUNIT_VERSION"
env:
SYMFONY_PHPUNIT_VERSION: 7.5
- name: "Remove useless deps"
run: "composer remove friendsofphp/php-cs-fixer --dev --no-progress --no-update"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v1"
with:
composer-options: "--optimize-autoloader --prefer-dist"
- name: "Setup logs"
run: "mkdir -p build/logs"
- name: "Run PHPUnit"
run: "php vendor/bin/simple-phpunit -v"
phpunit-coverage:
name: "PHPUnit coverage (PHP ${{ matrix.php }})"
runs-on: "ubuntu-18.04"
strategy:
matrix:
php:
- "7.4"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
with:
fetch-depth: 2
- name: "Install PHP with Xdebug"
uses: "shivammathur/setup-php@v2"
with:
php-version: "${{ matrix.php }}"
coverage: "xdebug"
tools: composer:v1
extensions: tidy
ini-values: "date.timezone=Europe/Paris"
env:
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: "Remove useless deps"
run: "composer remove friendsofphp/php-cs-fixer --dev --no-progress --no-update"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v1"
with:
composer-options: "--optimize-autoloader --prefer-dist"
- name: "Setup logs"
run: "mkdir -p build/logs"
- name: "Run PHPUnit (with coverage)"
run: "php vendor/bin/simple-phpunit -v --coverage-clover build/logs/clover.xml"
env:
SYMFONY_PHPUNIT_VERSION: 7.5
- name: "Retrieve Coveralls phar"
run: "wget https://github.com/php-coveralls/php-coveralls/releases/download/v2.4.2/php-coveralls.phar"
- name: "Enable Coveralls phar"
run: "chmod +x php-coveralls.phar"
- name: "Upload to Coveralls"
run: "php php-coveralls.phar -v -x build/logs/clover.xml"
env:
COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
phpunit-lowest:
name: "PHPUnit lowest deps (PHP ${{ matrix.php }})"
runs-on: "ubuntu-18.04"
strategy:
matrix:
php:
- "7.2"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
with:
fetch-depth: 2
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
php-version: "${{ matrix.php }}"
coverage: "none"
tools: composer:v1
extensions: tidy
ini-values: "date.timezone=Europe/Paris"
env:
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: "Remove useless deps"
run: "composer remove friendsofphp/php-cs-fixer --dev --no-progress --no-update"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v1"
with:
composer-options: "--optimize-autoloader --prefer-dist"
dependency-versions: "lowest"
- name: "Setup logs"
run: "mkdir -p build/logs"
- name: "Run PHPUnit"
run: "php vendor/bin/simple-phpunit -v"
env:
SYMFONY_PHPUNIT_VERSION: 7.5
phpunit-composerv2:
name: "PHPUnit with Composer v2 (PHP ${{ matrix.php }})"
runs-on: "ubuntu-18.04"
strategy:
matrix:
php:
- "7.4"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
with:
fetch-depth: 2
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
php-version: "${{ matrix.php }}"
coverage: "none"
tools: composer:v2
extensions: tidy
ini-values: "date.timezone=Europe/Paris"
env:
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: "Remove useless deps"
run: "composer remove friendsofphp/php-cs-fixer --dev --no-progress --no-update"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v1"
with:
composer-options: "--optimize-autoloader --prefer-dist"
- name: "Setup logs"
run: "mkdir -p build/logs"
- name: "Run PHPUnit"
run: "php vendor/bin/simple-phpunit -v"
env:
SYMFONY_PHPUNIT_VERSION: 7.5
+1
View File
@@ -2,3 +2,4 @@ vendor/
coverage/
composer.lock
.php_cs.cache
.phpunit.result.cache
+24 -14
View File
@@ -1,20 +1,30 @@
<?php
return Symfony\CS\Config\Config::create()
return PhpCsFixer\Config::create()
->setUsingCache(true)
->level(Symfony\CS\FixerInterface::SYMFONY_LEVEL)
// use default SYMFONY_LEVEL and extra fixers:
->fixers(array(
'concat_with_spaces',
'ordered_use',
'phpdoc_order',
'strict',
'strict_param',
'long_array_syntax',
))
->finder(
Symfony\CS\Finder\DefaultFinder::create()
->setRiskyAllowed(true)
->setRules([
'@Symfony' => true,
'@Symfony:risky' => true,
'array_syntax' => ['syntax' => 'short'],
'combine_consecutive_unsets' => true,
'heredoc_to_nowdoc' => true,
'no_extra_consecutive_blank_lines' => ['break', 'continue', 'extra', 'return', 'throw', 'use', 'parenthesis_brace_block', 'square_brace_block', 'curly_brace_block'],
'no_unreachable_default_argument_value' => true,
'no_useless_else' => true,
'no_useless_return' => true,
'ordered_class_elements' => true,
'ordered_imports' => true,
'php_unit_strict' => false,
'phpdoc_order' => true,
// 'psr4' => true,
'strict_comparison' => true,
'strict_param' => true,
'concat_space' => ['spacing' => 'one'],
])
->setFinder(
PhpCsFixer\Finder::create()
->exclude(['vendor'])
->in(__DIR__)
->exclude(array('vendor'))
)
;
+10
View File
@@ -1,2 +1,12 @@
tools:
external_code_coverage: false
build:
nodes:
analysis:
tests:
override:
- php-scrutinizer-run
environment:
php:
version: 7.2
+16 -35
View File
@@ -1,53 +1,34 @@
dist: xenial
os: linux
language: php
php:
- 5.3.3
- 5.3
- 5.4
- 5.5
- 5.6
- 7.0
- 7.1
- nightly
- hhvm
# avoid double Travis build when the PR is created on upstream
if: |
type = pull_request OR \
branch = master
matrix:
jobs:
include:
- php: 7.0
env: CS_FIXER=run
- php: 8.0
env: SYMFONY_PHPUNIT_VERSION=7.5
fast_finish: true
allow_failures:
- php: hhvm
- php: nightly
- php: 8.0
# faster builds on new travis setup not using sudo
sudo: false
# cache vendor dirs
cache:
directories:
- vendor
- $HOME/.composer/cache
- $HOME/.composer/cache/files
before_install:
- if [ -n "$GH_TOKEN" ]; then composer config github-oauth.github.com ${GH_TOKEN}; fi;
# disable TLS for composer because openssl is disabled for PHP 5.3.3 on travis
# see: https://blog.travis-ci.com/upcoming_ubuntu_11_10_migration/
- if [[ $TRAVIS_PHP_VERSION = 5.3.3 ]]; then composer config -g -- disable-tls true; fi;
- if [[ $TRAVIS_PHP_VERSION = 5.3.3 ]]; then composer config -g -- secure-http false; fi;
# no version compatible with PHP > 7.1
- if [[ $TRAVIS_PHP_VERSION = 7.2.* ]]; then composer remove friendsofphp/php-cs-fixer; fi;
install:
- composer self-update
- if [ "$CS_FIXER" != "run" ]; then composer remove friendsofphp/php-cs-fixer --dev --no-progress --no-update ; fi;
- composer update --prefer-dist --no-progress --no-suggest -o $
- php vendor/bin/simple-phpunit install
before_script:
- composer install --prefer-dist --no-interaction
- mkdir -p build/logs
script:
- mkdir -p build/logs
- php vendor/bin/simple-phpunit -v --coverage-clover build/logs/clover.xml
- if [ "$CS_FIXER" = "run" ]; then php vendor/bin/php-cs-fixer fix --verbose --dry-run ; fi;
after_script:
- php vendor/bin/coveralls -v
- php vendor/bin/simple-phpunit -v
+3
View File
@@ -1,7 +1,10 @@
# Readability
![CI](https://github.com/j0k3r/php-readability/workflows/CI/badge.svg)
[![Build Status](https://travis-ci.org/j0k3r/php-readability.svg?branch=master)](https://travis-ci.org/j0k3r/php-readability)
[![Coverage Status](https://coveralls.io/repos/j0k3r/php-readability/badge.svg?branch=master&service=github)](https://coveralls.io/github/j0k3r/php-readability/?branch=master)
[![Total Downloads](https://poser.pugx.org/j0k3r/php-readability/downloads)](https://packagist.org/packages/j0k3r/php-readability)
[![License](https://poser.pugx.org/j0k3r/php-readability/license)](https://packagist.org/packages/j0k3r/php-readability)
This is an extract of the Readability class from this [full-text-rss](https://github.com/Dither/full-text-rss) fork. It can be defined as a better version of the original [php-readability](https://bitbucket.org/fivefilters/php-readability/overview).
+8 -6
View File
@@ -24,21 +24,23 @@
"role": "Developer (original JS version)"
}],
"require": {
"php": ">=5.3.3",
"php": ">=5.6.0",
"ext-mbstring": "*",
"psr/log": "^1.0",
"electrolinux/php-html5lib": "^0.1.0"
"masterminds/html5": "^2.7"
},
"require-dev": {
"satooshi/php-coveralls": "~0.6",
"friendsofphp/php-cs-fixer": "<2",
"monolog/monolog": "^1.13",
"symfony/phpunit-bridge": "^3.2"
"friendsofphp/php-cs-fixer": "^2.14",
"monolog/monolog": "^1.24|^2.1",
"symfony/phpunit-bridge": "^4.2.3"
},
"suggest": {
"ext-tidy": "Used to clean up given HTML and to avoid problems with bad HTML structure."
},
"autoload": {
"psr-4": { "Readability\\": "src/" }
},
"autoload-dev": {
"psr-4": { "Tests\\Readability\\": "tests/" }
}
}
+13
View File
@@ -0,0 +1,13 @@
parameters:
level: 1
paths:
- src
- tests
# https://github.com/phpstan/phpstan/issues/694#issuecomment-350724288
bootstrapFiles:
- vendor/bin/.phpunit/phpunit-7.5-0/vendor/autoload.php
includes:
- vendor/phpstan/phpstan-phpunit/extension.neon
- vendor/phpstan/phpstan-phpunit/rules.neon
+1 -2
View File
@@ -7,7 +7,6 @@
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="vendor/autoload.php"
>
@@ -27,6 +26,6 @@
</filter>
<!-- <logging>
<log type="coverage-html" target="coverage" title="Readability" charset="UTF-8" yui="true" highlight="true" lowUpperBound="35" highLowerBound="70"/>
<log type="coverage-html" target="coverage" lowUpperBound="35" highLowerBound="70"/>
</logging> -->
</phpunit>
+12 -4
View File
@@ -45,7 +45,7 @@ class JSLikeHTMLElement extends \DOMElement
*/
public function __set($name, $value)
{
if ($name !== 'innerHTML') {
if ('innerHTML' !== $name) {
$trace = debug_backtrace();
trigger_error('Undefined property via __set(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], E_USER_NOTICE);
@@ -109,7 +109,7 @@ class JSLikeHTMLElement extends \DOMElement
*/
public function __get($name)
{
if ($name === 'innerHTML') {
if ('innerHTML' === $name) {
$inner = '';
foreach ($this->childNodes as $child) {
@@ -121,12 +121,20 @@ class JSLikeHTMLElement extends \DOMElement
$trace = debug_backtrace();
trigger_error('Undefined property via __get(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], E_USER_NOTICE);
return;
}
public function __toString()
{
return '[' . $this->tagName . ']';
}
public function getInnerHtml()
{
return $this->__get('innerHTML');
}
public function setInnerHtml($value)
{
return $this->__set('innerHTML', $value);
}
}
+595 -612
View File
File diff suppressed because it is too large Load Diff
+93 -79
View File
@@ -6,22 +6,11 @@ use Monolog\Handler\TestHandler;
use Monolog\Logger;
use Readability\Readability;
class ReadabilityTest extends \PHPUnit_Framework_TestCase
class ReadabilityTest extends \PHPUnit\Framework\TestCase
{
public $logHandler;
public $logger;
private function getReadability($html, $url = null, $parser = 'libxml', $useTidy = true)
{
$readability = new Readability($html, $url, $parser, $useTidy);
$this->logHandler = new TestHandler();
$this->logger = new Logger('test', array($this->logHandler));
$readability->setLogger($this->logger);
return $readability;
}
/**
* @requires extension tidy
*/
@@ -84,8 +73,8 @@ class ReadabilityTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertEmpty($readability->getTitle()->innerHTML);
$this->assertContains('Sorry, Readability was unable to parse this page for content.', $readability->getContent()->innerHTML);
$this->assertEmpty($readability->getTitle()->getInnerHtml());
$this->assertContains('Sorry, Readability was unable to parse this page for content.', $readability->getContent()->getInnerHtml());
}
public function testInitP()
@@ -96,9 +85,9 @@ class ReadabilityTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertContains('<div readability=', $readability->getContent()->innerHTML);
$this->assertEmpty($readability->getTitle()->innerHTML);
$this->assertContains('This is the awesome content :)', $readability->getContent()->innerHTML);
$this->assertContains('<div readability=', $readability->getContent()->getInnerHtml());
$this->assertEmpty($readability->getTitle()->getInnerHtml());
$this->assertContains('This is the awesome content :)', $readability->getContent()->getInnerHtml());
}
public function testInitDivP()
@@ -109,9 +98,9 @@ class ReadabilityTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertContains('<div readability=', $readability->getContent()->innerHTML);
$this->assertEmpty($readability->getTitle()->innerHTML);
$this->assertContains('This is the awesome content :)', $readability->getContent()->innerHTML);
$this->assertContains('<div readability=', $readability->getContent()->getInnerHtml());
$this->assertEmpty($readability->getTitle()->getInnerHtml());
$this->assertContains('This is the awesome content :)', $readability->getContent()->getInnerHtml());
}
public function testInitDiv()
@@ -123,9 +112,9 @@ class ReadabilityTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertContains('<div readability=', $readability->getContent()->innerHTML);
$this->assertEmpty($readability->getTitle()->innerHTML);
$this->assertContains('This is the awesome content :)', $readability->getContent()->innerHTML);
$this->assertContains('<div readability=', $readability->getContent()->getInnerHtml());
$this->assertEmpty($readability->getTitle()->getInnerHtml());
$this->assertContains('This is the awesome content :)', $readability->getContent()->getInnerHtml());
}
public function testWithFootnotes()
@@ -138,11 +127,11 @@ class ReadabilityTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertContains('<div readability=', $readability->getContent()->innerHTML);
$this->assertEmpty($readability->getTitle()->innerHTML);
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->innerHTML);
$this->assertContains('readabilityFootnoteLink', $readability->getContent()->innerHTML);
$this->assertContains('readabilityLink-3', $readability->getContent()->innerHTML);
$this->assertContains('<div readability=', $readability->getContent()->getInnerHtml());
$this->assertEmpty($readability->getTitle()->getInnerHtml());
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
$this->assertContains('readabilityFootnoteLink', $readability->getContent()->getInnerHtml());
$this->assertContains('readabilityLink-3', $readability->getContent()->getInnerHtml());
}
public function testStandardClean()
@@ -155,11 +144,11 @@ class ReadabilityTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertContains('<div readability=', $readability->getContent()->innerHTML);
$this->assertEmpty($readability->getTitle()->innerHTML);
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->innerHTML);
$this->assertContains('will NOT be removed', $readability->getContent()->innerHTML);
$this->assertNotContains('<h2>', $readability->getContent()->innerHTML);
$this->assertContains('<div readability=', $readability->getContent()->getInnerHtml());
$this->assertEmpty($readability->getTitle()->getInnerHtml());
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
$this->assertContains('will NOT be removed', $readability->getContent()->getInnerHtml());
$this->assertNotContains('<h2>', $readability->getContent()->getInnerHtml());
}
public function testWithIframe()
@@ -171,10 +160,10 @@ class ReadabilityTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertContains('<div readability=', $readability->getContent()->innerHTML);
$this->assertEmpty($readability->getTitle()->innerHTML);
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->innerHTML);
$this->assertContains('nofollow', $readability->getContent()->innerHTML);
$this->assertContains('<div readability=', $readability->getContent()->getInnerHtml());
$this->assertEmpty($readability->getTitle()->getInnerHtml());
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
$this->assertContains('nofollow', $readability->getContent()->getInnerHtml());
}
public function testWithArticle()
@@ -186,10 +175,10 @@ class ReadabilityTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertContains('alt="article"', $readability->getContent()->innerHTML);
$this->assertEmpty($readability->getTitle()->innerHTML);
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->innerHTML);
$this->assertContains('nofollow', $readability->getContent()->innerHTML);
$this->assertContains('alt="article"', $readability->getContent()->getInnerHtml());
$this->assertEmpty($readability->getTitle()->getInnerHtml());
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
$this->assertContains('nofollow', $readability->getContent()->getInnerHtml());
}
public function testWithAside()
@@ -201,10 +190,10 @@ class ReadabilityTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertEmpty($readability->getTitle()->innerHTML);
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->innerHTML);
$this->assertNotContains('<aside>', $readability->getContent()->innerHTML);
$this->assertContains('<footer readability="4"/>', $readability->getContent()->innerHTML);
$this->assertEmpty($readability->getTitle()->getInnerHtml());
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
$this->assertNotContains('<aside>', $readability->getContent()->getInnerHtml());
$this->assertContains('<footer readability="5"/>', $readability->getContent()->getInnerHtml());
}
public function testWithClasses()
@@ -216,10 +205,10 @@ class ReadabilityTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertContains('alt="article"', $readability->getContent()->innerHTML);
$this->assertEmpty($readability->getTitle()->innerHTML);
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->innerHTML);
$this->assertNotContains('This text should be removed', $readability->getContent()->innerHTML);
$this->assertContains('alt="article"', $readability->getContent()->getInnerHtml());
$this->assertEmpty($readability->getTitle()->getInnerHtml());
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
$this->assertNotContains('This text should be removed', $readability->getContent()->getInnerHtml());
}
public function testWithClassesWithoutLightClean()
@@ -232,10 +221,10 @@ class ReadabilityTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertContains('alt="article"', $readability->getContent()->innerHTML);
$this->assertEmpty($readability->getTitle()->innerHTML);
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->innerHTML);
$this->assertNotContains('This text should be removed', $readability->getContent()->innerHTML);
$this->assertContains('alt="article"', $readability->getContent()->getInnerHtml());
$this->assertEmpty($readability->getTitle()->getInnerHtml());
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
$this->assertNotContains('This text should be removed', $readability->getContent()->getInnerHtml());
}
public function testWithTd()
@@ -247,8 +236,8 @@ class ReadabilityTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertEmpty($readability->getTitle()->innerHTML);
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->innerHTML);
$this->assertEmpty($readability->getTitle()->getInnerHtml());
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
}
public function testWithSameClasses()
@@ -260,9 +249,9 @@ class ReadabilityTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertEmpty($readability->getTitle()->innerHTML);
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->innerHTML);
$this->assertContains('This text is also an awesome text and you should know that', $readability->getContent()->innerHTML);
$this->assertEmpty($readability->getTitle()->getInnerHtml());
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
$this->assertContains('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
}
public function testWithScript()
@@ -274,9 +263,9 @@ class ReadabilityTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertEmpty($readability->getTitle()->innerHTML);
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->innerHTML);
$this->assertNotContains('This text is also an awesome text and you should know that', $readability->getContent()->innerHTML);
$this->assertEmpty($readability->getTitle()->getInnerHtml());
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
$this->assertNotContains('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
}
public function testTitle()
@@ -288,9 +277,9 @@ class ReadabilityTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertEquals('this is my title', $readability->getTitle()->innerHTML);
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->innerHTML);
$this->assertNotContains('This text is also an awesome text and you should know that', $readability->getContent()->innerHTML);
$this->assertEquals('this is my title', $readability->getTitle()->getInnerHtml());
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
$this->assertNotContains('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
}
public function testTitleWithDash()
@@ -302,9 +291,9 @@ class ReadabilityTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertEquals('title2 - title3', $readability->getTitle()->innerHTML);
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->innerHTML);
$this->assertNotContains('This text is also an awesome text and you should know that', $readability->getContent()->innerHTML);
$this->assertEquals('title2 - title3', $readability->getTitle()->getInnerHtml());
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
$this->assertNotContains('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
}
public function testTitleWithDoubleDot()
@@ -316,9 +305,9 @@ class ReadabilityTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertEquals('title2 : title3', $readability->getTitle()->innerHTML);
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->innerHTML);
$this->assertNotContains('This text is also an awesome text and you should know that', $readability->getContent()->innerHTML);
$this->assertEquals('title2 : title3', $readability->getTitle()->getInnerHtml());
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
$this->assertNotContains('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
}
public function testTitleTooShortUseH1()
@@ -330,9 +319,9 @@ class ReadabilityTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertEquals('this is my h1 title !', $readability->getTitle()->innerHTML);
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->innerHTML);
$this->assertNotContains('This text is also an awesome text and you should know that', $readability->getContent()->innerHTML);
$this->assertEquals('this is my h1 title !', $readability->getTitle()->getInnerHtml());
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
$this->assertNotContains('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
}
// dummy function to be used to the next test
@@ -345,7 +334,7 @@ class ReadabilityTest extends \PHPUnit_Framework_TestCase
{
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', true);
set_error_handler(array($this, 'error2Exception'), E_ALL | E_STRICT);
set_error_handler([$this, 'error2Exception'], E_ALL | E_STRICT);
$data = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="ru-RU" prefix="og: http://ogp.me/ns#">
@@ -380,8 +369,8 @@ class ReadabilityTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertContains('<iframe src="https://www.youtube.com/embed/PUep6xNeKjA" width="560" height="315" frameborder="0" allowfullscreen="allowfullscreen"> </iframe>', $readability->getContent()->innerHTML);
$this->assertContains('3D Touch', $readability->getTitle()->innerHTML);
$this->assertContains('<iframe src="https://www.youtube.com/embed/PUep6xNeKjA" width="560" height="315" frameborder="0" allowfullscreen="allowfullscreen"> </iframe>', $readability->getContent()->getInnerHtml());
$this->assertContains('3D Touch', $readability->getTitle()->getInnerHtml());
}
/**
@@ -445,13 +434,13 @@ class ReadabilityTest extends \PHPUnit_Framework_TestCase
public function testPostFilters()
{
$readability = $this->getReadability('<div>' . str_repeat('<p>This <b>is</b> the awesome content :)</p>', 10) . '</div>', 'http://0.0.0.0');
$readability = $this->getReadability('<div>' . str_repeat('<p>This <strong>is</strong> the awesome content :)</p>', 10) . '</div>', 'http://0.0.0.0');
$readability->addPostFilter('!<strong[^>]*>(.*?)</strong>!is', '');
$res = $readability->init();
$this->assertTrue($res);
$this->assertContains('This the awesome content :)', $readability->getContent()->innerHTML);
$this->assertContains('This the awesome content :)', $readability->getContent()->getInnerHtml());
}
public function testPreFilters()
@@ -464,7 +453,7 @@ class ReadabilityTest extends \PHPUnit_Framework_TestCase
$res = $readability->init();
$this->assertTrue($res);
$this->assertContains('This the awesome and WONDERFUL content :)', $readability->getContent()->innerHTML);
$this->assertContains('This the awesome and WONDERFUL content :)', $readability->getContent()->getInnerHtml());
}
public function testChildNodeGoneNull()
@@ -479,4 +468,29 @@ class ReadabilityTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($res);
}
public function testKeepFootnotes()
{
// from https://www.schreibdichte.de/blog/feed-aggregator-und-spaeter-lesen-dienst-im-team
$html = file_get_contents('tests/fixtures/keepFootnotes.html');
$readability = $this->getReadability($html, 'http://0.0.0.0');
$readability->debug = true;
$res = $readability->init();
$this->assertTrue($res);
$this->assertContains('<sup id="fnref1:fnfeed_2"><a href="#fn:fnfeed_2" class="footnote-ref">2</a></sup>', $readability->getContent()->getInnerHtml());
$this->assertContains('<a href="#fnref1:fnfeed_2" rev="footnote"', $readability->getContent()->getInnerHtml());
}
private function getReadability($html, $url = null, $parser = 'libxml', $useTidy = true)
{
$readability = new Readability($html, $url, $parser, $useTidy);
$this->logHandler = new TestHandler();
$this->logger = new Logger('test', [$this->logHandler]);
$readability->setLogger($this->logger);
return $readability;
}
}
+54
View File
@@ -0,0 +1,54 @@
<article>
<h1>Feed-Aggregator und Sp&auml;ter-Lesen-Dienst im Team</h1>
<figure>
<img src="https://www.schreibdichte.de/content/1-blog/20170505-feed-aggregator-und-spaeter-lesen-dienst-im-team/workflow.png" alt="Feed-Aggregator und Sp&auml;ter-Lesen-Dienst im Team" >
</figure>
<time datetime="2017-05-05T18:40:00+00:00" >05.05.2017</time>
<p> <span class="tag">Tags:</span>
<ul class="tag_list">
<li><a href="https://www.schreibdichte.de/blog/tag:Software">Software</a></li>
<li><a href="https://www.schreibdichte.de/blog/tag:Web">Web</a></li>
<li><a href="https://www.schreibdichte.de/blog/tag:Tools">Tools</a></li>
</ul>
<p>
<div class="content">
<p>Dank einer Mitteilung <sup id="fnref1:fnfeed_1"><a href="#fn:fnfeed_1" class="footnote-ref">1</a></sup> im OSBN <sup id="fnref1:fnfeed_2"><a href="#fn:fnfeed_2" class="footnote-ref">2</a></sup>, bin ich auf den Feed-Aggregator Miniflux <sup id="fnref1:fnfeed_3"><a href="#fn:fnfeed_3" class="footnote-ref">3</a></sup> aufmerksam geworden. Ich hatte schon lange nach einer Alternative zu Fever <sup id="fnref1:fnfeed_4"><a href="#fn:fnfeed_4" class="footnote-ref">4</a></sup> gesucht, da der Anschein vorlag, dass die Entwicklung nicht mehr weiter ging. Was sich bestätigte.</p>
<p>Miniflux ist prima, einfach gehalten und erledigt genau dass, was es machen soll. Zudem wird die Fever-API unterstützt, was bedeutet, dass ich weiterhin meine Feed-Reader nutzen kann, was den Dialog mit Miniflux auf dem Server betrifft. Das ist deshalb interessant, um den Lesestatus oder das Favorisieren von Feeds zentral auf dem Server zu berücksichtigen und nicht lokal. So habe ich sowohl auf dem lokalen Rechner, als auch auf allen mobilen Geräten den gleichen Stand und Status meiner abonnierten Feeds.</p>
<p>Für das spätere Lesen von Webseiten, nutze ich seit längerem wallabag <sup id="fnref1:fnfeed_5"><a href="#fn:fnfeed_5" class="footnote-ref">5</a></sup>. Wallabag wird mit Inhalten über den Browser gefüttert. Die Webseiten werden bei der Konservierung von Werbung befreit, damit der reine Text vorliegt. Bilder dagegen nicht und gehen evtl. verloren, wenn es die Quelle mal nicht mehr geben sollte. Ich habe also zwei Orte, an denen Informationen gehalten werden. Miniflux zur Verwaltung von Feed-Nachrichten und Wallabag für Webseiten.</p>
<p>Bei einem Update von Miniflux ist mit aufgefallen, dass es nun eine API für Wallabag gibt. Dabei werden alle gespeicherten Feeds von Miniflux an Wallabag übergeben. Eine prima Angelegenheit, da ich jetzt nur noch einen Topf habe, woraus ich meine gesammelten Informationen aus dem Netz entnehme.</p>
<p>Miniflux als auch wallabag sind selbst gehostete Web-Applikationen, die auch über den Browser erreichbar sind. Native wallabag-Apps für iOS bzw. Android werden ebenfalls angeboten. Wallabag bietet zusätzlich einen Feed an, um die gesammelten Informationen per Feed-Reader zu lesen. Hierbei drängt sich evtl. die Idee auf, diesen Feed wieder in Miniflux zu abonnieren, da dann zentral alles aus verschiedenen Quellen vorliegt. Hier hätten wir allerdings eine gewisse Redundanz.</p>
<p>Ich nutze seit ein paar Monaten Devonthink <sup id="fnref1:fnfeed_6"><a href="#fn:fnfeed_6" class="footnote-ref">6</a></sup> auf dem Mac. Das ist eine lokale Dokumentenverwaltung (DMS), die heute u.a. meine Bücher, Notizen und mein Mail-Archiv verwaltet und ihre Stärke u.a. in der Suche von Informationen hat. Devonthink versteht es auch Feeds zu abonnieren. Für mich war dies der Moment, nun den Feed von wallabag mit all meinen gespeicherten Informationen aus dem Web mit zu integrieren. Ich muss sagen, eine runde Lösung, denn jetzt habe ich für die lokale Suche und das Lesen eine zentrale Stelle.</p>
<p>Die Grafik veranschaulicht das Teamplay zwischen Feed-Aggregator Miniflux und wallabag als Später-Lesen-Dienst, zusammengeführt in Devonthink. Ich kenne leider keine Dokumentenverwaltung für Linux oder Windows, die auch Feeds versteht. Wer etwas kennt, bitte melden. Wer zudem etwas zum Thema hören möchte, für dem ist ggf. die Podcast-Folge &quot;Der eigene Workflow&quot; <sup id="fnref1:fnfeed_7"><a href="#fn:fnfeed_7" class="footnote-ref">7</a></sup> interessant.</p>
<div class="footnotes">
<hr />
<ol>
<li id="fn:fnfeed_1">
<p>Artikel zu Miniflux: <a href="Link"><a href="https://www.robbinaer.info/index.php?post/78">https://www.robbinaer.info/index.php?post/78</a></a>&#160;<a href="#fnref1:fnfeed_1" rev="footnote" class="footnote-backref">&#8617;</a></p>
</li>
<li id="fn:fnfeed_2">
<p>OSBN: <a href="Link"><a href="https://osbn.de">https://osbn.de</a></a>&#160;<a href="#fnref1:fnfeed_2" rev="footnote" class="footnote-backref">&#8617;</a></p>
</li>
<li id="fn:fnfeed_3">
<p>Miniflux: <a href="Link"><a href="https://miniflux.net">https://miniflux.net</a></a>&#160;<a href="#fnref1:fnfeed_3" rev="footnote" class="footnote-backref">&#8617;</a></p>
</li>
<li id="fn:fnfeed_4">
<p>Fever: <a href="Link"><a href="https://feedafever.com">https://feedafever.com</a></a>&#160;<a href="#fnref1:fnfeed_4" rev="footnote" class="footnote-backref">&#8617;</a></p>
</li>
<li id="fn:fnfeed_5">
<p>wallabag: <a href="Link"><a href="https://wallabag.org/de">https://wallabag.org/de</a></a>&#160;<a href="#fnref1:fnfeed_5" rev="footnote" class="footnote-backref">&#8617;</a></p>
</li>
<li id="fn:fnfeed_6">
<p>Devonthink: <a href="Link"><a href="http://www.devontechnologies.com/de/produkte/devonthink/ueberblick.html">http://www.devontechnologies.com/de/produkte/devonthink/ueberblick.html</a></a>&#160;<a href="#fnref1:fnfeed_6" rev="footnote" class="footnote-backref">&#8617;</a></p>
</li>
<li id="fn:fnfeed_7">
<p>Podcast MacMittwoch: <a href="Link"><a href="https://itunes.apple.com/de/podcast/macmittwoch/id1212750085?mt=2ueberblick.html">https://itunes.apple.com/de/podcast/macmittwoch/id1212750085?mt=2ueberblick.html</a></a>&#160;<a href="#fnref1:fnfeed_7" rev="footnote" class="footnote-backref">&#8617;</a></p>
</li>
</ol>
</div></div>
</article>