padname * * The next A> line assigns an alias for the previously listed file. */ class ScratchpadMap { /** @var array */ protected $map = []; /** * @param string $config */ public function __construct($config) { $this->map = $this->parseConfig((string)$config); } /** * Resolve the given alias to a full file path. * * @param string $alias * @return string * @throws \Exception */ public function resolve($alias) { $alias = trim((string)$alias); if ($alias === '') throw new \Exception('Empty alias'); if (!isset($this->map[$alias])) { throw new \Exception('Unknown scratchpad alias'); } return (string)$this->map[$alias]['path']; } /** * Return the parsed mapping. * * @return array */ public function getMap() { return $this->map; } /** * @param string $config * @return array */ protected function parseConfig($config) { $map = []; $lines = explode("\n", (string)$config); $lastFile = ''; foreach ($lines as $line) { $line = trim($line); if ($line === '') continue; if (str_starts_with($line, 'A>')) { $alias = trim(substr($line, 2)); if ($alias === '' || $lastFile === '') continue; $map[$alias] = [ 'alias' => $alias, 'path' => $lastFile, ]; continue; } // Treat as file path (no trailing slash enforced) $filePath = Path::cleanPath($line, false); if ($filePath === '' || str_ends_with($filePath, '/')) { // Ignore invalid entries; they will not be resolvable $lastFile = ''; continue; } $lastFile = $filePath; } return $map; } }