Skip to content

Commit

Permalink
add: native reStructuredText support
Browse files Browse the repository at this point in the history
test: added AsciiDoc and reStructuredText tests
  • Loading branch information
AlphaJack committed Feb 23, 2024
1 parent 2b96ab3 commit 9a5c93a
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 49 deletions.
46 changes: 12 additions & 34 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,44 +1,22 @@
<!--
// ┌───────────────────────────────────────────────────────────────┐
// │ Contents of CHANGELOG.md │
// ├───────────────────────────────────────────────────────────────┘
// │
// ├──┐Changelog - toc
// │ ├──┐[2.4.0] - 2024-02-07
// │ │ ├── Added
// │ │ ├── Changed
// │ │ ├── Documentation
// │ │ ├── Performance
// │ │ └── Testing
// │ ├──┐[2.3.0] - 2024-02-02
// │ │ ├── Added
// │ │ ├── Documentation
// │ │ ├── Fixed
// │ │ ├── Performance
// │ │ └── Testing
// │ ├──┐[2.2.0] - 2024-01-29
// │ │ ├── Added
// │ │ ├── Documentation
// │ │ ├── Fixed
// │ │ └── Testing
// │ ├──┐[2.1.0] - 2024-01-22
// │ │ ├── Added
// │ │ └── Documentation
// │ ├── [2.0.0] - 2024-01-21
// │ └── [1.0.0] - 2023-11-03
// │
// └───────────────────────────────────────────────────────────────
-->

# Changelog - toc

## [2.5.0] - 2024-02-23
### Added

- Native reStructuredText support
- Native AsciiDoc support

### Testing

- Added AsciiDoc and reStructuredText tests

## [2.4.0] - 2024-02-07
### Added

- Native man pages support
- Line numbers to HTML toc
- Stdin support with `-` argument
- Set an arbitrary extension with `-e`, useful for stdin
- Stdin support with "-" argument
- Set an arbitrary extension with "-e", useful for stdin
- Native HTML support

### Changed
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ If you are using Arch or Manjaro Linux, you can install [toc](https://aur.archli

You should now be able to run `toc -h` to display a list of parameter you can use.

See [USAGE.md](./USAGE.md) for step-by-step explanations of the different features, and languages that don't need comments (e.g. Markdown) or needs special attention (e.g. CSS)
See [USAGE.md](./USAGE.md) for step-by-step explanations of different features, and a list of languages supported natively (e.g. Markdown, AsciiDoc, reStructuredText) or that need special attention (e.g. CSS)

See <https://regex101.com/r/ngzZXN/1> for examples of valid and invalid comments.

Expand Down
32 changes: 25 additions & 7 deletions USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
// │ │ ├── HTML
// │ │ ├── Man pages
// │ │ ├── Markdown
// │ │ └── Perl
// │ │ ├── Perl
// │ │ └── reStructuredText
// │ ├──┐Wrap around comments needed
// │ │ ├── CSS
// │ │ └── OCaml
Expand All @@ -40,7 +41,7 @@ The scenarios below show different features of `toc`
### Read the table of contents

Let's say you want to structure your javascript file "example.js".
Single line comments in this language start with `//`.
Single-line comments in this language start with `//`.
You open your file and add these comments where you need them:

```js
Expand Down Expand Up @@ -344,7 +345,6 @@ For [AsciiDoc](https://raw.githubusercontent.com/apple/pkl/main/CONTRIBUTING.ado
===== Level 4 Section Title

====== Level 5 Section Title

```

#### Beancount
Expand Down Expand Up @@ -416,9 +416,27 @@ Text
=cut
```

#### reStructuredText

For [ReStructured Text](https://raw.githubusercontent.com/sphinx-doc/sphinx/master/doc/usage/restructuredtext/basics.rst) files, just use the [conventional heading format](https://devguide.python.org/documentation/markup/#sections):

```rst
*******
Chapter
*******
=======
Section
=======
----------
Subsection
----------
```

### Wrap around comments needed

These languages do not support single line comments, and thus every comment should be wrapped by a multi line comment separator
These languages do not support single-line comments, and thus every comment should be wrapped by a multi-line comment separator

#### CSS

Expand Down Expand Up @@ -471,7 +489,7 @@ void main() { exit(0);}
#### RStudio
If you are using RStudio, you may want to end your comments with at least 4 `-`, `=` or `#`.
This marks the comment as a foldable sections:
This marks the comment as a foldable section:
```r
# ################################################################ Foldable section 1 ####
Expand All @@ -486,5 +504,5 @@ print("Collapse me!")


[^1]: No, not really, it's just a match-case statement using the file extension, defaulting to "#"
[^2]: Not even, it's just a bunch of if-else and try-excepts statement that may prevent catastrophic damage
[^3]: The outdated toc to be replaced is defined as the the first match of a non-greedy regex
[^2]: Not even, it's just a bunch of if-else and try-excepts statements that may prevent catastrophic damage
[^3]: The outdated toc to be replaced is defined as the first match of a non-greedy regex
15 changes: 15 additions & 0 deletions tests/input/asciidoc_simple.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
= Document Title (Level 0)

== Level 1 Section Title

= Level 0 Section Title (Part)

== Level 1 Section Title

=== Level 2 Section Title

==== Level 3 Section Title

===== Level 4 Section Title

====== Level 5 Section Title
13 changes: 13 additions & 0 deletions tests/input/restructuredtext_simple.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
*******
Chapter
*******

Section
=======

----------
Subsection
----------
^^^^^^^^^^^^^^
Subsubsections
^^^^^^^^^^^^^^
30 changes: 30 additions & 0 deletions tests/reference/asciidoc_simple.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// ┌───────────────────────────────────────────────────────────────┐
// │ Contents of asciidoc_simple.adoc │
// ├───────────────────────────────────────────────────────────────┘
// │
// ├──┐Document Title (Level 0)
// │ └── Level 1 Section Title
// ├──┐Level 0 Section Title (Part)
// │ └──┐Level 1 Section Title
// │ └──┐Level 2 Section Title
// │ └──┐Level 3 Section Title
// │ └──┐Level 4 Section Title
// │ └── Level 5 Section Title
// │
// └───────────────────────────────────────────────────────────────

= Document Title (Level 0)

== Level 1 Section Title

= Level 0 Section Title (Part)

== Level 1 Section Title

=== Level 2 Section Title

==== Level 3 Section Title

===== Level 4 Section Title

====== Level 5 Section Title
24 changes: 24 additions & 0 deletions tests/reference/restructuredtext_simple.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
.. ┌───────────────────────────────────────────────────────────────┐
.. │ Contents of restructuredtext_simple.rst │
.. ├───────────────────────────────────────────────────────────────┘
..
.. │ └──┐Chapter
.. │ └──┐Section
.. │ └──┐Subsection
.. │ └── Subsubsections
..
.. └───────────────────────────────────────────────────────────────
*******
Chapter
*******

Section
=======

----------
Subsection
----------
^^^^^^^^^^^^^^
Subsubsections
^^^^^^^^^^^^^^
2 changes: 1 addition & 1 deletion toc/__version__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/usr/bin/env python

__version__ = "2.4.0"
__version__ = "2.5.0"
50 changes: 44 additions & 6 deletions toc/toc.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
# │ │ └──┐BODY
# │ │ ├── ASCIIDOC, BEANCOUNT AND MARKDOWN
# │ │ ├── HTML
# │ │ ├── RESTRUCTUREDTEXT
# │ │ ├── MAN PAGES
# │ │ ├── PERL
# │ │ ├── GENERIC
Expand Down Expand Up @@ -54,6 +55,7 @@ def __init__(self, inputFile: str = "", outputFile=None, lineNumbers: bool = Fal
self.innerTocTitle = None
self.innerTocEnd = None
self.pattern = None
# n=2**(7−l), l=7−math.log(n,2)
self.levels = {
64: 1,
32: 2,
Expand Down Expand Up @@ -81,10 +83,6 @@ def set_character(self):
# https://www.gnu.org/software/groff/manual/, https://manpages.bsd.lv/mdoc.html
case "1" | "1m" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "n":
self.character = '.\\"'
case "ml" | "mli":
self.character = "*"
case "vb" | "vba" | "vbs":
self.character = "'"
case "apl":
self.character = "⍝"
# https://www.gavilan.edu/csis/languages/comments.html#_Toc53710123
Expand All @@ -93,13 +91,19 @@ def set_character(self):
# https://stackoverflow.com/a/17665688
case "cbl" | "cob":
self.character = " *>"
case "f" | "for":
self.character = "C"
# https://github.com/textmate/fortran.tmbundle/issues/10#issuecomment-22660333
case "f90" | "f95" | "f03" | "f08" | "f15" | "f18":
self.character = "!"
case "f" | "for":
self.character = "C"
case "j":
self.character = "NB."
case "ml" | "mli":
self.character = "*"
case "rst":
self.character = ".."
case "vb" | "vba" | "vbs":
self.character = "'"
# jl mojo pl pm ps1 py r rb sh, yml, and anything else
case _:
self.character = "#"
Expand Down Expand Up @@ -346,6 +350,8 @@ def _toc_body(self):
_newtoc = self._process_man(_lines)
case "pl" | "pm" | "pod":
_newtoc = self._process_perl(_lines)
case "rst":
_newtoc = self._process_restructuredtext(_data)
case _:
_newtoc = self._process_generic(_lines)
_tocBody = self._prettify_connectors(_newtoc)
Expand Down Expand Up @@ -410,6 +416,38 @@ def _process_html(self, data):
_newtoc.append(self._add_heading(_heading_level, _heading_text))
return _newtoc

# #### RESTRUCTUREDTEXT

def _process_restructuredtext(self, data):
_newtoc = []
# match the line above a streak of "#" (chapters), "*" (sections), etc., avoiding '"""' heredocs (min 4)
_pattern = re.compile(r'(?:[#\*=\-\^~]{2,}|[\"]{4,}|\n)[ \t]*(?!\.\.)(.+)\n[ \t]*([#\*=\-\^~]{2,}|[\"]{4,})\n', re.MULTILINE)
_fromLastMatch = 0
n = 1
# https://devguide.python.org/documentation/markup/#sections
_levels = {
'#': 1,
'*': 2,
'=': 3,
'-': 4,
'~': 5,
'^': 5,
'"': 6
}
for _match in _pattern.finditer(data):
_heading_text = _match.group(1)
_symbol = _match.group(2)[:1]
_heading_level = _levels[_symbol]
if self.lineNumbers:
# start counting from _heading_text, not optional overline
_untilCurrentMatch = _match.start(1)
n = n + data.count("\n", _fromLastMatch, _untilCurrentMatch)
_heading_text = _heading_text + " " + str(n)
# update with the position of the current match
_fromLastMatch = _untilCurrentMatch
_newtoc.append(self._add_heading(_heading_level, _heading_text))
return _newtoc

# #### MAN PAGES

def _process_man(self, lines):
Expand Down

0 comments on commit 9a5c93a

Please sign in to comment.