Step 1:- Create a blade page
<div class="container">
<div id="back">
<h1>Readability Score</h1>
<br>
<br>
<form action="{{route('read')}}" method="POST">
@csrf
<!-- <input name="inputUrl" class="form-control"> -->
<input type="text" name="inputUrl" class="form-control" placeholder="Enter a Website Url">
<br>
<br>
<button type="submit" id="searchButton">submit</button>
</form>
</div>
@if (\Session::has('success'))
<div class="alert alert-success">
<ul>
<li>{!! \Session::get('success') !!}</li>
</ul>
</div>
@elseif(\Session::has('danger'))
<div class="alert alert-danger">
<ul>
<li>{!! \Session::get('danger') !!}</li>
</ul>
</div>
@endif
<br>
<br>
@if(isset($titleOfThePage))
<p>The title of the page is: <b class="text-success">{{$titleOfThePage}}</b></p>
<p>Excerpt of the page is:
<b>{{ $excerpt}}</b>
</p>
<p>Number of words: <b>{{$wordsCount}}</b></p>
<p>Based on your content of the url, Your Readabilty Score is <b class="text-success"> {{$readabiltyScore}} %</b>
</p>
<div class="container ml-5">
@if($readabiltyScore >= 90)
<div class="single-chart">
<svg viewBox="0 0 36 36" class="circular-chart green">
<path class="circle-bg" d="M18 2.0845
a 15.9155 15.9155 0 0 1 0 31.831
a 15.9155 15.9155 0 0 1 0 -31.831" />
<path class="circle" stroke-dasharray="{{$readabiltyScore}}, 100" d="M18 2.0845
a 15.9155 15.9155 0 0 1 0 31.831
a 15.9155 15.9155 0 0 1 0 -31.831" />
<text x="18" y="20.35" class="percentage">{{$readabiltyScore}}</text>
</svg>
</div>
<h4 class="text-success">Excellent</h4>
@elseif($readabiltyScore >= 75)
<div class="single-chart">
<svg viewBox="0 0 36 36" class="circular-chart orange">
<path class="circle-bg" d="M18 2.0845
a 15.9155 15.9155 0 0 1 0 31.831
a 15.9155 15.9155 0 0 1 0 -31.831" />
<path class="circle" stroke-dasharray="{{$readabiltyScore}}, 100" d="M18 2.0845
a 15.9155 15.9155 0 0 1 0 31.831
a 15.9155 15.9155 0 0 1 0 -31.831" />
<text x="18" y="20.35" class="percentage">{{$readabiltyScore}}</text>
</svg>
</div>
<h4 class="text-info">Very Good</h4>
@elseif($readabiltyScore >= 50)
<div class="single-chart">
<svg viewBox="0 0 36 36" class="circular-chart blue">
<path class="circle-bg" d="M18 2.0845
a 15.9155 15.9155 0 0 1 0 31.831
a 15.9155 15.9155 0 0 1 0 -31.831" />
<path class="circle" stroke-dasharray="{{$readabiltyScore}}, 100" d="M18 2.0845
a 15.9155 15.9155 0 0 1 0 31.831
a 15.9155 15.9155 0 0 1 0 -31.831" />
<text x="18" y="20.35" class="percentage">{{$readabiltyScore}}</text>
</svg>
</div>
<h4 class="text-primary">Good</h4>
@elseif($readabiltyScore < 25) <div class="single-chart">
<svg viewBox="0 0 36 36" class="circular-chart red">
<path class="circle-bg" d="M18 2.0845
a 15.9155 15.9155 0 0 1 0 31.831
a 15.9155 15.9155 0 0 1 0 -31.831" />
<path class="circle" stroke-dasharray="{{$readabiltyScore}}, 100" d="M18 2.0845
a 15.9155 15.9155 0 0 1 0 31.831
a 15.9155 15.9155 0 0 1 0 -31.831" />
<text x="18" y="20.35" class="percentage">{{$readabiltyScore}}</text>
</svg>
</div>
<h4 class="text-danger">Poor</h4>
@endif
</div>
@else
<br>
<br>
<p><strong> Provide a url to check the readabilty score of the page</strong></p>
@endif
</div>
Step 2: Create a route in web.php
Route::post('read', [App\Http\Controllers\ReadabilityController::class, 'read'])->name('read');
Step 3:- Create a Controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use App\Http\Controllers\Controller;
use andreskrey\Readability\Readability;
use andreskrey\Readability\Configuration;
use andreskrey\Readability\ParseException;
use App\CustomClass\ReadabilityAlgorithm;
class ReadabilityController extends Controller
{
public function read(Request $request)
{
// Log::info("Get inside read method");
// Log::info($request);
if($request->inputUrl){
if (filter_var($request->inputUrl, FILTER_VALIDATE_URL) == true) {
$readability = new Readability(new Configuration());
$html = file_get_contents($request->inputUrl);
try {
$readability->parse($html);
$readObj = new ReadabilityAlgorithm();
$titleOfThePage = $readability->getTitle();
$excerpt = $readability->getExcerpt();
log::info('excerpt' . $excerpt);
$totalReadabiltyScore = $readObj->calculateReadabilityScore($readability->getContent());
log::info('totalReadabiltyScore' . $totalReadabiltyScore);
$wordsCount = str_word_count($readability->getContent());
log::info('wordsCount' . $wordsCount);
$readabiltyScore = (int)$totalReadabiltyScore;
log::info('readabiltyScore' . $readabiltyScore);
if($readabiltyScore > 100){
// $readabiltyScore = 95;
return view('welcome',compact('titleOfThePage','excerpt','readabiltyScore','wordsCount'));
}else{
return view('welcome',compact('titleOfThePage','excerpt','readabiltyScore','wordsCount'));
}
} catch (ParseException $e) {
return redirect()->back()->with('danger', 'Sorry! unable to process the url try again');
}
}else{
return redirect()->back()->with('danger', 'Incorrect Url');
}
}else{
return redirect()->back()->with('danger', 'No Url Found');
}
}
}
Step 4:- Create a CustomClass folder in app
ReadabilityAlgorithm.php
<?php
namespace App\CustomClass;
use App\CustomClass\ReadabilitySyllableCheckPattern;
class ReadabilityAlgorithm {
function countSyllable($strWord) {
$pattern = new ReadabilitySyllableCheckPattern();
$strWord = trim($strWord);
// Check for problem words
if (isset($pattern->{'probWords'}[$strWord])) {
return $pattern->{'probWords'}[$strWord];
}
// Check prefix, suffix
$strWord = str_replace($pattern->{'prefixSuffixPatterns'}, '', $strWord, $tmpPrefixSuffixCount);
// Removed non word characters from word
$arrWordParts = preg_split('`[^aeiouy]+`', $strWord);
$wordPartCount = 0;
foreach ($arrWordParts as $strWordPart) {
if ($strWordPart <> '') {
$wordPartCount++;
}
}
$intSyllableCount = $wordPartCount + $tmpPrefixSuffixCount;
// Check syllable patterns
foreach ($pattern->{'subSyllablePatterns'} as $strSyllable) {
$intSyllableCount -= preg_match('`' . $strSyllable . '`', $strWord);
}
foreach ($pattern->{'addSyllablePatterns'} as $strSyllable) {
$intSyllableCount += preg_match('`' . $strSyllable . '`', $strWord);
}
$intSyllableCount = ($intSyllableCount == 0) ? 1 : $intSyllableCount;
return $intSyllableCount;
}
public function calculateReadabilityScore($stringText) {
// Calculate average words per sentence
$total_sentences = 1; // Start with 1 for the first sentence
$punctuation_marks = array('.', '?', '!', ':');
foreach ($punctuation_marks as $punctuation_mark) {
$total_sentences += substr_count($stringText, $punctuation_mark);
}
$total_words = str_word_count($stringText);
$average_words_per_sentence = $total_words / $total_sentences;
// Assuming a value for average syllables per word (you can refine this)
$average_syllables_per_word = 6.5; // Adjust this value based on your content
// Calculate the readability score
$score = 0.39 * $average_words_per_sentence + 11.8 * $average_syllables_per_word - 15.59;
return $score;
}
public function calculateReadabilityPercentage($readabilityScore) {
// Perform linear transformation to convert score to percentage
$minScore = 0; // Minimum readability score
$maxScore = 100; // Maximum readability score (adjust this based on your readability scale)
// Perform the linear transformation
$percentage = (($readabilityScore - $minScore) / ($maxScore - $minScore)) * 100;
// Ensure the percentage is within 0 to 100 range
$percentage = max(0, min(100, $percentage));
return $percentage;
}
}
ReadabilitySyllableCheckPattern.php
<?php
namespace App\CustomClass;
class ReadabilitySyllableCheckPattern {
public $probWords = [
'abalone' => 4,
'abare' => 3,
'abed' => 2,
'abruzzese' => 4,
'abbruzzese' => 4,
'aborigine' => 5,
'acreage' => 3,
'adame' => 3,
'adieu' => 2,
'adobe' => 3,
'anemone' => 4,
'apache' => 3,
'aphrodite' => 4,
'apostrophe' => 4,
'ariadne' => 4,
'cafe' => 2,
'calliope' => 4,
'catastrophe' => 4,
'chile' => 2,
'chloe' => 2,
'circe' => 2,
'coyote' => 3,
'epitome' => 4,
'forever' => 3,
'gethsemane' => 4,
'guacamole' => 4,
'hyperbole' => 4,
'jesse' => 2,
'jukebox' => 2,
'karate' => 3,
'machete' => 3,
'maybe' => 2,
'people' => 2,
'recipe' => 3,
'sesame' => 3,
'shoreline' => 2,
'simile' => 3,
'syncope' => 3,
'tamale' => 3,
'yosemite' => 4,
'daphne' => 2,
'eurydice' => 4,
'euterpe' => 3,
'hermione' => 4,
'penelope' => 4,
'persephone' => 4,
'phoebe' => 2,
'zoe' => 2
];
public $addSyllablePatterns = [
"([^s]|^)ia",
"iu",
"io",
"eo($|[b-df-hj-np-tv-z])",
"ii",
"[ou]a$",
"[aeiouym]bl$",
"[aeiou]{3}",
"[aeiou]y[aeiou]",
"^mc",
"ism$",
"asm$",
"thm$",
"([^aeiouy])\1l$",
"[^l]lien",
"^coa[dglx].",
"[^gq]ua[^auieo]",
"dnt$",
"uity$",
"[^aeiouy]ie(r|st|t)$",
"eings?$",
"[aeiouy]sh?e[rsd]$",
"iell",
"dea$",
"real",
"[^aeiou]y[ae]",
"gean$",
"riet",
"dien",
"uen"
];
public $prefixSuffixPatterns = [
"^un",
"^fore",
"^ware",
"^none?",
"^out",
"^post",
"^sub",
"^pre",
"^pro",
"^dis",
"^side",
"ly$",
"less$",
"some$",
"ful$",
"ers?$",
"ness$",
"cians?$",
"ments?$",
"ettes?$",
"villes?$",
"ships?$",
"sides?$",
"ports?$",
"shires?$",
"tion(ed)?$"
];
public $subSyllablePatterns = [
"cia(l|$)",
"tia",
"cius",
"cious",
"[^aeiou]giu",
"[aeiouy][^aeiouy]ion",
"iou",
"sia$",
"eous$",
"[oa]gue$",
".[^aeiuoycgltdb]{2,}ed$",
".ely$",
"^jua",
"uai",
"eau",
"[aeiouy](b|c|ch|d|dg|f|g|gh|gn|k|l|ll|lv|m|mm|n|nc|ng|nn|p|r|rc|rn|rs|rv|s|sc|sk|sl|squ|ss|st|t|th|v|y|z)e$",
"[aeiouy](b|c|ch|dg|f|g|gh|gn|k|l|lch|ll|lv|m|mm|n|nc|ng|nch|nn|p|r|rc|rn|rs|rv|s|sc|sk|sl|squ|ss|th|v|y|z)ed$",
"[aeiouy](b|ch|d|f|gh|gn|k|l|lch|ll|lv|m|mm|n|nch|nn|p|r|rn|rs|rv|s|sc|sk|sl|squ|ss|st|t|th|v|y)es$",
"^busi$"
];
}
Output :-
Hopefully, It will help you !!!!!