mirror of
https://github.com/suk-ws/ph-Bookshelf.git
synced 2024-12-05 09:26:52 +08:00
添加旧标题策略兼容。添加 书架/书目/页面 三级配置读取,为一些兼容化和个性化添加配置标签。
为旧的标题策略做出兼容: 当这个功能开启时,如果输出检测到markdown内没有填入一级标题,则会自动以 book.xml 中声明的页面标题生成一级标题。 添加的配置: - 旧的页面标题策略兼容 : 默认 false,可选 true - 代码块背景色 : 默认跟随样式表fallback,可填任意 css 支持颜色 - 代码块 highlight.js 高亮 : 默认 true,可选 false - highlight.js 主题 : 默认 atom-one-dark,可填任意字符串(但是没有对应主题会无法使用 - 彩虹列表标记效果 : 默认 false,可选 true
This commit is contained in:
parent
3426f7a798
commit
57915682ee
@ -2,6 +2,6 @@
|
|||||||
|
|
||||||
const APP_NAME = "ph-Bookshelf";
|
const APP_NAME = "ph-Bookshelf";
|
||||||
|
|
||||||
const VERSION = "0.3.0.9";
|
const VERSION = "0.3.0.10";
|
||||||
const CHANNEL = "suk-ws";
|
const CHANNEL = "suk-ws";
|
||||||
const BRANCH = "master";
|
const BRANCH = "master";
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once "./src/Data/SiteMeta.php";
|
||||||
require_once "./src/Element/BookContent/BookContented.php";
|
require_once "./src/Element/BookContent/BookContented.php";
|
||||||
require_once "./src/Element/BookContent/Page.php";
|
require_once "./src/Element/BookContent/Page.php";
|
||||||
|
|
||||||
@ -17,4 +18,30 @@ class PageMeta {
|
|||||||
return ""; // todo wip description
|
return ""; // todo wip description
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getConfigurationLevelBook (string $key): ?string {
|
||||||
|
$value = SiteMeta::getConfigurationLevelShelf($key);
|
||||||
|
$valueAttr = self::$book->getConfiguration($key);
|
||||||
|
if ($valueAttr != null) $value = $valueAttr;
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getConfigurationLevelPage (string $key): ?string {
|
||||||
|
$value = self::getConfigurationLevelBook($key);
|
||||||
|
$valueAttr = self::$page->getConfiguration($key);
|
||||||
|
if ($valueAttr != null) $value = $valueAttr;
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function compatibilityOldTitlePolicy (): bool {
|
||||||
|
if (self::getConfigurationLevelPage("compatibility.article.title.oldversion") == "true")
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function highlightJsTheme (): string {
|
||||||
|
$theme = trim(self::getConfigurationLevelPage("customization.article.codeblock.highlightjs.theme"));
|
||||||
|
if (empty($theme)) return "atom-one-dark";
|
||||||
|
return $theme;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once "./src/Data/PageMeta.php";
|
||||||
require_once "./src/Element/Bookshelf.php";
|
require_once "./src/Element/Bookshelf.php";
|
||||||
require_once "./constant.php";
|
require_once "./constant.php";
|
||||||
|
|
||||||
@ -30,33 +31,37 @@ class SiteMeta {
|
|||||||
return "/favicon.ico"; // TODO ICON
|
return "/favicon.ico"; // TODO ICON
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getGitbookStylesheetsList (): array {
|
public static function getStylesheetsList (): array {
|
||||||
return array(
|
return array(
|
||||||
// "/assets/gitbook/style.css",
|
// "/assets/gitbook/style.css",
|
||||||
// "/assets/gitbook/gitbook-plugin-fontsettings/website.css",
|
// "/assets/gitbook/gitbook-plugin-fontsettings/website.css",
|
||||||
// "/assets/gitbook-fix.css",
|
// "/assets/gitbook-fix.css",
|
||||||
// "/assets/ref.css",
|
// "/assets/ref.css",
|
||||||
"//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.3.1/styles/atom-one-dark.min.css",
|
(PageMeta::getConfigurationLevelPage("customization.article.codeblock.highlightjs")=="false"?
|
||||||
|
null:"//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.3.1/styles/".PageMeta::highlightJsTheme().".min.css"),
|
||||||
"/assets/bread-card-markdown.css",
|
"/assets/bread-card-markdown.css",
|
||||||
"/assets/bread-card-markdown-enhanced-listing-rainbow.css",
|
(PageMeta::getConfigurationLevelPage("customization.article.listing.rainbow.marker")=="true"?
|
||||||
|
"/assets/bread-card-markdown-enhanced-listing-rainbow.css":null),
|
||||||
"/assets/bread-card-markdown-compat-highlight-js.css",
|
"/assets/bread-card-markdown-compat-highlight-js.css",
|
||||||
"/assets/main.css",
|
"/assets/main.css",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getGitbookJavascriptList (): array {
|
public static function getJavascriptList (): array {
|
||||||
return array(
|
return array(
|
||||||
// "/assets/gitbook/gitbook.js",
|
// "/assets/gitbook/gitbook.js",
|
||||||
// "/assets/gitbook-fix.js",
|
// "/assets/gitbook-fix.js",
|
||||||
// "https://cdn.jsdelivr.net/npm/marked/marked.min.js",
|
// "https://cdn.jsdelivr.net/npm/marked/marked.min.js",
|
||||||
// "/assets/ref.js",
|
// "/assets/ref.js",
|
||||||
"//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.3.1/highlight.min.js",
|
(PageMeta::getConfigurationLevelPage("customization.article.codeblock.highlightjs")=="false"?
|
||||||
|
null:"//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.3.1/highlight.min.js"),
|
||||||
"/assets/utils-touchscreen-event.js",
|
"/assets/utils-touchscreen-event.js",
|
||||||
"/assets/main.js",
|
"/assets/main.js",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getCustomCssContent (string $id): string {
|
public static function getCustomCssContent (string $id): string {
|
||||||
|
if (!file_exists("./data/$id.css")) return "";
|
||||||
return file_get_contents("./data/$id.css");
|
return file_get_contents("./data/$id.css");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,4 +77,8 @@ class SiteMeta {
|
|||||||
return "font-size-$fontSize font-family-$fontFamily color-theme-$colorTheme";
|
return "font-size-$fontSize font-family-$fontFamily color-theme-$colorTheme";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getConfigurationLevelShelf (string $key): ?string {
|
||||||
|
return self::$BOOKSHELF->getConfiguration($key);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once "./src/Element/Book.php";
|
require_once "./src/Element/Book.php";
|
||||||
|
require_once "./src/Element/Bookshelf.php";
|
||||||
require_once "./src/Element/BookContent/Chapter.php";
|
require_once "./src/Element/BookContent/Chapter.php";
|
||||||
|
|
||||||
class BookContented {
|
class BookContented {
|
||||||
@ -8,6 +9,8 @@ class BookContented {
|
|||||||
private string $id;
|
private string $id;
|
||||||
private string $name;
|
private string $name;
|
||||||
|
|
||||||
|
private array $configurations = array();
|
||||||
|
|
||||||
public function __construct (string $id, string $name) {
|
public function __construct (string $id, string $name) {
|
||||||
$this->id = $id;
|
$this->id = $id;
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
@ -32,6 +35,7 @@ class BookContented {
|
|||||||
else $id = $attrId->nodeValue;
|
else $id = $attrId->nodeValue;
|
||||||
$node = new BookContented($id, $name);
|
$node = new BookContented($id, $name);
|
||||||
$node->childs = Chapter::parse($xmlData, null);
|
$node->childs = Chapter::parse($xmlData, null);
|
||||||
|
Bookshelf::parseConfigurationAttr($xmlData->attributes, $node->configurations, array("name", "id"));
|
||||||
} else
|
} else
|
||||||
throw new Exception("No child or attribute found on BookWithContent");
|
throw new Exception("No child or attribute found on BookWithContent");
|
||||||
return $node;
|
return $node;
|
||||||
@ -71,4 +75,8 @@ class BookContented {
|
|||||||
return $this->childs->getPage($id);
|
return $this->childs->getPage($id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getConfiguration (string $key): ?string {
|
||||||
|
return @$this->configurations[$key];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once "./src/Data/PageMeta.php";
|
require_once "./src/Data/PageMeta.php";
|
||||||
|
require_once "./src/Element/Bookshelf.php";
|
||||||
require_once "./src/Element/BookContent/Chapter.php";
|
require_once "./src/Element/BookContent/Chapter.php";
|
||||||
|
|
||||||
class Page {
|
class Page {
|
||||||
@ -10,6 +11,8 @@ class Page {
|
|||||||
|
|
||||||
private Chapter $parent;
|
private Chapter $parent;
|
||||||
|
|
||||||
|
private array $configurations = array();
|
||||||
|
|
||||||
public function __construct (string $id, string $name, Chapter $parent) {
|
public function __construct (string $id, string $name, Chapter $parent) {
|
||||||
$this->id = $id;
|
$this->id = $id;
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
@ -33,6 +36,7 @@ class Page {
|
|||||||
if ($attrId == null) throw new Exception("Page xml data named \"$name\" missing attribute \"id\"");
|
if ($attrId == null) throw new Exception("Page xml data named \"$name\" missing attribute \"id\"");
|
||||||
else $id = $attrId->nodeValue;
|
else $id = $attrId->nodeValue;
|
||||||
$node = new Page($id, $name, $parent);
|
$node = new Page($id, $name, $parent);
|
||||||
|
Bookshelf::parseConfigurationAttr($xmlData->attributes, $node->configurations, array("name", "id"));
|
||||||
} else
|
} else
|
||||||
throw new Exception("Book xml data missing attributes");
|
throw new Exception("Book xml data missing attributes");
|
||||||
for ($child = $xmlData->firstChild;$child != null ; $child = $child->nextSibling) {
|
for ($child = $xmlData->firstChild;$child != null ; $child = $child->nextSibling) {
|
||||||
@ -57,6 +61,10 @@ class Page {
|
|||||||
return $this->parent;
|
return $this->parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getConfiguration (string $key): ?string {
|
||||||
|
return @$this->configurations[$key];
|
||||||
|
}
|
||||||
|
|
||||||
public function getSummaryHtml (): string {
|
public function getSummaryHtml (): string {
|
||||||
// $str =
|
// $str =
|
||||||
// "<li id='page/$this->id' page-id='$this->id' class='page-contented chapter link-page " .
|
// "<li id='page/$this->id' page-id='$this->id' class='page-contented chapter link-page " .
|
||||||
|
@ -13,6 +13,8 @@ class Bookshelf {
|
|||||||
|
|
||||||
private BookContented $rootBook;
|
private BookContented $rootBook;
|
||||||
|
|
||||||
|
private array $configurations = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $xmlData
|
* @param string $xmlData
|
||||||
* @return Bookshelf
|
* @return Bookshelf
|
||||||
@ -42,6 +44,9 @@ class Bookshelf {
|
|||||||
case "rootBook":
|
case "rootBook":
|
||||||
$return->rootBook = BookContented::parse($rc);
|
$return->rootBook = BookContented::parse($rc);
|
||||||
break;
|
break;
|
||||||
|
case "configurations":
|
||||||
|
self::parseConfiguration($rc, $return->configurations);
|
||||||
|
break;
|
||||||
case "#comment":
|
case "#comment":
|
||||||
break;
|
break;
|
||||||
case "#text":
|
case "#text":
|
||||||
@ -56,6 +61,39 @@ class Bookshelf {
|
|||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static function parseConfiguration(DOMNode $dom, array &$configurations) {
|
||||||
|
for ($rc = $dom->firstChild; $rc != null; $rc = $rc->nextSibling) {
|
||||||
|
if ($rc->nodeName == "#text") {
|
||||||
|
if (!empty(trim($rc->nodeValue)))
|
||||||
|
throw new Exception("Unsupported element type \"$rc->nodeName\" in parsing configurations");
|
||||||
|
else continue;
|
||||||
|
} else if ($rc->nodeName == "#comment") continue;
|
||||||
|
$value = "";
|
||||||
|
for ($rcc = $rc->firstChild; $rcc != null; $rcc = $rcc->nextSibling) {
|
||||||
|
switch ($rcc->nodeName) {
|
||||||
|
case "#text":
|
||||||
|
$value .= trim($rcc->nodeValue);
|
||||||
|
break;
|
||||||
|
case "#comment":
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Unsupported element type \"$rcc->nodeName\" in parsing configuration $rcc->nodeName");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$configurations[$rc->nodeName] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function parseConfigurationAttr (DOMNamedNodeMap $attributes, array &$configurations, array $ignores = array()) {
|
||||||
|
foreach ($attributes as $attr) {
|
||||||
|
if (in_array($attr->name, $ignores)) continue;
|
||||||
|
$configurations[$attr->name] = $attr->value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function getSiteName (): string {
|
public function getSiteName (): string {
|
||||||
return $this->siteName;
|
return $this->siteName;
|
||||||
}
|
}
|
||||||
@ -76,4 +114,8 @@ class Bookshelf {
|
|||||||
return $this->books->getBook($id);
|
return $this->books->getBook($id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getConfiguration (string $key): ?string {
|
||||||
|
return @$this->configurations[$key];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
<?php require_once "./src/Data/SiteMeta.php" ?>
|
<?php require_once "./src/Data/SiteMeta.php" ?>
|
||||||
|
<?php require_once "./src/Data/PageMeta.php" ?>
|
||||||
|
|
||||||
<!-- Gitbook Assets(js) -->
|
<!-- Assets(js) -->
|
||||||
<?php
|
<?php
|
||||||
foreach (SiteMeta::getGitbookJavascriptList() as $item) {
|
foreach (SiteMeta::getJavascriptList() as $item) {
|
||||||
|
if ($item==null) continue;
|
||||||
echo "<script src=\"$item\"></script>";
|
echo "<script src=\"$item\"></script>";
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
@ -10,7 +12,9 @@
|
|||||||
<script>
|
<script>
|
||||||
bookCurrentId = "<?= PageMeta::$book->getId() ?>";
|
bookCurrentId = "<?= PageMeta::$book->getId() ?>";
|
||||||
pageCurrentId = "<?= PageMeta::$page->getId() ?>";
|
pageCurrentId = "<?= PageMeta::$page->getId() ?>";
|
||||||
|
<?php if (!(PageMeta::getConfigurationLevelPage("customization.article.codeblock.highlightjs")=="false")) : ?>
|
||||||
hljs.highlightAll();
|
hljs.highlightAll();
|
||||||
|
<?php endif; ?>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
@ -15,13 +15,19 @@
|
|||||||
<link rel="shortcut icon" href="<?= SiteMeta::getGlobalIcon() ?>">
|
<link rel="shortcut icon" href="<?= SiteMeta::getGlobalIcon() ?>">
|
||||||
<title><?= PageMeta::getPageTitle() ?></title>
|
<title><?= PageMeta::getPageTitle() ?></title>
|
||||||
<meta name="description" content="<?= PageMeta::getDescription() ?>">
|
<meta name="description" content="<?= PageMeta::getDescription() ?>">
|
||||||
<!-- Gitbook Assets(css) -->
|
<!-- Assets(css) -->
|
||||||
<?php
|
<?php
|
||||||
foreach (SiteMeta::getGitbookStylesheetsList() as $item) {
|
foreach (SiteMeta::getStylesheetsList() as $item) {
|
||||||
|
if ($item==null) continue;
|
||||||
echo "<link rel=\"stylesheet\" href=\"$item\">";
|
echo "<link rel=\"stylesheet\" href=\"$item\">";
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<!-- Customs(css) -->
|
<!-- Customs(css) -->
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
----bcm-color-highlight-bg: <?= PageMeta::getConfigurationLevelPage("customization.article.codeblock.background.color") ?>;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<style><?= SiteMeta::getCustomCssContent("custom") ?></style>
|
<style><?= SiteMeta::getCustomCssContent("custom") ?></style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -8,5 +8,19 @@ $parser = new ParsedownExtend();
|
|||||||
$parser->setMarkupEscaped(false);
|
$parser->setMarkupEscaped(false);
|
||||||
$parser->setSafeMode(false);
|
$parser->setSafeMode(false);
|
||||||
|
|
||||||
//echo "<h1 id='phb-page-".PageMeta::$page->getId()."'>".PageMeta::$page->getName()."</h1>\n";
|
$pageMarkdownContent = PageMeta::$page->getMarkdownContent();
|
||||||
echo $parser->text(PageMeta::$page->getMarkdownContent());
|
|
||||||
|
if (PageMeta::compatibilityOldTitlePolicy()) {
|
||||||
|
$length = strlen($pageMarkdownContent);
|
||||||
|
for ($i=0; $i<$length; $i++) {
|
||||||
|
if (empty(trim($pageMarkdownContent[$i]))) {
|
||||||
|
continue;
|
||||||
|
} else if ($pageMarkdownContent[$i] == '#' && $pageMarkdownContent[$i+1] != '#') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
echo "<h1 id='phb-page-".PageMeta::$page->getId()."'>".PageMeta::$page->getName()."</h1>\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo $parser->text($pageMarkdownContent);
|
||||||
|
Loading…
Reference in New Issue
Block a user