diff --git a/assets/main.css b/assets/main.css
index 25463aa..f59bc00 100644
--- a/assets/main.css
+++ b/assets/main.css
@@ -371,6 +371,15 @@ body {
flex-grow: 1;
}
+#sidebar > .menu-container > .menu hr {
+ width: calc(0.66 * calc(var(--sidebar-menu-container-padding-width) + 100%));
+ margin: 0.55rem auto;
+ transform: translate(calc(0px - var(--sidebar-menu-container-padding-width)/2), 0px);
+ height: var(--sidebar-menu-list-seperator-width);
+ border-radius: calc(var(--sidebar-menu-list-seperator-width) / 2);
+ background: var(--color-menu-list-separator);
+}
+
#sidebar > .menu-container > .menu .menu-item {
display: block;
padding: 0.55rem 0;
diff --git a/assets/xsd/book.xsd b/assets/xsd/book.xsd
index f4a2225..d8b0550 100644
--- a/assets/xsd/book.xsd
+++ b/assets/xsd/book.xsd
@@ -1,46 +1,63 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/xsd/bookshelf.xsd b/assets/xsd/bookshelf.xsd
index 4d0cacd..275fa22 100644
--- a/assets/xsd/bookshelf.xsd
+++ b/assets/xsd/bookshelf.xsd
@@ -1,8 +1,8 @@
@@ -13,63 +13,77 @@
+
+
-
+
+
+
+
+
-
+
+
+
+
+
-
+
-
+
-
-
+
+
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
-
+
-
-
+
+
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
-
+
\ No newline at end of file
diff --git a/assets/xsd/configurations.xsd b/assets/xsd/configurations.xsd
index aac2504..9b4597e 100644
--- a/assets/xsd/configurations.xsd
+++ b/assets/xsd/configurations.xsd
@@ -1,30 +1,29 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
diff --git a/constant.php b/constant.php
index 33d702d..d7eecce 100644
--- a/constant.php
+++ b/constant.php
@@ -2,6 +2,6 @@
const APP_NAME = "ph-Bookshelf";
-const VERSION = "0.4.0";
+const VERSION = "0.5.0-alpha1";
const CHANNEL = "suk-ws";
const BRANCH = "master";
diff --git a/src/Element/Book.php b/src/Element/Book.php
index f4d9847..d9b2e7d 100644
--- a/src/Element/Book.php
+++ b/src/Element/Book.php
@@ -20,26 +20,28 @@ class Book {
}
/**
- * @param DOMNode $xmlData
+ * @param DOMNode $bookNode
* @param BookCollection $parent
* @return Book
* @throws Exception
*/
- public static function parse (DOMNode $xmlData, BookCollection $parent): Book {
- if ($xmlData->hasAttributes()) {
- $attrName = $xmlData->attributes->getNamedItem("name");
- $attrId = $xmlData->attributes->getNamedItem("id");
- if ($attrName == null)
- if ($attrId == null) throw new Exception("Book xml data missing attribute \"name\"");
- else throw new Exception("Book xml data with id \"$attrId->nodeValue\" missing attribute \"name\"");
- else $name = $attrName->nodeValue;
- if ($attrId == null) throw new Exception("Book xml data named \"$name\" missing attribute \"id\"");
+ public static function parse (DOMNode $bookNode, BookCollection $parent): Book {
+ if ($bookNode->hasAttributes()) {
+ $attrId = $bookNode->attributes->getNamedItem("id");
+ if ($attrId == null) throw new Exception("an Book xml data named missing attribute \"id\"");
else $id = $attrId->nodeValue;
} else
throw new Exception("Book xml data missing attributes");
- if ($xmlData->hasChildNodes())
- throw new Exception("Book xml with id \"$id\" have some children which are not supported");
- return new Book($id, $name, $parent);
+ $valueName = $bookNode->nodeValue;
+// if ($bookNode->hasChildNodes()) {
+// for ($child = $bookNode->firstChild; $child; $child = $child->nextSibling) {
+// $valueName .= match ($child->nodeName) {
+// "#text", "#cdata-section" => $child->nodeValue,
+// default => throw new Exception("Unsupported element type \"$child->nodeName\" in parsing configuration $bookNode->nodeName")
+// };
+// }
+// } // todo warn if no link name
+ return new Book($id, $valueName, $parent);
}
public function getId (): string {
diff --git a/src/Element/BookCollection.php b/src/Element/BookCollection.php
index 0da485f..e710580 100644
--- a/src/Element/BookCollection.php
+++ b/src/Element/BookCollection.php
@@ -23,23 +23,33 @@ class BookCollection {
}
/**
- * @param DOMNode $root
+ * @param DOMNode $collectionNode
* @param ?BookCollection $parent
* @param bool $isRoot
* @return BookCollection
* @throws Exception
*/
- public static function parse (DOMNode $root, ?BookCollection $parent, bool $isRoot = false): BookCollection {
- $name = BookCollection::ROOT;
+ public static function parse (DOMNode $collectionNode, ?BookCollection $parent, bool $isRoot = false): BookCollection {
+ $collectionName = LinkCollection::ROOT;
+ $child = $collectionNode->firstChild;
+ if ($child == null) throw new Exception("an BookCollection is NULL!");
if (!$isRoot) {
- if ($root->hasAttributes()) {
- $attrName = $root->attributes->getNamedItem("name");
- if ($attrName == null) throw new Exception("BookCollection (not root) xml data missing attribute \"name\"");
- else $name = $attrName->nodeValue;
- } else throw new Exception("BookCollection (not root) xml data missing attributes");
+ while ($child->nodeName != "caption") {
+ switch ($child->nodeName) {
+ case "#comment":
+ break;
+ case "#text":
+ if (empty(trim($child->nodeValue))) break;
+ default:
+ throw new Exception("BookCollection need a \"caption\" as first child but \"$child->nodeName\" found");
+ }
+ $child = $child->nextSibling;
+ }
+ $collectionName = $child->nodeValue;
+ $child = $child->nextSibling;
}
- $node = new BookCollection($name, $parent);
- for ($child = $root->firstChild; $child != null; $child = $child->nextSibling) {
+ $node = new BookCollection($collectionName, $parent);
+ for (; $child != null; $child = $child->nextSibling) {
switch ($child->nodeName) {
case "Book":
$node->array[] = Book::parse($child, $node);
@@ -51,9 +61,9 @@ class BookCollection {
break;
case "#text":
if (empty(trim($child->nodeValue))) break;
- throw new Exception("Unsupported element type \"$child->nodeName\" in BookCollection named \"$name\"");
+ throw new Exception("Unsupported element type \"$child->nodeName\" in BookCollection named \"$collectionName\"");
default:
- throw new Exception("Unsupported element type \"$child->nodeName\" in BookCollection named \"$name\"");
+ throw new Exception("Unsupported element type \"$child->nodeName\" in BookCollection named \"$collectionName\"");
}
}
return $node;
diff --git a/src/Element/BookContent/BookContented.php b/src/Element/BookContent/BookContented.php
index 91da22b..2722bb6 100644
--- a/src/Element/BookContent/BookContented.php
+++ b/src/Element/BookContent/BookContented.php
@@ -44,6 +44,17 @@ class BookContented {
return $node;
}
+ /**
+ * @param DOMNode $rootBookNode
+ * @return BookContented
+ * @throws Exception
+ */
+ public static function parseRootBook (DOMNode $rootBookNode): BookContented {
+ $return = new BookContented("%root", "");
+ $return->childs = Chapter::parse($rootBookNode, null);
+ return $return;
+ }
+
/**
* @param string $xmlContent
* @return BookContented
diff --git a/src/Element/BookContent/Chapter.php b/src/Element/BookContent/Chapter.php
index 10171cd..f0bb3a7 100644
--- a/src/Element/BookContent/Chapter.php
+++ b/src/Element/BookContent/Chapter.php
@@ -28,12 +28,23 @@ class Chapter {
* @throws Exception
*/
public static function parse (DOMNode $xmlData, ?Chapter $parent): Chapter {
- if ($xmlData->hasAttributes()) {
- $attrName = $xmlData->attributes->getNamedItem("name");
- if ($attrName == null) throw new Exception("Chapter xml data missing attribute \"name\"");
- else $node = new Chapter($xmlData->attributes->getNamedItem("name")->nodeValue, array(), $parent);
- } else throw new Exception("Chapter xml data missing attributes");
- for ($child = $xmlData->firstChild;$child != null ; $child = $child->nextSibling) {
+ $child = $xmlData->firstChild;
+ if ($parent != null) {
+ while ($child->nodeName != "caption") {
+ switch ($child->nodeName) {
+ case "#comment":
+ break;
+ case "#text":
+ if (empty(trim($child->nodeValue))) break;
+ default:
+ throw new Exception("Chapter need a \"caption\" as first child but \"$child->nodeName\" found");
+ }
+ $child = $child->nextSibling;
+ }
+ $node = new Chapter($child->nodeValue, array(), $parent);
+ $child = $child->nextSibling;
+ } else $node = new Chapter("", array(), $parent);
+ for (;$child != null ; $child = $child->nextSibling) {
switch ($child->nodeName) {
case "Page":
$node->children[] = Page::parse($child, $node);
@@ -41,6 +52,9 @@ class Chapter {
case "Chapter":
$node->children[] = self::parse($child, $node);
break;
+ case "Separator":
+ $node->children[] = Separator::parse($child, $node);
+ break;
case "#comment":
break;
case "#text":
diff --git a/src/Element/BookContent/Page.php b/src/Element/BookContent/Page.php
index d2118e0..c29ee0d 100644
--- a/src/Element/BookContent/Page.php
+++ b/src/Element/BookContent/Page.php
@@ -23,33 +23,19 @@ class Page {
}
/**
- * @param DOMNode $xmlData
+ * @param DOMNode $pageNode
* @param Chapter $parent
* @return Page
* @throws Exception
*/
- public static function parse (DOMNode $xmlData, Chapter $parent): Page {
- if ($xmlData->hasAttributes()) {
- $attrName = $xmlData->attributes->getNamedItem("name");
- $attrId = $xmlData->attributes->getNamedItem("id");
- if ($attrName == null)
- if ($attrId == null) throw new Exception("Page xml data missing attribute \"name\"");
- else throw new Exception("Page xml data with id \"$attrId->nodeValue\" missing attribute \"name\"");
- else $name = $attrName->nodeValue;
- if ($attrId == null) throw new Exception("Page xml data named \"$name\" missing attribute \"id\"");
+ public static function parse (DOMNode $pageNode, Chapter $parent): Page {
+ if ($pageNode->hasAttributes()) {
+ $attrId = $pageNode->attributes->getNamedItem("id");
+ if ($attrId == null) throw new Exception("an Page xml data missing attribute \"id\"");
else $id = $attrId->nodeValue;
- $node = new Page($id, $name, $parent);
- Bookshelf::parseConfigurationAttr($xmlData->attributes, $node->configurations, array("name", "id"));
} else
throw new Exception("Book xml data missing attributes");
- for ($child = $xmlData->firstChild; $child != null; $child = $child->nextSibling) {
- switch ($child->nodeName) {
- case "#text":
- default:
- throw new Exception("Unsupported element type \"$child->nodeName\" in Page with id $id");
- }
- }
- return $node;
+ return new Page($id, $pageNode->nodeValue, $parent);
}
public function getId (): string {
diff --git a/src/Element/BookContent/Separator.php b/src/Element/BookContent/Separator.php
new file mode 100644
index 0000000..00303c0
--- /dev/null
+++ b/src/Element/BookContent/Separator.php
@@ -0,0 +1,38 @@
+parent = $parent;
+ }
+
+ /**
+ * @throws Exception
+ */
+ public static function parse (DOMNode $xmlData, ?Chapter $parent): Separator {
+ if ($xmlData->hasAttributes() || $xmlData->hasChildNodes())
+ throw new Exception("Separator need be clean with no any attr/children");
+ if ($parent->getParent() != null)
+ throw new Exception("Separator must in root contents path");
+ return new Separator($parent);
+ }
+
+ /**
+ * @return Chapter
+ */
+ public function getParent (): Chapter {
+ return $this->parent;
+ }
+
+ public function getSummaryHtml (): string {
+ return "
";
+ }
+
+}
\ No newline at end of file
diff --git a/src/Element/Bookshelf.php b/src/Element/Bookshelf.php
index c02a232..afe5c6f 100644
--- a/src/Element/Bookshelf.php
+++ b/src/Element/Bookshelf.php
@@ -10,6 +10,8 @@ use Exception;
class Bookshelf {
+ private string $configureVersion;
+
private string $siteName;
private LinkCollection $links;
@@ -32,9 +34,9 @@ class Bookshelf {
if ($dom->hasAttributes() && $dom->hasChildNodes()) {
// Bookshelf 属性
- $attrSiteName = $dom->attributes->getNamedItem("siteName");
- if ($attrSiteName == null) throw new Exception("Bookshelf xml data missing attribute \"siteName\"");
- $return->siteName = $attrSiteName->nodeValue;
+ $attrConfigVersion = $dom->attributes->getNamedItem("version");
+ // todo no version warning
+ $return->configureVersion = $attrConfigVersion->nodeValue;
// 对根节点的子节点进行遍历
for ($rc = $dom->firstChild; $rc != null; $rc = $rc->nextSibling) {
@@ -45,12 +47,15 @@ class Bookshelf {
case "books":
$return->books = BookCollection::parse($rc, null, true);
break;
- case "rootBook":
- $return->rootBook = BookContented::parse($rc);
+ case "root_book":
+ $return->rootBook = BookContented::parseRootBook($rc);
break;
case "configurations":
self::parseConfiguration($rc, $return->configurations);
break;
+ case "site_name":
+ $return->siteName = self::parseSiteName($rc);
+ break;
case "#comment":
break;
case "#text":
@@ -100,6 +105,19 @@ class Bookshelf {
}
}
+ private static function parseSiteName (DOMNode $siteNameNode): string {
+ $siteNameValue = "";
+ for ($child = $siteNameNode->firstChild; $child != null; $child = $child->nextSibling) {
+ $siteNameValue .= match ($child->nodeName) {
+ "#text", "#cdata-section" => $child->nodeValue,
+ default => throw new Exception(
+ "Unsupported element type \"$child->nodeName\" in parsing configuration $siteNameNode->nodeName"
+ ),
+ };
+ }
+ return $siteNameValue;
+ }
+
public function getSiteName (): string {
return $this->siteName;
}
diff --git a/src/Element/Link.php b/src/Element/Link.php
index 11588c5..be7e056 100644
--- a/src/Element/Link.php
+++ b/src/Element/Link.php
@@ -18,26 +18,28 @@ class Link {
}
/**
- * @param DOMNode $xmlData
+ * @param DOMNode $linkNode
* @param LinkCollection $parent
* @return Link
* @throws Exception
*/
- public static function parse (DOMNode $xmlData, LinkCollection $parent): Link {
- if ($xmlData->hasAttributes()) {
- $attrName = $xmlData->attributes->getNamedItem("name");
- $attrHref = $xmlData->attributes->getNamedItem("href");
- if ($attrName == null)
- if ($attrHref == null) throw new Exception("Link xml data missing attribute \"name\"");
- else throw new Exception("Link xml data which href is \"$attrHref->nodeValue\" missing attribute \"name\"");
- else $name = $attrName->nodeValue;
- if ($attrHref == null) throw new Exception("Link xml data named \"$name\" missing attribute \"href\"");
+ public static function parse (DOMNode $linkNode, LinkCollection $parent): Link {
+ if ($linkNode->hasAttributes()) {
+ $attrHref = $linkNode->attributes->getNamedItem("href");
+ if ($attrHref == null) throw new Exception("an Link data missing attribute \"href\"");
else $href = $attrHref->nodeValue;
} else
- throw new Exception("Link xml data missing attributes");
- if ($xmlData->hasChildNodes())
- throw new Exception("Link xml named \"$name\" have some children which are not supported");
- return new Link($name, $href, $parent);
+ throw new Exception("an Link data missing attributes");
+ $valueName = $linkNode->nodeValue;
+// if ($linkNode->hasChildNodes()) {
+// for ($child = $linkNode->firstChild; $child; $child = $child->nextSibling) {
+// $valueName .= match ($child->nodeName) {
+// "#text", "#cdata-section" => $child->nodeValue,
+// default => throw new Exception("Unsupported element type \"$child->nodeName\" in parsing configuration $linkNode->nodeName")
+// };
+// }
+// } // todo warn if no link name
+ return new Link($valueName, $href, $parent);
}
public function getName (): string {
diff --git a/src/Element/LinkCollection.php b/src/Element/LinkCollection.php
index a49ce7d..f4c6411 100644
--- a/src/Element/LinkCollection.php
+++ b/src/Element/LinkCollection.php
@@ -22,23 +22,33 @@ class LinkCollection {
}
/**
- * @param DOMNode $root
+ * @param DOMNode $collectionNode
* @param ?LinkCollection $parent
* @param bool $isRoot
* @return LinkCollection
* @throws Exception
*/
- public static function parse (DOMNode $root, ?LinkCollection $parent, bool $isRoot = false): LinkCollection {
- $name = LinkCollection::ROOT;
+ public static function parse (DOMNode $collectionNode, ?LinkCollection $parent, bool $isRoot = false): LinkCollection {
+ $collectionName = LinkCollection::ROOT;
+ $child = $collectionNode->firstChild;
+ if ($child == null) throw new Exception("an LinkCollection is NULL!");
if (!$isRoot) {
- if ($root->hasAttributes()) {
- $attrName = $root->attributes->getNamedItem("name");
- if ($attrName == null) throw new Exception("LinkCollection (not root) xml data missing attribute \"name\"");
- else $name = $attrName->nodeValue;
- } else throw new Exception("LinkCollection (not root) xml data missing attributes");
+ while ($child->nodeName != "caption") {
+ switch ($child->nodeName) {
+ case "#comment":
+ break;
+ case "#text":
+ if (empty(trim($child->nodeValue))) break;
+ default:
+ throw new Exception("LinkCollection need a \"caption\" as first child but \"$child->nodeName\" found");
+ }
+ $child = $child->nextSibling;
+ }
+ $collectionName = $child->nodeValue;
+ $child = $child->nextSibling;
}
- $node = new LinkCollection($name, $parent);
- for ($child = $root->firstChild; $child != null; $child = $child->nextSibling) {
+ $node = new LinkCollection($collectionName, $parent);
+ for (; $child != null; $child = $child->nextSibling) {
switch ($child->nodeName) {
case "Link":
$node->array[] = Link::parse($child, $node);
@@ -50,9 +60,9 @@ class LinkCollection {
break;
case "#text":
if (empty(trim($child->nodeValue))) break;
- throw new Exception("Unsupported element type \"$child->nodeName\" in LinkCollection named \"$name\"");
+ throw new Exception("Unsupported element type \"$child->nodeName\" in LinkCollection named \"$collectionName\"");
default:
- throw new Exception("Unsupported element type \"$child->nodeName\" in LinkCollection named \"$name\"");
+ throw new Exception("Unsupported element type \"$child->nodeName\" in LinkCollection named \"$collectionName\"");
}
}
return $node;
diff --git a/template/main.php b/template/main.php
index df8c179..6d49a5c 100644
--- a/template/main.php
+++ b/template/main.php
@@ -6,7 +6,7 @@
-
+