Example #1
0
 /**
  * @param \nochso\WriteMe\Placeholder\Call $call
  * @param string                           $templateName 'summary', 'short' or 'full'
  */
 public function api(Call $call, $templateName)
 {
     $classes = $this->getClasses($call->getDocument());
     $template = new Template();
     $template->prepare($classes, $call->getDocument()->getFrontmatter());
     $call->replace($template->render($templateName . '.php'));
 }
Example #2
0
 /**
  * @param \nochso\WriteMe\Placeholder\Call $call
  *
  * @return \nochso\WriteMe\Markdown\HeaderContent[]
  */
 private function getHeaderContents(Call $call)
 {
     $changelogPath = $this->findChangelog($call->getDocument());
     $changelog = Document::fromFile($changelogPath);
     $parser = new HeaderParser();
     $headerContentList = $parser->extractHeaderContents($changelog);
     $maxChanges = $this->options->getValue('changelog.max-changes');
     $releaseLevel = $this->options->getValue('changelog.release-level');
     $changes = 0;
     /** @var HeaderContent[] $displayHeaders */
     $displayHeaders = [];
     /** @var HeaderContent $headerContent */
     foreach ($headerContentList->getHeaders() as $headerContent) {
         // This header marks a release
         if ($headerContent->getLevel() === $releaseLevel) {
             $changes++;
             // Stop if we reached the max amount of changes.
             if ($changes > $maxChanges) {
                 break;
             }
             $displayHeaders[] = $headerContent;
         }
         // Keep adding sub-HeaderContent if we're within a release
         if ($changes > 0 && $headerContent->getLevel() > $releaseLevel) {
             $displayHeaders[] = $headerContent;
         }
     }
     return $displayHeaders;
 }
Example #3
0
 public function writemePlaceholderDocs(Call $call)
 {
     $classes = [];
     foreach ($this->placeholders->toArray() as $placeholder) {
         $classes[get_class($placeholder)] = ReflectionClass::createFromInstance($placeholder);
     }
     $template = new TemplateData();
     $template->setHeaderStartLevel($this->options->getValue('placeholder-docs.header-depth'));
     $template->prepare($classes, $this->placeholders);
     $docs = $template->render('full.php');
     $docs = (new Converter())->escape($docs);
     $call->replace($docs);
 }
Example #4
0
 /**
  * Travis CI build status.
  *
  * @param \nochso\WriteMe\Placeholder\Call $call
  * @param string|null                      $userRepository User/repository, e.g. `nochso/writeme`. Defaults to `composer.name`
  * @param string|null                      $branch         Optional branch name.
  */
 public function badgeTravis(Call $call, $userRepository = null, $branch = null)
 {
     if ($userRepository === null) {
         $userRepository = $call->getDocument()->getFrontmatter()->get('composer.name');
     }
     if ($userRepository === null) {
         return;
     }
     $image = sprintf('https://api.travis-ci.org/%s.svg', $userRepository);
     if ($branch !== null) {
         $image .= '?branch=' . $branch;
     }
     $url = 'https://travis-ci.org/' . $userRepository;
     $this->image($call, $image, 'Travis CI build status', $url);
 }
Example #5
0
 /**
  * getMethodsForCall by Call method name and priority.
  *
  * @param \nochso\WriteMe\Placeholder\Call $call
  *
  * @return \nochso\WriteMe\Reflection\Method[] A list of matching methods of this collection.
  */
 public function getMethodsForCall(Call $call)
 {
     $name = $call->getDotName();
     if (!isset($this->methods[$name])) {
         $name = Method::WILDCARD_METHOD_NAME;
     }
     if (!isset($this->methods[$name])) {
         return [];
     }
     $methods = [];
     foreach ($this->methods[$name] as $method) {
         if ($method->hasPriorityOfCall($call)) {
             $methods[] = $method;
         }
     }
     return $methods;
 }
Example #6
0
 /**
  * `@toc.sub@` collects Markdown headers that are **below** the placeholder and on the same or deeper level.
  * If there's a header above the placeholder, its depth will be used as a minimum depth.
  * If there's no header above the placeholder, the first header after the placeholder will be used for the minimum depth.
  * There is currently no maximum depth for `@toc.sub@`.
  *
  * e.g.
  * ```markdown
  * # ignore me
  *
  * @toc.sub@
  * ## sub 1
  * # ignore me again
  * ```
  * is converted into
  *
  * ```markdown
  * # ignore me
  * - [sub 1](#sub-1)
  * ## sub 1
  * # ignore me again
  * ```
  *
  * @param \nochso\WriteMe\Placeholder\Call $call
  * @param int                              $maxDepth How many levels of headers you'd like to keep.
  *                                                   Defaults to zero, meaning all sub-headers are kept.
  */
 public function tocSub(Call $call, $maxDepth = 0)
 {
     $parser = new Markdown\HeaderParser();
     $headerList = $parser->extractHeaders($call->getDocument());
     $lines = Multiline::create($call->getDocument()->getContent());
     $lineIndex = $lines->getLineIndexByCharacterPosition($call->getStartPositionOfRawCall());
     $headers = $headerList->getHeadersBelowLine($lineIndex);
     if ($maxDepth > 0) {
         $minDepth = $this->getMinimumDepth($headers);
         // Filter headers that are relatively too deep
         $headers = array_filter($headers, function (Markdown\Header $header) use($minDepth, $maxDepth) {
             return $header->getLevel() - $minDepth < $maxDepth;
         });
     }
     $toc = $this->formatTOC($headers);
     $call->replace($toc);
 }
Example #7
0
 /**
  * @dataProvider tocSubProvider
  *
  * @param string $input
  * @param string $expected
  */
 public function testTocSub($input, $expected)
 {
     $document = new Document($input);
     $toc = new TOC();
     $toc->prepare($document);
     $call = Call::extractFirstCall($document);
     $toc->tocSub($call);
     $this->assertSame($expected, $document->getContent());
 }
Example #8
0
 public function testWildcard_WhenFrontmatterIsUnknown_MustNotBeReplaced()
 {
     $document = new Document('@foo@');
     $frontmatter = new Frontmatter();
     $call = Call::extractFirstCall($document);
     $frontmatter->wildcard($call);
     $this->assertFalse($call->isReplaced());
     $this->assertSame('@foo@', $document->getContent());
 }
 public function testGetMethodsForCall_SpecificPlaceholdersHavePriorityOverPotentialFrontmatter()
 {
     // Frontmatter must not accidentally replace a @toc@ call even though it *theoretically* would be frontmatter.
     $collection = new PlaceholderCollection([new TOC(), new Frontmatter()]);
     $document = new Document("---\ntoc: foo\n---\n@toc@");
     $call = Call::extractFirstCall($document, Placeholder::PRIORITY_FIRST);
     $methods = $collection->getMethodsForCall($call);
     $this->assertCount(0, $methods);
     $tocCall = Call::extractFirstCall($document, Placeholder::PRIORITY_LAST);
     $methods = $collection->getMethodsForCall($tocCall);
     $this->assertCount(1, $methods);
     $this->assertSame(TOC::class, get_class($methods[0]->getPlaceholder()));
 }
Example #10
0
 public function wildcard(Call $call)
 {
     $path = $call->getIdentifier();
     if ($call->getMethod() !== null) {
         $path .= '.' . $call->getMethod();
     }
     $value = $call->getDocument()->getFrontmatter()->get($path);
     if ($value !== null) {
         $call->replace($value);
     }
 }
Example #11
0
 /**
  * applyPlaceholdersAtPriority by calling only the placeholders that are relevant at a certain priority.
  *
  * @param Document                                          $document     The document to modify.
  * @param int                                               $priority     The priority stage to consider.
  *                                                                        Placeholders are only called when they've
  *                                                                        listed that priority. See
  *                                                                        `Placeholder::getCallPriorities()`
  * @param \nochso\WriteMe\Placeholder\PlaceholderCollection $placeholders
  */
 private function applyPlaceholdersAtPriority(Document $document, $priority, PlaceholderCollection $placeholders)
 {
     $offset = 0;
     $call = Call::extractFirstCall($document, $priority, $offset);
     while ($call !== null) {
         $methods = $placeholders->getMethodsForCall($call);
         $isReplaced = false;
         foreach ($methods as $method) {
             $method->call($call);
             if ($call->isReplaced()) {
                 $isReplaced = true;
                 break;
             }
         }
         if ($isReplaced) {
             // Anything could have changed in content. Start from the beginning.
             $offset = 0;
         } else {
             // The call was skipped by all placeholders. Ignore it at this priority.
             $offset = $call->getEndPositionOfRawCall();
         }
         $call = Call::extractFirstCall($document, $priority, $offset);
     }
 }
Example #12
0
 public function testGetEndPositionOfRawCall()
 {
     $document = new Document('@test@ @test@');
     $call = Call::extractFirstCall($document, Placeholder::PRIORITY_FIRST);
     $this->assertSame(6, $call->getEndPositionOfRawCall());
     $secondCall = Call::extractFirstCall($document, Placeholder::PRIORITY_FIRST, $call->getEndPositionOfRawCall());
     $this->assertSame(13, $secondCall->getEndPositionOfRawCall(), 'End position must be absolute and not be influenced by an offset');
 }
Example #13
0
 /**
  * Call a placeholder method with the Call object and parameters extracted from the raw template call.
  */
 public function call(Call $call)
 {
     $callable = [$this->placeholder, $this->method->getShortName()];
     $params = array_merge([$call], $call->getParameters());
     call_user_func_array($callable, $params);
 }