mirror of https://github.com/apache/druid.git
114 lines
4.5 KiB
Python
Executable File
114 lines
4.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
# Licensed to the Apache Software Foundation (ASF) under one or more
|
|
# contributor license agreements. See the NOTICE file distributed with
|
|
# this work for additional information regarding copyright ownership.
|
|
# The ASF licenses this file to You under the Apache License, Version 2.0
|
|
# (the "License"); you may not use this file except in compliance with
|
|
# the License. You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
import argparse
|
|
import urllib.parse
|
|
|
|
def get_header_level(line):
|
|
count = 0
|
|
for element in line:
|
|
if element == '#':
|
|
count = count + 1
|
|
else:
|
|
break
|
|
return count
|
|
|
|
def make_link_text(prefix, text):
|
|
return "{}-{}".format(prefix, urllib.parse.quote_plus(text.lower().replace(' ', '-')))
|
|
|
|
def process_release_notes(release_version, release_notes, outfile):
|
|
"""
|
|
rewrites markdown headers with an embedded html link so that github release notes can become linkable.
|
|
|
|
parent header text is url-encoded and prefixed to the link text so that links are ensured to be unique, albeit a
|
|
bit long.
|
|
|
|
e.g.
|
|
# New features
|
|
...
|
|
## Queries
|
|
...
|
|
### Some cool feature
|
|
|
|
becomes:
|
|
# <a name="0.22.0-new-features" href="#0.22.0.new-features">#</a> New features
|
|
...
|
|
## <a name="0.22.0-new-features-queries" href="...">#</a> Queries
|
|
...
|
|
### <a name="0.22.0-new-features-queries-some-cool-feature" href="...">#</a> Some cool feature
|
|
|
|
Markdown headers which already have an embedded link of this form will be ignored (though this logic isn't very
|
|
smart, if it starts with "<a href=" or like, any other valid link form it will be missed...)
|
|
|
|
:param release_version: release version is always the first part of the embedded link prefix
|
|
:param release_notes: markdown file that contains release notes
|
|
:param outfile: destination for rewritten markdown file
|
|
:return: nothing
|
|
"""
|
|
with open(args.out_path, "w", encoding="utf-8") as outfile:
|
|
with open(release_notes, encoding="utf-8") as file:
|
|
current_level = 0
|
|
current_prefix = release_version
|
|
levels = []
|
|
prefixes = []
|
|
for line in file:
|
|
header_level = get_header_level(line)
|
|
header_text = line[header_level + 1:len(line) - 1]
|
|
if (header_level > 0 and "<a name=" not in line):
|
|
if header_level > current_level:
|
|
levels.append(current_level)
|
|
prefixes.append(current_prefix)
|
|
current_level = header_level
|
|
elif header_level < current_level:
|
|
current_level = levels.pop()
|
|
prefixes.pop()
|
|
while (header_level < current_level):
|
|
current_level = levels.pop()
|
|
prefixes.pop()
|
|
|
|
current_prefix = prefixes.pop()
|
|
link_text = make_link_text(current_prefix, header_text)
|
|
prefixes.append(current_prefix)
|
|
current_prefix = link_text
|
|
|
|
print(
|
|
"{} <a name=\"{}\" href=\"#{}\">#</a> {}".format(
|
|
line[0:header_level],
|
|
link_text,
|
|
link_text,
|
|
line[header_level + 1:]
|
|
),
|
|
file=outfile,
|
|
end = ''
|
|
)
|
|
else:
|
|
print(line, file=outfile, end = '')
|
|
return
|
|
|
|
if __name__ == "__main__":
|
|
try:
|
|
parser = argparse.ArgumentParser(description='rewrite markdown so that headings contain direct links')
|
|
parser.add_argument('version', metavar='release version', type=str)
|
|
parser.add_argument('release_notes', metavar='<path to release notes markdown file>', type=str)
|
|
parser.add_argument('out_path', metavar='<path to output file>', type=str)
|
|
args = parser.parse_args()
|
|
|
|
process_release_notes(args.version, args.release_notes, args.out_path)
|
|
|
|
except KeyboardInterrupt:
|
|
print('Interrupted, closing.')
|