diff --git a/.gitignore b/.gitignore index 31ec63724..1bff54ad1 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ /.build /Package.resolved /TSPL.docc/header.html +/TSPL.docc/tags /swift-book diff --git a/bin/make_tags b/bin/make_tags new file mode 100755 index 000000000..51230157b --- /dev/null +++ b/bin/make_tags @@ -0,0 +1,60 @@ +#! /usr/bin/env python3 + +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2023 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See https://swift.org/LICENSE.txt for license information +# See https://swift.org/CONTRIBUTORS.txt for Swift project authors + +""" +Generates a tags file, using the POSIX ctags syntax, for navigation while +editing. The tags file provides "jump to definition" information about DocC +links to headings and syntactic categories in the formal grammar. + +To use these tags, configure your editor to include a-z, A-Z, pound (#), +hyphen (-), and colon (:), as valid characters in a tag. +""" + +import os +import re + +CHAPTER_REGEX = re.compile(r'^# ') +HEADING_REGEX = re.compile(r'^#+ ') +GRAMMAR_REGEX = re.compile(r'^> \*[a-z-]*\* → ') + +chapter = None +tags = [] + +os.chdir('TSPL.docc') +for root, dirs, files in os.walk('.'): + for file in files: + if not file.endswith('.md'): + continue + if file == 'SummaryOfTheGrammar.md': + continue + path = os.path.join(root, file) + with open(path, encoding='utf8') as f: + chapter = None + for line in f: + line = line.rstrip() + if CHAPTER_REGEX.match(line): + chapter = line.lstrip('# ').replace(' ', '') + tag = 'doc:' + chapter + search = '/^' + line.replace('/', '\\/') + '/' + tags.append(tag + '\t' + path + '\t' + search + '\n') + elif HEADING_REGEX.match(line): + heading = line.lstrip('# ').replace(' ', '-') + tag = 'doc:' + chapter + '#' + heading + search = '/^' + line.replace('/', '\\/') + '/' + tags.append(tag + '\t' + path + '\t' + search + '\n') + elif GRAMMAR_REGEX.match(line): + tag, _ = line.split('→') + tag = tag.lstrip('*> ').rstrip('* ') + search = '/*' + tag.replace('/', '\\/') + '* →/' + tags.append(tag + '\t' + path + '\t' + search + '\n') + +tags.sort() +with open('tags', 'w', encoding='utf8') as tags_file: + tags_file.writelines(tags) diff --git a/bin/make_tags.swift b/bin/make_tags.swift new file mode 100644 index 000000000..0cace6d10 --- /dev/null +++ b/bin/make_tags.swift @@ -0,0 +1,53 @@ +#! /usr/bin/env python3 + +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2023 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for Swift project authors + +/* +Generates a tags file, using the POSIX ctags syntax, for navigation while +editing. The tags file provides "jump to definition" information about DocC +links to headings and syntactic categories in the formal grammar. + +To use these tags, configure your editor to include a-z, A-Z, pound (#), +hyphen (-), and colon (:), as valid characters in a tag. +*/ + +import Foundation + +let chapterRegex = try Regex("^# (.*)") +let headingRegex = try Regex("^#+ ") +let grammarRegex = try Regex(#"^> \*[a-z-]*\* → "#) + +var chapter: String? = nil +var tags: [String] = [] + +let basePath = "TSPL.docc/" +let fileManager = FileManager() +let fileEnumerator = fileManager.enumerator(atPath: basePath)! +for case let path as String in fileEnumerator { + guard path.hasSuffix(".md") else { continue } + guard path != "ReferenceManual/SummaryOfTheGrammar.md" else { continue } + print(path) + + let fileContents = try String(contentsOfFile: basePath + path, encoding: .utf8) + chapter = nil + for line in fileContents.split(separator: "\n") { + if let match = line.firstMatch(of: chapterRegex) { + let chapter = match.0 + let tag = "doc:" + chapter + let search = "/^" + line.replacingOccurances(of: "/", with: "\\/") + "/" + tags.append(tag + "\t" + path + "\t" + search + "\n") + } else if let match = line.firstMatch(of: headingRegex) { + + } else if let match = line.firstMatch(of: grammarRegex) { + + } + } +} + +print(tags)