How To Create a Readability Score website Through Laravel

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 !!!!!

Related Posts

The Smart Way to Check Product Availability Near Me Today

Introduction We have all experienced that frustrating moment. You need a specific item urgently—perhaps a replacement cable, a last-minute birthday gift, or a crucial household tool—so you…

Read More

Guiding Global Patients: A Caregiver Approach to Cancer Hospitals

Introduction Supporting a family member through a cancer diagnosis is an emotional and demanding journey for any caregiver. When a loved one faces serious illness, knowing how…

Read More

Navigating Brain Surgery Hospitals, Clinical Teams, and Treatment Paths

When a neurological disorder or intracranial diagnosis enters a family’s life, the immediate emotional response is often accompanied by an overwhelming amount of clinical data. Patients and…

Read More

Secrets of Lost Recipes: Ancient Tastes and Traditions

Every family kitchen holds sensory memories: the rhythmic tapping of a wooden spoon, the sharp crackle of seeds hitting hot oil, or the sweet fragrance of seasonal…

Read More

Top Predictive Maintenance Tools and Strategies for Data Platform Engineering

Introduction Every data engineer knows the frustration of waking up to broken data pipelines, corrupted tables, or an executive dashboard showing blank tiles. Traditionally, data teams discover…

Read More

The Complete Guide to Automating Analytics Pipelines and Workflows

Introduction Picture this scenario: An analyst arrives at work, opens a key executive dashboard, and discovers the numbers are completely outdated because a scheduled data extract failed…

Read More
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x