functions.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. <?php
  2. /* Copyright (c) 2019 Geert Bergman (geert@scrivo.nl), highlight.php
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions are met:
  6. *
  7. * 1. Redistributions of source code must retain the above copyright notice,
  8. * this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright notice,
  10. * this list of conditions and the following disclaimer in the documentation
  11. * and/or other materials provided with the distribution.
  12. * 3. Neither the name of "highlight.js", "highlight.php", nor the names of its
  13. * contributors may be used to endorse or promote products derived from this
  14. * software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  17. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  20. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  21. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  22. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  23. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  24. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  25. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  26. * POSSIBILITY OF SUCH DAMAGE.
  27. */
  28. namespace HighlightUtilities;
  29. /**
  30. * Get a list of available stylesheets.
  31. *
  32. * By default, a list of filenames without the `.css` extension will be returned.
  33. * This can be configured with the `$filePaths` argument.
  34. *
  35. * @api
  36. *
  37. * @since 9.15.8.1
  38. *
  39. * @param bool $filePaths Return absolute paths to stylesheets instead
  40. *
  41. * @return string[]
  42. */
  43. function getAvailableStyleSheets($filePaths = false)
  44. {
  45. $results = array();
  46. $folder = getStyleSheetFolder();
  47. $dh = @dir($folder);
  48. if ($dh) {
  49. while (($entry = $dh->read()) !== false) {
  50. if (substr($entry, -4, 4) !== ".css") {
  51. continue;
  52. }
  53. if ($filePaths) {
  54. $results[] = implode(DIRECTORY_SEPARATOR, array($folder, $entry));
  55. } else {
  56. $results[] = basename($entry, ".css");
  57. }
  58. }
  59. $dh->close();
  60. }
  61. return $results;
  62. }
  63. /**
  64. * Get the contents of the given stylesheet.
  65. *
  66. * @api
  67. *
  68. * @since 9.15.8.1
  69. *
  70. * @param string $name The stylesheet name (with or without the extension)
  71. *
  72. * @throws \DomainException when the no stylesheet with this name exists
  73. *
  74. * @return false|string The CSS content of the stylesheet or FALSE when
  75. * the stylesheet content could be read
  76. */
  77. function getStyleSheet($name)
  78. {
  79. $path = getStyleSheetPath($name);
  80. return file_get_contents($path);
  81. }
  82. /**
  83. * Get the absolute path to the folder containing the stylesheets distributed in this package.
  84. *
  85. * @api
  86. *
  87. * @since 9.15.8.1
  88. *
  89. * @return string An absolute path to the folder
  90. */
  91. function getStyleSheetFolder()
  92. {
  93. $paths = array(__DIR__, '..', 'styles');
  94. return implode(DIRECTORY_SEPARATOR, $paths);
  95. }
  96. /**
  97. * Get the absolute path to a given stylesheet distributed in this package.
  98. *
  99. * @api
  100. *
  101. * @since 9.15.8.1
  102. *
  103. * @param string $name The stylesheet name (with or without the extension)
  104. *
  105. * @throws \DomainException when the no stylesheet with this name exists
  106. *
  107. * @return string The absolute path to the stylesheet with the given name
  108. */
  109. function getStyleSheetPath($name)
  110. {
  111. if (substr($name, -4, 4) === ".css") {
  112. $name = preg_replace("/\.css$/", "", $name);
  113. }
  114. $path = implode(DIRECTORY_SEPARATOR, array(getStyleSheetFolder(), $name)) . ".css";
  115. if (!file_exists($path)) {
  116. throw new \DomainException("There is no stylesheet with by the name of '$name'.");
  117. }
  118. return $path;
  119. }
  120. /**
  121. * Convert the HTML generated by Highlighter and split it up into an array of lines.
  122. *
  123. * @api
  124. *
  125. * @since 9.15.6.1
  126. *
  127. * @param string $html An HTML string generated by `Highlighter::highlight()`
  128. *
  129. * @throws \RuntimeException when the DOM extension is not available
  130. * @throws \UnexpectedValueException when the given HTML could not be parsed
  131. *
  132. * @return string[]|false An array of lines of code as strings. False if an error occurred in splitting up by lines
  133. */
  134. function splitCodeIntoArray($html)
  135. {
  136. if (!extension_loaded("dom")) {
  137. throw new \RuntimeException("The DOM extension is not loaded but is required.");
  138. }
  139. $dom = new \DOMDocument();
  140. if (!$dom->loadHTML($html)) {
  141. throw new \UnexpectedValueException("The given HTML could not be parsed correctly.");
  142. }
  143. $spans = $dom->getElementsByTagName("span");
  144. /** @var \DOMElement $span */
  145. foreach ($spans as $span) {
  146. $classes = $span->getAttribute("class");
  147. $renderedSpan = $dom->saveHTML($span);
  148. if (preg_match('/\R/', $renderedSpan)) {
  149. $finished = preg_replace(
  150. '/\R/',
  151. sprintf('</span>%s<span class="%s">', PHP_EOL, $classes),
  152. $renderedSpan
  153. );
  154. $html = str_replace($renderedSpan, $finished, $html);
  155. }
  156. }
  157. return preg_split('/\R/', $html);
  158. }