diff options
Diffstat (limited to 'Userland/Libraries/LibManual')
-rw-r--r-- | Userland/Libraries/LibManual/CMakeLists.txt | 7 | ||||
-rw-r--r-- | Userland/Libraries/LibManual/Node.h | 30 | ||||
-rw-r--r-- | Userland/Libraries/LibManual/PageNode.cpp | 29 | ||||
-rw-r--r-- | Userland/Libraries/LibManual/PageNode.h | 38 | ||||
-rw-r--r-- | Userland/Libraries/LibManual/SectionNode.cpp | 62 | ||||
-rw-r--r-- | Userland/Libraries/LibManual/SectionNode.h | 65 |
6 files changed, 231 insertions, 0 deletions
diff --git a/Userland/Libraries/LibManual/CMakeLists.txt b/Userland/Libraries/LibManual/CMakeLists.txt new file mode 100644 index 0000000000..13f0454acb --- /dev/null +++ b/Userland/Libraries/LibManual/CMakeLists.txt @@ -0,0 +1,7 @@ +set(SOURCES + PageNode.cpp + SectionNode.cpp +) + +serenity_lib(LibManual manual) +target_link_libraries(LibManual PRIVATE LibCore) diff --git a/Userland/Libraries/LibManual/Node.h b/Userland/Libraries/LibManual/Node.h new file mode 100644 index 0000000000..232a7c3094 --- /dev/null +++ b/Userland/Libraries/LibManual/Node.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org> + * Copyright (c) 2022, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <AK/NonnullRefPtrVector.h> +#include <AK/RefCounted.h> +#include <AK/String.h> +#include <AK/StringView.h> + +namespace Manual { + +class PageNode; + +class Node : public RefCounted<Node> { +public: + virtual ~Node() = default; + + virtual NonnullRefPtrVector<Node>& children() const = 0; + virtual Node const* parent() const = 0; + virtual String name() const = 0; + virtual bool is_page() const { return false; } + virtual bool is_open() const { return false; } +}; + +} diff --git a/Userland/Libraries/LibManual/PageNode.cpp b/Userland/Libraries/LibManual/PageNode.cpp new file mode 100644 index 0000000000..0b44ee97c0 --- /dev/null +++ b/Userland/Libraries/LibManual/PageNode.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org> + * Copyright (c) 2022, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "PageNode.h" +#include "SectionNode.h" + +namespace Manual { + +Node const* PageNode::parent() const +{ + return m_section.ptr(); +} + +NonnullRefPtrVector<Node>& PageNode::children() const +{ + static NonnullRefPtrVector<Node> empty_vector; + return empty_vector; +} + +ErrorOr<String> PageNode::path() const +{ + return TRY(String::formatted("{}/{}.md", TRY(m_section->path()), m_page)); +} + +} diff --git a/Userland/Libraries/LibManual/PageNode.h b/Userland/Libraries/LibManual/PageNode.h new file mode 100644 index 0000000000..f74e78fb2f --- /dev/null +++ b/Userland/Libraries/LibManual/PageNode.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <AK/NonnullRefPtr.h> +#include <LibManual/Node.h> + +namespace Manual { + +class SectionNode; + +class PageNode : public Node { +public: + virtual ~PageNode() override = default; + + PageNode(NonnullRefPtr<SectionNode> section, String page) + : m_section(move(section)) + , m_page(move(page)) + { + } + + virtual NonnullRefPtrVector<Node>& children() const override; + virtual Node const* parent() const override; + virtual String name() const override { return m_page; }; + virtual bool is_page() const override { return true; } + + ErrorOr<String> path() const; + +private: + NonnullRefPtr<SectionNode> m_section; + String m_page; +}; + +} diff --git a/Userland/Libraries/LibManual/SectionNode.cpp b/Userland/Libraries/LibManual/SectionNode.cpp new file mode 100644 index 0000000000..8ab6c89380 --- /dev/null +++ b/Userland/Libraries/LibManual/SectionNode.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "SectionNode.h" +#include "PageNode.h" +#include <AK/LexicalPath.h> +#include <AK/QuickSort.h> +#include <LibCore/DirIterator.h> + +namespace Manual { + +ErrorOr<String> SectionNode::path() const +{ + return String::formatted("/usr/share/man/man{}", m_section); +} + +ErrorOr<void> SectionNode::reify_if_needed() const +{ + if (m_reified) + return {}; + m_reified = true; + + Core::DirIterator dir_iter { TRY(path()).to_deprecated_string(), Core::DirIterator::Flags::SkipDots }; + + Vector<String> page_names; + while (dir_iter.has_next()) { + LexicalPath lexical_path(dir_iter.next_path()); + if (lexical_path.extension() != "md") + continue; + page_names.append(TRY(String::from_utf8(lexical_path.title()))); + } + + quick_sort(page_names); + + for (auto& page_name : page_names) + m_children.append(TRY(try_make_ref_counted<PageNode>(*this, move(page_name)))); + + return {}; +} + +void SectionNode::set_open(bool open) +{ + if (m_open == open) + return; + m_open = open; +} + +Array<NonnullRefPtr<SectionNode>, number_of_sections> const sections = { { + make_ref_counted<SectionNode>("1"sv, "User Programs"sv), + make_ref_counted<SectionNode>("2"sv, "System Calls"sv), + make_ref_counted<SectionNode>("3"sv, "Library Functions"sv), + make_ref_counted<SectionNode>("4"sv, "Special Files"sv), + make_ref_counted<SectionNode>("5"sv, "File Formats"sv), + make_ref_counted<SectionNode>("6"sv, "Games"sv), + make_ref_counted<SectionNode>("7"sv, "Miscellanea"sv), + make_ref_counted<SectionNode>("8"sv, "Sysadmin Tools"sv), +} }; + +} diff --git a/Userland/Libraries/LibManual/SectionNode.h b/Userland/Libraries/LibManual/SectionNode.h new file mode 100644 index 0000000000..cc7546f8e1 --- /dev/null +++ b/Userland/Libraries/LibManual/SectionNode.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org> + * Copyright (c) 2022, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <AK/Error.h> +#include <AK/String.h> +#include <LibManual/Node.h> + +namespace Manual { + +class SectionNode : public Node { +public: + virtual ~SectionNode() override = default; + + SectionNode(StringView section, StringView name) + : m_section(MUST(String::from_utf8(section))) + , m_full_name(MUST(String::formatted("{}. {}", section, name))) + { + } + + virtual NonnullRefPtrVector<Node>& children() const override + { + MUST(reify_if_needed()); + return m_children; + } + + virtual Node const* parent() const override { return nullptr; } + virtual String name() const override { return m_full_name; } + virtual bool is_open() const override { return m_open; } + void set_open(bool open); + + String const& section_name() const { return m_section; } + ErrorOr<String> path() const; + +private: + ErrorOr<void> reify_if_needed() const; + + String m_section; + String m_full_name; + mutable NonnullRefPtrVector<Node> m_children; + mutable bool m_reified { false }; + bool m_open { false }; +}; + +constexpr size_t number_of_sections = 8; + +extern Array<NonnullRefPtr<SectionNode>, number_of_sections> const sections; + +constexpr Array<StringView, number_of_sections> const section_numbers = { + "1"sv, + "2"sv, + "3"sv, + "4"sv, + "5"sv, + "6"sv, + "7"sv, + "8"sv, +}; + +} |