How To Create a Readability Score website Through Laravel

Posted by

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

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