]> _ Git - fluidbook-toolbox.git/commitdiff
wip #7877 @5
authorVincent Vanwaelscappel <vincent@cubedesigners.com>
Mon, 8 Dec 2025 18:08:15 +0000 (19:08 +0100)
committerVincent Vanwaelscappel <vincent@cubedesigners.com>
Mon, 8 Dec 2025 18:08:15 +0000 (19:08 +0100)
app/Fluidbook/Compiler/Accessibility.php
app/Fluidbook/Compiler/Compiler.php
app/Models/FluidbookPublication.php

index e8a9ebdd889e0303c434abaf4e27d2d0c846a5b0..9c884f14a7a96af55dc3baddcd5e035824c9cff5 100644 (file)
@@ -20,7 +20,7 @@ trait Accessibility
         if ($ext === 'txt') {
             $file = $this->wdir . '/' . $link['to'];
             if (file_exists($file)) {
-                $this->audioDescriptionTextsList[$link['page']] = ['text' => file_get_contents($file)];
+                $this->accessibleTextsList[$link['page']] = ['text' => file_get_contents($file)];
             }
         } else {
             $this->config->set('audiodescription.' . $link['page'], $link['to']);
@@ -30,8 +30,14 @@ trait Accessibility
 
     protected function writeAccessibility()
     {
-        if ($this->fluidbookSettings->audiodescriptionTexts) {
 
+        if ($this->fluidbookSettings->accessible_contents == 'disabled') {
+            return;
+        } else if ($this->fluidbookSettings->accessible_contents == 'docling') {
+            foreach ($this->getFluidbook()->getAccessibleContents('latest', 'html') as $page => $text) {
+                $this->accessibleTextsList[$page] = ['page' => $page, 'text' => $text];
+            }
+        } else if ($this->fluidbookSettings->accessible_contents == 'excel' && $this->fluidbookSettings->audiodescriptionTexts) {
             $file = $this->wdir . '/' . $this->fluidbookSettings->audiodescriptionTexts;
             if (file_exists($file)) {
                 $reader = new Xlsx();
@@ -51,12 +57,12 @@ trait Accessibility
                     if ($voice) {
                         $data['voice'] = $voice;
                     }
-                    $this->audioDescriptionTextsList[$page] = $data;
+                    $this->accessibleTextsList[$page] = $data;
                 }
             }
         }
 
-        foreach ($this->audioDescriptionTextsList as $page => $data) {
+        foreach ($this->accessibleTextsList as $page => $data) {
             $replace = [
                 '`' => "'",
                 '“' => '"',
@@ -71,40 +77,42 @@ trait Accessibility
             $text = str_replace(array_keys($replace), array_values($replace), $text);
             $text = Text::cleanUTF8($text, '');
 
-            $voiceInfos = $data['voice'] ?? $this->fluidbookSettings->audiodescriptionVoice;
-
-            if ($voiceInfos) {
-                $e = explode(':', $voiceInfos);
-
-                if (count($e) === 1) {
-                    $engine = 'azuretts';
-                    $voice = $voiceInfos;
-                } else {
-                    $engine = $e[0];
-                    $voice = $e[1];
-                }
+            if ($this->fluidbookSettings->audiodescription) {
+                $voiceInfos = $data['voice'] ?? $this->fluidbookSettings->audiodescriptionVoice;
 
-                $text = Api::stripNonSSMLTags($text);
-                $hash = hash('sha256', $engine . ':' . $voice . '_^_' . $text);
-                $fname = $hash . '.mp3';
-                $dir = Files::mkdir($this->getFluidbook()->protected_path('audiodescription'));
+                if ($voiceInfos) {
+                    $e = explode(':', $voiceInfos);
 
-                $file = $dir . $fname;
+                    if (count($e) === 1) {
+                        $engine = 'azuretts';
+                        $voice = $voiceInfos;
+                    } else {
+                        $engine = $e[0];
+                        $voice = $e[1];
+                    }
 
-                if (Files::isEmpty($file)) {
-                    if ($engine == 'azuretts') {
-                        $e = explode('/', $voice);
-                        if (count($e) < 2) {
-                            FluidbookHealthIssues::addIssue($this->book_id, FluidbookHealthIssues::TYPE_TTS_VOICE_INVALID, ['voice' => $voice]);
-                            continue;
+                    $ttsText = Api::stripNonSSMLTags($text);
+                    $hash = hash('sha256', $engine . ':' . $voice . '_^_' . $ttsText);
+                    $fname = $hash . '.mp3';
+                    $dir = Files::mkdir($this->getFluidbook()->protected_path('audiodescription'));
+
+                    $file = $dir . $fname;
+
+                    if (Files::isEmpty($file)) {
+                        if ($engine == 'azuretts') {
+                            $e = explode('/', $voice);
+                            if (count($e) < 2) {
+                                FluidbookHealthIssues::addIssue($this->book_id, FluidbookHealthIssues::TYPE_TTS_VOICE_INVALID, ['voice' => $voice]);
+                                continue;
+                            }
+                            $this->_azureTTS($ttsText, $e[0], $e[1], $e[2], $file);
                         }
-                        $this->_azureTTS($text, $e[0], $e[1], $e[2], $file);
                     }
-                }
 
-                if (Files::isNotEmpty($file)) {
-                    $this->config->set('audiodescription.' . $page, $fname);
-                    $this->vdir->copy($file, 'data/audiodescription/' . $fname);
+                    if (Files::isNotEmpty($file)) {
+                        $this->config->set('audiodescription.' . $page, $fname);
+                        $this->vdir->copy($file, 'data/audiodescription/' . $fname);
+                    }
                 }
             }
             $this->accessibleTexts[$page] = $text;
index 93f0b0cd93c611e363ed2bd1c2b635613078d477..74b116276ea64a0af8b043be0da72aaad3fd249d 100644 (file)
@@ -264,7 +264,7 @@ class Compiler extends Base implements CompilerInterface, IVirtualDirectoryError
     public $accessibleTexts = [];
     protected $_svgSymbols = [];
     protected $_addedPDFJS = false;
-    protected $audioDescriptionTextsList = [];
+    protected $accessibleTextsList = [];
     protected $hybrid = false;
     protected $_links;
     protected $_rulers;
index bacbd6c45284145b2f8eb1efe8bcb89ce7318dd3..8e49a6ff07a36d48274397afaee2fa2d4c3a3723 100644 (file)
@@ -3,7 +3,6 @@
 
 namespace App\Models;
 
-use App\Console\Commands\WorkshopMigration;
 use App\Fields\FluidbookChapters;
 use App\Fields\FluidbookComposition;
 use App\Fields\FluidbookExtranetTask;
@@ -52,7 +51,6 @@ use App\Models\Traits\PublicationTags;
 use App\Models\Traits\SCORMVersionTrait;
 use App\Models\Traits\ToolboxSettings;
 use App\Slack\Mattermost;
-use App\Slack\Slack;
 use App\SubForms\Link\Base;
 use Cubedesigners\UserDatabase\Permissions;
 use Cubist\Backpack\Magic\Fields\Checkbox;
@@ -70,9 +68,14 @@ use Cubist\Util\Gzip;
 use Cubist\Util\Json;
 use Cubist\Util\Str;
 use Datetime;
-use Illuminate\Support\Facades\Artisan;
 use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Log;
+use League\CommonMark\Environment\Environment;
+use League\CommonMark\Extension\Autolink\AutolinkExtension;
+use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
+use League\CommonMark\Extension\Table\TableExtension;
+use League\CommonMark\MarkdownConverter;
+use League\CommonMark\Exception\CommonMarkException;
 
 // __('!!Paramètres des fluidbooks')
 class FluidbookPublication extends ToolboxStatusModel
@@ -476,11 +479,15 @@ class FluidbookPublication extends ToolboxStatusModel
         }
     }
 
-    public function getAccessibleContents($revision = 'latest')
+    /**
+     * @throws CommonMarkException
+     */
+    public function getAccessibleContents($revision = 'latest', $format = 'array')
     {
         $base = Files::mkdir($this->protected_path('fluidbookpublication/accessible/' . $this->id . '/'));
         $file = $base . $revision . '.accessible.gz';
         $meta = $base . $revision . '.meta.gz';
+
         if (!file_exists($file)) {
             if ($revision === 'latest') {
                 $json = ['pages' => []];
@@ -499,11 +506,55 @@ class FluidbookPublication extends ToolboxStatusModel
                 copy($file, $base . time() . '.accessible.gz');
                 copy($meta, $base . time() . '.meta.gz');
 
-                return $json;
+                if ($format === 'array') {
+                    return $json;
+                }
             }
-        } else {
-            return json_decode(gzdecode(file_get_contents($file)), true);
         }
+
+        if ($format === 'html') {
+            $htmlFile = $base . '.html.gz';
+            if (!file_exists($htmlFile) || filemtime($htmlFile) < filemtime($file) || filemtime($htmlFile) < filemtime(__FILE__)) {
+                $html = [];
+                if (!isset($json)) {
+                    $json = json_decode(gzdecode(file_get_contents($file)), true);
+                }
+                $config = [
+                    'table' => [
+                        'wrap' => [
+                            'enabled' => false,
+                            'tag' => 'div',
+                            'attributes' => [],
+                        ],
+                        'alignment_attributes' => [
+                            'left' => ['align' => 'left'],
+                            'center' => ['align' => 'center'],
+                            'right' => ['align' => 'right'],
+                        ],
+                    ],
+                ];
+
+                $environment = new Environment($config);
+                $environment->addExtension(new CommonMarkCoreExtension());
+                $environment->addExtension(new TableExtension());
+                $environment->addExtension(new AutolinkExtension());
+
+                $converter = new MarkdownConverter($environment);
+                foreach ($json['pages'] as $page => $markdown) {
+                    $h = $converter->convert($markdown)->getContent();
+                    $h = preg_replace('/<p><img.*<\/p>/U', '', $h);
+                    $h = str_replace("/\n+/", "\n", $h);
+                    $html[$page] = $h;
+                }
+                file_put_contents($htmlFile, gzencode(json_encode($html)));
+
+                return $html;
+            }
+            return json_decode(gzdecode(file_get_contents($htmlFile)), true);
+
+        }
+
+        return json_decode(gzdecode(file_get_contents($file)), true);
     }
 
     public function getPDFSplitSource($page)