���ѧۧݧ�ӧ�� �ާ֧ߧ֧էا֧� - ���֧էѧܧ�ڧ��ӧѧ�� - /home/rickpfrv/wiki.craftaro.com/vendor/wikimedia/parsoid/src/Wt2Html/ParserPipelineFactory.php
���ѧ٧ѧ�
<?php declare( strict_types = 1 ); namespace Wikimedia\Parsoid\Wt2Html; use Wikimedia\Assert\Assert; use Wikimedia\Parsoid\Config\Env; use Wikimedia\Parsoid\Core\InternalException; use Wikimedia\Parsoid\DOM\Document; use Wikimedia\Parsoid\Utils\PHPUtils; use Wikimedia\Parsoid\Wt2Html\TreeBuilder\TreeBuilderStage; use Wikimedia\Parsoid\Wt2Html\TT\AttributeExpander; use Wikimedia\Parsoid\Wt2Html\TT\BehaviorSwitchHandler; use Wikimedia\Parsoid\Wt2Html\TT\DOMFragmentBuilder; use Wikimedia\Parsoid\Wt2Html\TT\ExtensionHandler; use Wikimedia\Parsoid\Wt2Html\TT\ExternalLinkHandler; use Wikimedia\Parsoid\Wt2Html\TT\IncludeOnly; use Wikimedia\Parsoid\Wt2Html\TT\LanguageVariantHandler; use Wikimedia\Parsoid\Wt2Html\TT\ListHandler; use Wikimedia\Parsoid\Wt2Html\TT\NoInclude; use Wikimedia\Parsoid\Wt2Html\TT\OnlyInclude; use Wikimedia\Parsoid\Wt2Html\TT\ParagraphWrapper; use Wikimedia\Parsoid\Wt2Html\TT\PreHandler; use Wikimedia\Parsoid\Wt2Html\TT\QuoteTransformer; use Wikimedia\Parsoid\Wt2Html\TT\SanitizerHandler; use Wikimedia\Parsoid\Wt2Html\TT\TemplateHandler; use Wikimedia\Parsoid\Wt2Html\TT\TokenStreamPatcher; use Wikimedia\Parsoid\Wt2Html\TT\WikiLinkHandler; /** * This class assembles parser pipelines from parser stages */ class ParserPipelineFactory { private static $globalPipelineId = 0; private static $stages = [ "Tokenizer" => [ "class" => PegTokenizer::class, ], "TokenTransform2" => [ "class" => TokenTransformManager::class, "transformers" => [ OnlyInclude::class, IncludeOnly::class, NoInclude::class, TemplateHandler::class, ExtensionHandler::class, // Expand attributes after templates to avoid expanding unused branches // No expansion of quotes, paragraphs etc in attributes, as in // PHP parser- up to text/x-mediawiki/expanded only. AttributeExpander::class, // now all attributes expanded to tokens or string // more convenient after attribute expansion WikiLinkHandler::class, ExternalLinkHandler::class, LanguageVariantHandler::class, // This converts dom-fragment-token tokens all the way to DOM // and wraps them in DOMFragment wrapper tokens which will then // get unpacked into the DOM by a dom-fragment unpacker. DOMFragmentBuilder::class ], ], "TokenTransform3" => [ "class" => TokenTransformManager::class, "transformers" => [ TokenStreamPatcher::class, // add <pre>s PreHandler::class, QuoteTransformer::class, // add before transforms that depend on behavior switches // examples: toc generation, edit sections BehaviorSwitchHandler::class, ListHandler::class, SanitizerHandler::class, // Wrap tokens into paragraphs post-sanitization so that // tags that converted to text by the sanitizer have a chance // of getting wrapped into paragraphs. The sanitizer does not // require the existence of p-tags for its functioning. ParagraphWrapper::class ], ], "TreeBuilder" => [ // Build a tree out of the fully processed token stream "class" => TreeBuilderStage::class, ], "DOMPP" => [ // Generic DOM transformer. // This performs a lot of post-processing of the DOM // (Template wrapping, broken wikitext/html detection, etc.) "class" => DOMPostProcessor::class, "processors" => [], ], ]; private static $pipelineRecipes = [ // This pipeline takes wikitext as input and emits a fully // processed DOM as output. This is the pipeline used for // all top-level documents. // Stages 1-5 of the pipeline "text/x-mediawiki/full" => [ "outType" => "DOM", "stages" => [ "Tokenizer", "TokenTransform2", "TokenTransform3", "TreeBuilder", "DOMPP" ] ], // This pipeline takes wikitext as input and emits tokens that // have had all templates, extensions, links, images processed // Stages 1-2 of the pipeline "text/x-mediawiki" => [ "outType" => "Tokens", "stages" => [ "Tokenizer", "TokenTransform2" ] ], // This pipeline takes tokens from the PEG tokenizer and emits // tokens that have had all templates and extensions processed. // Stage 2 of the pipeline "tokens/x-mediawiki" => [ "outType" => "Tokens", "stages" => [ "TokenTransform2" ] ], // This pipeline takes tokens from stage 2 and emits a fully // processed DOM as output. // Stages 3-5 of the pipeline "tokens/x-mediawiki/expanded" => [ "outType" => "DOM", "stages" => [ "TokenTransform3", "TreeBuilder", "DOMPP" ] ], ]; private static $supportedOptions = [ // If true, templates found in content will have its contents expanded 'expandTemplates', // If true, indicates pipeline is processing the expanded content of a // template or its arguments 'inTemplate', // If true, indicates that we are in a <includeonly> context // (in current usage, isInclude === inTemplate) 'isInclude', // The extension tag that is being processed (Ex: ref, references) // (in current usage, only used for native tag implementation) 'extTag', // Extension-specific options 'extTagOpts', // Content being parsed is used in an inline context 'inlineContext', // Are we processing content of attributes? // (in current usage, used for transcluded attr. keys/values) 'attrExpansion' ]; /** @var array */ private $pipelineCache; /** @var Env */ private $env; /** * @param Env $env */ public function __construct( Env $env ) { $this->pipelineCache = []; $this->env = $env; } /** * Default options processing * * @param array $options * @return array */ private function defaultOptions( array $options ): array { // default: not in a template if ( !isset( $options['inTemplate'] ) ) { $options['inTemplate'] = false; } // default: not an include context if ( !isset( $options['isInclude'] ) ) { $options['isInclude'] = false; } // default: wrap templates if ( !isset( $options['expandTemplates'] ) ) { $options['expandTemplates'] = true; } // Catch pipeline option typos foreach ( $options as $k => $v ) { Assert::invariant( in_array( $k, self::$supportedOptions, true ), 'Invalid cacheKey option: ' . $k ); } return $options; } /** * Generic pipeline creation from the above recipes. * * @param string $type * @param string $cacheKey * @param array $options * @return ParserPipeline */ private function makePipeline( string $type, string $cacheKey, array $options ): ParserPipeline { if ( !isset( self::$pipelineRecipes[$type] ) ) { throw new InternalException( 'Unsupported Pipeline: ' . $type ); } $recipe = self::$pipelineRecipes[$type]; $pipeStages = []; $prevStage = null; $recipeStages = $recipe["stages"]; foreach ( $recipeStages as $stageId ) { $stageData = self::$stages[$stageId]; $stage = new $stageData["class"]( $this->env, $options, $stageId, $prevStage ); if ( isset( $stageData["transformers"] ) ) { foreach ( $stageData["transformers"] as $tName ) { $stage->addTransformer( new $tName( $stage, $options ) ); } } elseif ( isset( $stageData["processors"] ) ) { $stage->registerProcessors( $stageData["processors"] ); } $prevStage = $stage; $pipeStages[] = $stage; } return new ParserPipeline( $type, $recipe["outType"], $cacheKey, $pipeStages, $this->env ); } /** * @param string $cacheKey * @param array $options * @return string */ private function getCacheKey( string $cacheKey, array $options ): string { if ( empty( $options['isInclude'] ) ) { $cacheKey .= '::noInclude'; } if ( empty( $options['expandTemplates'] ) ) { $cacheKey .= '::noExpand'; } if ( !empty( $options['inlineContext'] ) ) { $cacheKey .= '::inlineContext'; } if ( !empty( $options['inTemplate'] ) ) { $cacheKey .= '::inTemplate'; } if ( !empty( $options['attrExpansion'] ) ) { $cacheKey .= '::attrExpansion'; } if ( isset( $options['extTag'] ) ) { $cacheKey .= '::' . $options['extTag']; // FIXME: This is not the best strategy. But, instead of // premature complexity, let us see how extensions want to // use this and then figure out what constraints are needed. if ( isset( $options['extTagOpts'] ) ) { $cacheKey .= '::' . PHPUtils::jsonEncode( $options['extTagOpts'] ); } } return $cacheKey; } /** * @param string $src * @return Document */ public function parse( string $src ): Document { $pipe = $this->getPipeline( 'text/x-mediawiki/full' ); $pipe->init( [ 'toplevel' => true, 'frame' => $this->env->topFrame, ] ); // Disable the garbage collector in PHP 7.2 (T230861) if ( gc_enabled() && version_compare( PHP_VERSION, '7.3.0', '<' ) ) { $gcDisabled = true; gc_collect_cycles(); gc_disable(); } else { $gcDisabled = false; } $result = $pipe->parseChunkily( $src, [ 'atTopLevel' => true, // Top-level doc parsing always start in SOL state 'sol' => true, ] ); if ( $gcDisabled ) { gc_enable(); // There's no point running gc_collect_cycles() here, since objects // are not marked for collection while the GC is disabled. The root // buffer will be empty. } return $result->ownerDocument; } /** * Get a pipeline of a given type. Pipelines are cached as they are * frequently created. * * @param string $type * @param array $options These also determine the key under which the * pipeline is cached for reuse. * @return ParserPipeline */ public function getPipeline( string $type, array $options = [] ): ParserPipeline { $options = $this->defaultOptions( $options ); $cacheKey = $this->getCacheKey( $type, $options ); if ( empty( $this->pipelineCache[$cacheKey] ) ) { $this->pipelineCache[$cacheKey] = []; } if ( count( $this->pipelineCache[$cacheKey] ) ) { $pipe = array_pop( $this->pipelineCache[$cacheKey] ); } else { $pipe = $this->makePipeline( $type, $cacheKey, $options ); } // Debugging aid: Assign unique id to the pipeline $pipe->setPipelineId( self::$globalPipelineId++ ); return $pipe; } /** * Callback called by a pipeline at the end of its processing. Returns the * pipeline to the cache. * * @param ParserPipeline $pipe */ public function returnPipeline( ParserPipeline $pipe ): void { $cacheKey = $pipe->getCacheKey(); if ( empty( $this->pipelineCache[$cacheKey] ) ) { $this->pipelineCache[$cacheKey] = []; } if ( count( $this->pipelineCache[$cacheKey] ) < 100 ) { $this->pipelineCache[$cacheKey][] = $pipe; } } }
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | ���֧ߧ֧�ѧ�ڧ� ����ѧߧڧ��: 0.29 |
proxy
|
phpinfo
|
���ѧ����ۧܧ�