From: Vincent Vanwaelscappel Date: Mon, 8 Dec 2025 18:08:15 +0000 (+0100) Subject: wip #7877 @5 X-Git-Url: http://git.cubedesigners.com/?a=commitdiff_plain;h=4048b83b1b4ce5aa185ae5b9ae8ac8a654eac94d;p=fluidbook-toolbox.git wip #7877 @5 --- diff --git a/app/Fluidbook/Compiler/Accessibility.php b/app/Fluidbook/Compiler/Accessibility.php index e8a9ebdd8..9c884f14a 100644 --- a/app/Fluidbook/Compiler/Accessibility.php +++ b/app/Fluidbook/Compiler/Accessibility.php @@ -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; diff --git a/app/Fluidbook/Compiler/Compiler.php b/app/Fluidbook/Compiler/Compiler.php index 93f0b0cd9..74b116276 100644 --- a/app/Fluidbook/Compiler/Compiler.php +++ b/app/Fluidbook/Compiler/Compiler.php @@ -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; diff --git a/app/Models/FluidbookPublication.php b/app/Models/FluidbookPublication.php index bacbd6c45..8e49a6ff0 100644 --- a/app/Models/FluidbookPublication.php +++ b/app/Models/FluidbookPublication.php @@ -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('/

/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)