LineIterator.h 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /*
  2. * Copyright (c) 2021, Peter Elliott <pelliott@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Iterator.h>
  8. #include <AK/StringView.h>
  9. #include <AK/Vector.h>
  10. namespace Markdown {
  11. template<typename T>
  12. class FakePtr {
  13. public:
  14. FakePtr(T item)
  15. : m_item(move(item))
  16. {
  17. }
  18. T const* operator->() const { return &m_item; }
  19. T* operator->() { return &m_item; }
  20. private:
  21. T m_item;
  22. };
  23. class LineIterator {
  24. public:
  25. struct Context {
  26. enum class Type {
  27. ListItem,
  28. BlockQuote,
  29. };
  30. Type type;
  31. size_t indent;
  32. bool ignore_prefix;
  33. static Context list_item(size_t indent) { return { Type::ListItem, indent, true }; }
  34. static Context block_quote() { return { Type::BlockQuote, 0, false }; }
  35. };
  36. LineIterator(Vector<StringView>::ConstIterator const& lines)
  37. : m_iterator(lines)
  38. {
  39. }
  40. bool is_end() const;
  41. StringView operator*() const;
  42. LineIterator operator++()
  43. {
  44. reset_ignore_prefix();
  45. ++m_iterator;
  46. return *this;
  47. }
  48. LineIterator operator++(int)
  49. {
  50. LineIterator tmp = *this;
  51. reset_ignore_prefix();
  52. ++m_iterator;
  53. return tmp;
  54. }
  55. LineIterator operator+(ptrdiff_t delta) const
  56. {
  57. LineIterator copy = *this;
  58. copy.reset_ignore_prefix();
  59. copy.m_iterator = copy.m_iterator + delta;
  60. return copy;
  61. }
  62. LineIterator operator-(ptrdiff_t delta) const
  63. {
  64. LineIterator copy = *this;
  65. copy.reset_ignore_prefix();
  66. copy.m_iterator = copy.m_iterator - delta;
  67. return copy;
  68. }
  69. ptrdiff_t operator-(LineIterator const& other) const { return m_iterator - other.m_iterator; }
  70. FakePtr<StringView> operator->() const { return FakePtr<StringView>(operator*()); }
  71. void push_context(Context context) { m_context_stack.append(move(context)); }
  72. void pop_context() { m_context_stack.take_last(); }
  73. private:
  74. void reset_ignore_prefix();
  75. Optional<StringView> match_context(StringView line) const;
  76. Vector<StringView>::ConstIterator m_iterator;
  77. Vector<Context> m_context_stack;
  78. };
  79. }