File size: 3,604 Bytes
f65fe85
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#!/usr/bin/env python
#
# This file is part of LilyPond, the GNU music typesetter.
#
# Copyright (C) 2010--2020 Graham Percival <[email protected]>
#
# LilyPond is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# LilyPond is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.

import sys

try:
    infile = sys.argv[1]
except IndexError:
    print("Error: need a filename")
    sys.exit(1)

with open(infile, encoding='utf8') as file:
    lines = file.readlines()

nodes = []

# Generate TOC
for i in range(len(lines)):
    line = lines[i]
    if line.startswith('@node '):
        node_name = line[6:].rstrip()
        # ASSUME: the last line of the file is not @node
        section_line = lines[i+1]
        if (section_line.startswith('@chapter ') or
            section_line.startswith('@unnumbered ') or
                section_line.startswith('@appendix ')):
            section_type = 1
        elif (section_line.startswith('@section ') or
              section_line.startswith('@unnumberedsec ') or
              section_line.startswith('@appendixsec ')):
            section_type = 2
        elif (section_line.startswith('@subsection ') or
              section_line.startswith('@unnumberedsubsec ') or
              section_line.startswith('@appendixsubsec ')):
            section_type = 3
        elif (section_line.startswith('@subsubsection ') or
              section_line.startswith('@unnumberedsubsubsec ') or
              section_line.startswith('@appendixsubsubsec ')):
            section_type = 4
        else:
            print("ERROR: unknown sectioning command")
            print(section_line)
            sys.exit(1)
        nodes.append((section_type, node_name))

# sanity check for debugging
# for node in nodes:
#    print ' '*2*node[0] + node[1]


def getMenuFor(node_name):
    i = 0
    while nodes[i][1] != node_name:
        i += 1
    startIndex = i + 1
    findType = nodes[i][0] + 1
    menu = []
    for i in range(startIndex, len(nodes)):
        currentSectionType = nodes[i][0]
        currentNodeName = nodes[i][1]
        if currentSectionType < findType:
            break
        elif currentSectionType == findType:
            menu.append(currentNodeName)
        else:
            pass
    return menu


# rewrite file with new menus from TOC
outfile = open(infile, 'w', encoding='utf8')

lastNode = ''
line_index = 0
while line_index < len(lines):
    line = lines[line_index]
    if line.startswith('@node'):
        lastNode = line[6:].rstrip()
    if line.startswith('@menu'):
        outfile.write('@menu\n')
        # skip over existing menu
        # ASSUME: every @menu has a proper @end menu
        while not lines[line_index].startswith('@end menu'):
            line_index += 1

        # write new menu entries
        menu = getMenuFor(lastNode)
        for item in menu:
            node_formatted = '* ' + item + '::\n'
            outfile.write(node_formatted)

        line = lines[line_index]
    line_index += 1
    # write normal line.  Removes tabs and spaces; leaves EOL
    outfile.write(line.rstrip('\t '))
outfile.close()