|
- #!/usr/bin/env python3
- # encoding: utf-8
- # Copyright 2020 Huawei Technologies Co., Ltd
- #
- # Licensed 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 sys
- import math
-
- MIN_CHARS_PER_ROW = 20 # minimal number of chars on one line
- COLS_TO_ROWS_RATIO = 4 # ratio of # columns to # rows (unit is char)
- MAX_LABEL_LENGTH = 1000 # maximal number of chars of a label
-
-
- # for specified number of chars, calculate a suitable number for how many chars per row
- # Num Total Chars : n
- # Num Chars Per Row : m
- # Num Rows : k
- # (k - 1) * m < n <= k * m
- # suppose: m / k = u
- # ==> sqrt(u * n) <= m < u / 2 + sqrt(u * n + u * u / 4)
- # m = max(20, m)
- # parameters:
- # @total_chars number of total chars
- # @ratio ratio of # columns to # rows (unit is char)
- def calc_num_chars_per_row(total_chars, ratio):
- chars_per_row = math.ceil(math.sqrt(total_chars * ratio))
- return max(MIN_CHARS_PER_ROW, chars_per_row)
-
-
- def process_label_text(text):
- label_len = min(len(text), MAX_LABEL_LENGTH)
- chars_per_row = calc_num_chars_per_row(label_len, COLS_TO_ROWS_RATIO)
- if label_len <= MIN_CHARS_PER_ROW:
- return text
- beg_idx = 0
- texts = []
- while beg_idx < label_len:
- end_idx = beg_idx + chars_per_row
- if end_idx >= label_len:
- texts.append(text[beg_idx:label_len])
- else:
- texts.append(text[beg_idx:end_idx])
- beg_idx = end_idx
- return "\\n".join(texts)
-
-
- # insert '\n' to labels which are too long
- def process_file(f):
- line_text = f.readline()
- beg_idx = -1 # label begin index, index of 'label="'
- end_idx = -1 # label end index, index of '"'
- label_text = ""
- label_prefix = ""
- label_postfix = ""
- while line_text:
- line_text = line_text.rstrip()
-
- if beg_idx < 0:
- beg_idx = line_text.find('label="')
- if beg_idx >= 0:
- end_idx = line_text.find('"', beg_idx + len('label="'))
- if end_idx >= 0: # the full label text is on one line
- label = line_text[beg_idx + len('label="'):end_idx]
- print('%slabel="%s"%s' % (line_text[0:beg_idx], process_label_text(label), line_text[end_idx + 1:]))
- beg_idx = -1 # reset to initial conditions
- else: # the label text is distributed on multiple lines
- label_prefix = line_text[0:beg_idx]
- label_text = line_text[beg_idx + len('label="'):]
- else:
- print(line_text)
- else:
- end_idx = line_text.find('"')
- if end_idx >= 0:
- label_text = label_text + line_text[0:end_idx]
- label_postfix = line_text[end_idx + 1:]
- print('%slabel="%s"%s' % (label_prefix, process_label_text(label_text), label_postfix))
- beg_idx = -1 # reset to initial conditions
- else:
- label_text += line_text
-
- # print(f'{len(line_text)} - {line_text}')
- line_text = f.readline()
-
-
- if __name__ == "__main__":
- if len(sys.argv) > 1 and sys.argv[1] == "--help":
- print("Usage: %s < dotfile | dot -Tpng -o filename.png" % sys.argv[0])
- sys.exit()
-
- # read text from stdin
- process_file(sys.stdin)
|