74 def indent(self, nodeToUpdate=None, indentProgramunit=0, indentBranch=2,
81 nodeToUpdate : Element, optional
82 Specific node to indent. If None, indents entire scope.
83 indentProgramunit : int, optional
84 Number of spaces for program unit contents. Default is 0.
85 indentBranch : int, optional
86 Number of spaces for nested constructs (do, if, etc.). Default is 2.
87 exclDirectives : list, optional
88 Lines to exclude from indentation:
89 - None: Exclude '!$OMP' lines (default).
90 - []: Include all lines.
91 - ['!$acc', '!$mnh']: Custom directive list.
96 Returns self for chaining.
100 >>> pft = PYFT('input.F90')
101 >>> pft.indent() # Default indentation
102 >>> pft.indent(indentProgramunit=0, indentBranch=4) # Custom
105 if nodeToUpdate
is None:
108 if exclDirectives
is None:
109 exclDirectives = [
'!$OMP']
111 def setLevel(elem, level, nextElem):
113 :param elem: element whose tail must be modifies
114 :param level: level of indentation
115 :param nextElem: next element
117 if elem.tail
is not None:
118 elem.tail = elem.tail.replace(
'\t',
' ')
119 excl = (nextElem
is not None and
120 (tag(nextElem) ==
'cpp' or
121 tag(nextElem) ==
'C' and
122 any(nextElem.text.startswith(d)
for d
in exclDirectives)))
124 elem.tail = re.sub(
'\n[ ]*',
'\n' +
' ' * level, elem.tail)
126 def indentRecur(elem, level, inConstruct):
128 :param elem: dom element
129 :param level: current level for elem
130 :param inConstruct: True if we are inside a construct
132 blocs = [
'file',
'program-unit',
'if-block',
'where-block',
'selectcase-block']
133 progstmt = [
'subroutine-stmt',
'program-stmt',
'module-stmt',
'function-stmt',
134 'submodule-stmt',
'procedure-stmt',
'interface-stmt']
135 endprogstmt = [
'end-' + s
for s
in progstmt]
136 interbranchstmt = [
'else-stmt',
'else-if-stmt',
'else-where-stmt']
137 branchstmt = [
'if-then-stmt',
'where-construct-stmt'] + interbranchstmt
138 endbranchstmt = [
'end-if-stmt',
'end-where-stmt']
142 firstnumselect =
True
143 for ie, sElem
in enumerate(elem):
146 if tag(sElem)
in progstmt:
147 currlevel += indentProgramunit
148 elif tag(sElem)
in branchstmt + [inConstruct +
'-stmt']:
149 currlevel += indentBranch
152 setLevel(sElem, currlevel, elem[ie + 1]
if ie + 1 < len(elem)
else None)
154 if tag(elem) ==
'selectcase-construct':
172 firstnumselect =
False
176 setLevel(laste[-1], level + indentBranch, sElem)
178 indentRecur(sElem, level + indentBranch * 2,
"")
179 if tag(sElem[-1]) ==
'end-select-case-stmt':
180 setLevel(sElem[-2], level, sElem[-1])
182 elif tag(sElem)
in blocs
or tag(sElem).endswith(
'-construct'):
184 if tag(sElem[0])
in interbranchstmt:
193 setLevel(laste[-1], level, sElem)
194 construct = tag(sElem)[:-10]
if tag(sElem).endswith(
'-construct')
else ""
195 indentRecur(sElem, currlevel, construct)
199 if tag(sElem)
in endprogstmt + endbranchstmt + [
'end-' + inConstruct +
'-stmt']:
200 setLevel(laste, level, sElem)
203 indentRecur(nodeToUpdate, 0,
"")
280 removeALL=False, addBegin=True, removeBegin=False):
282 :param nodeToUpdate: if None, the entire xml is updated
283 :param align: True to align begin of continued lines
284 :param removeALL: True to suppress all the continuation line characters ('&')
285 :param addBegin: True to add missing continuation line characters ('&')
286 at the begining of lines
287 :param removeBegin: True to suppress continuation line characters ('&')
288 at the begining of lines
290 When suppressed, the '&' are replaced by a space character
291 Comments after a '&' are lost
294 assert not (align
and removeALL),
"We cannot remove and align at the same time"
295 assert not (addBegin
and (removeALL
or removeBegin)), \
296 "We cannot remove and add, at the same time, continuation characters"
298 if nodeToUpdate
is None:
303 def recurReverse(elem, tail):
304 for ie
in range(len(elem))[::-1]:
306 parents[sElem] = elem
307 if tag(sElem) ==
'cnt':
311 while j < len(elem)
and tag(elem[j])
in (
'C',
'cpp'):
312 commentsAfter.append(elem[j])
314 nextNode = elem[j]
if j < len(elem)
else None
317 isend = ((sElem.tail
is not None and '\n' in sElem.tail)
or
318 len(commentsAfter) > 0)
321 if isend
and addBegin:
322 if sElem.tail
is not None and \
323 sElem.tail.replace(
'\n',
'').replace(
'\t',
'').lstrip(
' ') !=
'':
326 new = createElem(
'cnt', text=
'&')
329 while sElem.tail[i]
in (
' ',
'\n',
'\t'):
331 new.tail =
' ' + sElem.tail[i:]
332 sElem.tail = sElem.tail[:i]
333 elem.insert(ie + 1, new)
334 elif tag(nextNode) !=
'cnt':
336 new = createElem(
'cnt', text=
'&')
337 if len(commentsAfter) > 0:
341 while i < len(commentsAfter[-1].tail)
and \
342 commentsAfter[-1].tail[i]
in (
' ',
'\n',
'\t'):
344 new.tail =
' ' + commentsAfter[-1].tail[i:]
345 commentsAfter[-1].tail = commentsAfter[-1].tail[:i]
348 elem.insert(ie + 1 + len(commentsAfter), new)
351 if removeALL
or (removeBegin
and not isend):
353 for com
in commentsAfter[::-1]:
354 if tag(com) !=
'cpp':
361 if sElem.tail
is not None:
362 txt = sElem.tail.strip() +
' '
366 if elem[ie - 1].tail
is None:
367 elem[ie - 1].tail = txt
369 elem[ie - 1].tail += txt
373 recurReverse(sElem, tail)
375 def recurDirect(elem, ct, inCnt):
377 :param ct: current text
378 :param inCnt: -1 if we are not in a statement spanning several lines
379 elswhere contains the number of spaces to add
381 ignoreComment =
False
383 for ie, sElem
in enumerate(list(elem)):
385 isendcnt = tag(sElem) ==
'cnt' and \
386 ((sElem.tail
is not None and '\n' in sElem.tail)
or
387 (ie + 1 < len(elem)
and tag(elem[ie + 1]) ==
'C'))
388 ignoreComment = (ignoreComment
or
390 (ie + 1 < len(elem)
and tag(elem[ie + 1]) ==
'C')))
399 if isendcnt
or ignoreComment
or (inCnt != -1
and tag(sElem) ==
'cpp'):
402 if isendcnt
and inCnt == -1:
405 while not tag(topstmt).endswith(
'-stmt'):
406 topstmt = parents[topstmt]
409 if tag(topstmt) ==
'a-stmt':
410 patList = (
'=>',
'=',
r'\(')
411 elif tag(topstmt) ==
'call-stmt':
412 patList = (
r'\(',
r'call[ ]+\w',
'call ',
'call')
413 elif tag(topstmt) ==
'if-stmt':
414 patList = (
r'\(',
r'\)',
'if ',
'if')
415 elif tag(topstmt) ==
'where-stmt':
416 patList = (
r'\(',
r'\)',
'where ',
'where')
417 elif tag(topstmt) ==
'forall-stmt':
418 patList = (
r'\(',
r'\)',
'forall ',
'forall')
419 elif tag(topstmt) ==
'namelist-stmt':
420 patList = (
'/.*/',
'/',
'namelist')
421 elif tag(topstmt) ==
'subroutine-stmt':
422 patList = (
r'\(',
r'subroutine[ ]+\w',
'subroutine ',
'subroutine')
423 elif tag(topstmt) ==
'use-stmt':
424 patList = (
':',
r'use[ ]+\w',
'use ',
'use')
425 elif tag(topstmt) ==
'T-decl-stmt':
426 patList = (
'::',
r'\w,',
r'\w ',
r'\w')
427 elif tag(topstmt) ==
'print-stmt':
428 patList = (
'print', )
429 elif tag(topstmt) ==
'write-stmt':
430 patList = (
r'\)',
r'write[ ]*\(',
'write[ ]*',
'write')
431 elif tag(topstmt) ==
'procedure-stmt':
432 patList = (
'module[ ]+procedure[ ]*',
'module[ ]*',
'module')
434 patList = (
'::',
':',
r'\(',
'=>',
'=',
'[',
':',
'/')
440 mat = re.search(pat, ct, flags=re.IGNORECASE)
442 if ie + 1 < len(elem)
and tag(elem[ie + 1]) !=
'cnt':
448 inCnt = mat.end() - 1
453 if not (ie + 1 < len(elem)
and tag(elem[ie + 1]) ==
'cpp'):
454 if sElem.tail
is not None:
455 sElem.tail = re.sub(
'\n[ ]*',
'\n' +
' ' * inCnt, sElem.tail)
457 sElem.tail =
'\n' +
' ' * inCnt
459 if tag(sElem)
not in (
'C',
'cnt'):
460 ct += (sElem.text
if sElem.text
is not None else '')
461 ignoreComment =
False
465 ct, inCnt = recurDirect(sElem, ct, inCnt)
468 ct += (sElem.tail
if sElem.tail
is not None else '')
470 ct = ct.split(
'\n')[-1]
471 if tag(sElem)
not in (
'cnt',
'C',
'cpp'):
476 recurReverse(nodeToUpdate, 0)
477 recurDirect(nodeToUpdate,
"", -1)
484 beforeComma=0, afterComma=1,
485 beforeParenthesis=0, afterParenthesis=0,
486 beforeAffectation=1, afterAffectation=1, inAffectation=True,
487 beforeRangeDelim=0, afterRangeDelim=0,
488 beforeUseDelim=0, afterUseDelim=1,
489 beforeDeclDelim=1, afterDeclDelim=1,
490 inDeclDelim=True, afterTypeDecl=1,
491 beforeEqDo=0, afterEqDo=0,
492 beforeEqCall=0, afterEqCall=0,
493 beforeEqInit=0, afterEqInit=0,
494 beforeEndcnt=1, afterBegincnt=1,
495 afterIfwherecase=1, beforeThen=1, beforeIfaction=1,
497 endOfLine=True, afterName=0, inName=True,
498 beforeCmdsep=0, afterCmdsep=1,
499 adjacentKeywords=__NO_VALUE__, afterKeywords=__NO_VALUE__):
501 :param beforeOp, afterOp: number of spaces before and after operators
502 :param inOperator: True to suppress spaces in operators
503 :param beforeComma, afterComma: number of spaces before and after commas
504 :param beforeParenthesis, afterParenthesis: number of spaces before and after parenthesis
505 :param beforeAffectation, afterAffectation: number of spaces before and after
506 affectations or associations
507 :param inAffectation: True to suppress spaces in affectations and in association ('= >')
508 :param beforeRangeDelim, afterRangeDelim: number of spaces before and after range delimiters
509 :param beforeUseDelim, afterUseDelim: number of spaces before and after use delimiters (':')
510 :param beforeDeclDelim, afterDeclDelim: number of spaces before and after declaration and
511 enumerator delimiter ('::')
512 :param inDeclDelim: True to suppress spaces in declaration and enumerator delimiter (': :')
513 :param afterTypeDecl: number of spaces after the type in a declaration w/o '::'
514 (e.g. 'INTEGER I'); also for enumerators (minimum 1)
515 :param beforeEqDo, afterEqDo: number of spaces before and after '=' sign in DO and
517 :param beforeEqCall, afterEqCall: number of spaces before and after '=' sign
519 :param beforeEqInit, afterEqInit: number of spaces before and after '=' sign for init values
520 :param beforeEndcnt, afterBegincnt: number of spaces before a continuation chararcter at the
521 end of the line and after a continuation character
522 at the begining of a line
523 :param afterIfwherecase: number of spaces after the IF, ELSEIF, WHERE, ELSEWHERE,
524 SELECTCASE, CASE and FORALL keywords
525 :param beforeThen: number of spaces before the THEN keyword
526 :param beforeIfaction: number of spaces
527 between IF condition and action in one-line IF statement and
528 between FORALL specification and affectation in one-line FORALL
530 between WHERE mask and action in one-line WHERE statement
531 :param afterProgunit: between the program unit type (e.g. SUBROUTINE) and its name
532 :param endOfLine: True to suppress spaces at the end of the line
533 :param afterName: number of spaces after an indentifier, type or attribute name
534 :param inName: True to suppress spaces in identifier names
535 :param beforeCmdsep, afterCmdsep: number of spaces before and after command separator (';')
536 :param adjacentKeywords: describes the number of spaces to introduce between adjancent
537 keywords when this is legal (the list comes from the table
538 "6.2 Adjacent keywords where separating blanks are optional" of the
539 F2008 norm and has been complemented by "end select",
540 "implicit none" and "module procedure"; for the last two,
541 a minimum of 1 is required).
542 The allowed dictionnary keys are:
574 For example, use {'end_do':1} to write 'END DO' or
575 {'end_do':0} to write 'ENDDO' or
576 {'end_do':None} to not update the writting
577 or use adjacentKeywords=None to disable everything
578 :param afterKeywords: describes the number of spaces to introduce after keywords.
579 Some keywords need a more sophisticated treatment and are controled
580 by specific keys (e.g. CASE).
581 The keys are the keyword in lowercase, some names can be tricky
582 to guess (e.g. the key for ENDFILE is 'end-file'). By default
583 only a few are defined.
584 Use afterKeywords=None to disable everything.
586 To not update spaces, put None instead of an integer and False in booleans.
587 For example, to not change number of spaces after a comma, use afterComma=None
589 Updates are done in the following order:
593 'block_data': (1,
'.//{*}block-data-stmt'),
594 'double_precision': (1,
'.//{*}intrinsic-T-spec/{*}T-N'),
595 'else_if': (1,
'.//{*}else-if-stmt'),
596 'else_where': (0,
'.//{*}else-where-stmt'),
597 'end_associate': (1,
'.//{*}end-associate-stmt'),
598 'end_block': (1,
'.//{*}end-block-stmt'),
599 'end_block_data': (1,
'.//{*}end-block-data-stmt'),
600 'end_critical': (1,
'.//{*}end-critical-stmt'),
601 'end_do': (1,
'.//{*}end-do-stmt'),
602 'end_enum': (1,
'.//{*}end-enum-stmt'),
603 'end_file': (1,
'.//{*}end-file-stmt'),
604 'end_forall': (1,
'.//{*}end-forall-stmt'),
605 'end_function': (1,
'.//{*}end-function-stmt'),
606 'end_if': (1,
'.//{*}end-if-stmt'),
607 'end_interface': (1,
'.//{*}end-interface-stmt'),
608 'end_module': (1,
'.//{*}end-module-stmt'),
609 'end_procedure': (1,
'.//{*}end-procedure-stmt'),
610 'end_program': (1,
'.//{*}end-program-stmt'),
611 'end_selec': (1,
'.//{*}end-select-case-stmt'),
612 'end_select': (1,
'.//{*}end-select-T-stmt'),
613 'end_submodule': (1,
'.//{*}end-submodule-stmt'),
614 'end_subroutine': (1,
'.//{*}end-subroutine-stmt'),
615 'end_team': (1,
'.//{*}end-change-team-stmt'),
616 'end_type': (1,
'.//{*}end-T-stmt'),
617 'end_where': (1,
'.//{*}end-where-stmt'),
618 'go_to': (0,
'.//{*}goto-stmt'),
619 'in_out': (0,
'.//{*}intent-spec'),
620 'select_case': (1,
'.//{*}select-case-stmt'),
621 'select_type': (1,
'.//{*}select-T-stmt'),
622 'implicit_none': (1,
'.//{*}implicit-none-stmt'),
623 'module_procedure': (1,
'.//{*}procedure-stmt'),
635 assert adjacentKeywords
is None or adjacentKeywords == self.
__NO_VALUE__ or \
637 for k
in adjacentKeywords),
"Unknown key in **adjacentKeywords"
640 if adjacentKeywords
is None:
643 return adjaKeyDesc[key][0]
644 return adjacentKeywords.get(key, adjaKeyDesc[key][0])
646 def getvalAfter(key):
649 num = afterKeywords.get(key, afterKey.get(key,
None))
651 num = afterKey.get(key,
None)
654 assert afterProgunit
is None or afterProgunit >= 1
655 assert afterTypeDecl
is None or afterTypeDecl >= 1
656 for k
in (
'implicit_none',
'module_procedure'):
658 assert num
is None or num >= 1, \
659 "adjacentKeywords['" + k +
"'] must be at least 1 (is " + str(num) +
")"
660 for k
in (
'use',
'call',
'end-file',
'do'):
661 num = getvalAfter(k +
'-stmt')
662 assert num
is None or num >= 1, \
663 "afterKeywords['" + k +
"'] must be at least 1 (is " + str(num) +
")"
665 for elem
in self.iter():
666 isNotC = tag(elem) !=
'C'
668 if elem.tail
is None:
670 elem.tail = elem.tail.replace(
'\t',
' ')
673 if beforeParenthesis
is not None:
674 elem.tail = re.sub(
r"[ ]*\(",
" " * beforeParenthesis +
r"(", elem.tail)
675 elem.tail = re.sub(
r"[ ]*\)",
" " * beforeParenthesis +
r")", elem.tail)
676 if elem.text
is not None and isNotC:
677 elem.text = re.sub(
r"[ ]*\(",
" " * beforeParenthesis +
r"(", elem.text)
678 elem.text = re.sub(
r"[ ]*\)",
" " * beforeParenthesis +
r")", elem.text)
679 if afterParenthesis
is not None:
680 elem.tail = re.sub(
r"\([ ]*",
"(" +
" " * afterParenthesis, elem.tail)
681 elem.tail = re.sub(
r"\)[ ]*",
")" +
" " * afterParenthesis, elem.tail)
682 if elem.text
is not None and isNotC:
683 elem.text = re.sub(
r"\([ ]*",
"(" +
" " * afterParenthesis, elem.text)
684 elem.text = re.sub(
r"\)[ ]*",
")" +
" " * afterParenthesis, elem.text)
687 if beforeComma
is not None:
688 elem.tail = re.sub(
r"[ ]*,",
" " * beforeComma +
r",", elem.tail)
689 if elem.text
is not None and isNotC:
690 elem.text = re.sub(
r"[ ]*,",
" " * beforeComma +
r",", elem.text)
691 if afterComma
is not None:
692 elem.tail = re.sub(
r",[ ]*",
"," +
" " * afterComma, elem.tail)
693 if elem.text
is not None and isNotC:
694 elem.text = re.sub(
r",[ ]*",
"," +
" " * afterComma, elem.text)
698 elem.tail = re.sub(
r"[ ]*\n",
r"\n", elem.tail)
701 if tag(elem)
in (
'N',
'T-N',
'attribute-N'):
703 for nnn
in elem.findall(
'{*}n'):
704 if nnn.tail
is not None:
705 nnn.tail = nnn.tail.strip(
' ')
706 if elem.tail
is not None and afterName
is not None:
707 elem.tail =
' ' * afterName + elem.tail.lstrip(
' ')
710 elif tag(elem) ==
'lower-bound' and elem.tail
is not None and ':' in elem.tail:
711 if beforeRangeDelim
is not None:
712 elem.tail =
' ' * beforeRangeDelim + elem.tail.lstrip(
' ')
713 if afterRangeDelim
is not None:
714 elem.tail = elem.tail.rstrip(
' ') +
' ' * beforeRangeDelim
717 elif tag(elem) ==
'module-N' and elem.tail
is not None and ':' in elem.tail:
718 if beforeUseDelim
is not None:
719 elem.tail = re.sub(
r"[ ]*:",
" " * beforeUseDelim +
r":", elem.tail)
720 if afterUseDelim
is not None:
721 elem.tail = re.sub(
r":[ ]*",
":" +
" " * afterUseDelim, elem.tail)
725 elif tag(elem)
in (
'attribute',
'_T-spec_')
and elem.tail
is not None:
727 elem.tail = re.sub(
r":[ ]*:",
r"::", elem.tail)
728 if beforeDeclDelim
is not None:
729 elem.tail = re.sub(
r"[ ]*(:[ ]*:)",
' ' * beforeDeclDelim +
r"\1", elem.tail)
730 if afterDeclDelim
is not None:
731 elem.tail = re.sub(
r"(:[ ]*:)[ ]*",
r"\1" +
' ' * afterDeclDelim, elem.tail)
732 if tag(elem) ==
'_T-spec_' and afterTypeDecl
is not None:
733 elem.tail = elem.tail.rstrip(
' ') +
' ' * afterTypeDecl
737 elif tag(elem) ==
'enumerator-stmt' and elem.text
is not None:
740 elem.text = re.sub(
r":[ ]*:",
r"::", elem.text)
741 if beforeDeclDelim
is not None:
742 elem.text = re.sub(
r"[ ]*(:[ ]*:)",
' ' * beforeDeclDelim +
r"\1",
744 if afterDeclDelim
is not None:
745 elem.text = re.sub(
r"(:[ ]*:)[ ]*",
r"\1" +
' ' * afterDeclDelim,
747 elif afterTypeDecl
is not None:
748 elem.text = elem.text.rstrip(
' ') +
' ' * afterTypeDecl
751 elif (tag(elem)
in (
'subroutine-stmt',
'program-stmt',
'module-stmt',
'function-stmt',
752 'submodule-stmt',
'procedure-stmt',
'interface-stmt',
753 'end-subroutine-stmt',
'end-program-stmt',
754 'end-module-stmt',
'end-function-stmt',
755 'end-submodule-stmt',
'end-procedure-stmt',
'end-interface-stmt')
756 and afterProgunit
is not None):
757 if elem.text
is not None:
758 elem.text = elem.text.rstrip(
' ') +
' ' * afterProgunit
761 elif tag(elem)
in (
'do-V',
'V')
and elem.tail
is not None and '=' in elem.tail:
762 if beforeEqDo
is not None:
763 elem.tail = re.sub(
'[ ]*=',
' ' * beforeEqDo +
'=', elem.tail)
764 if afterEqDo
is not None:
765 elem.tail = re.sub(
'=[ ]*',
'=' +
' ' * beforeEqDo, elem.tail)
768 elif tag(elem) ==
'arg-N' and elem.tail
is not None and '=' in elem.tail:
769 if beforeEqCall
is not None:
770 elem.tail = re.sub(
'[ ]*=',
' ' * beforeEqCall +
'=', elem.tail)
771 if afterEqCall
is not None:
772 elem.tail = re.sub(
'=[ ]*',
'=' +
' ' * beforeEqCall, elem.tail)
775 elif (tag(elem)
in (
'EN-N',
'named-constant')
and
776 elem.tail
is not None and '=' in elem.tail):
777 if beforeEqInit
is not None:
778 elem.tail = re.sub(
'[ ]*=',
' ' * beforeEqInit +
'=', elem.tail)
779 if afterEqInit
is not None:
780 elem.tail = re.sub(
'=[ ]*',
'=' +
' ' * beforeEqInit, elem.tail)
782 elif tag(elem) ==
'smc':
783 if beforeCmdsep
is not None:
784 prev = self.getSiblings(elem, after=
False)
785 if len(prev) != 0
and prev[-1].tail
is not None:
786 prev[-1].tail =
' ' * beforeCmdsep + prev[-1].tail.lstrip(
' ')
787 if afterCmdsep
is not None and elem.tail
is not None:
788 elem.tail = elem.tail.rstrip(
' ') +
' ' * afterCmdsep
791 elif tag(elem) ==
'associate-N' and elem.tail
is not None and '=' in elem.tail:
792 if beforeAffectation
is not None:
793 elem.tail = re.sub(
'[ ]*=',
' ' * beforeAffectation +
'=', elem.tail)
794 if afterAffectation
is not None:
795 elem.tail = re.sub(
'>[ ]*',
'>' +
' ' * beforeAffectation, elem.tail)
797 elem.tail = re.sub(
r'=[ ]*>',
'=>', elem.tail)
811 for elem
in self.iter():
813 if tag(elem) ==
'op-E':
814 for op
in elem.findall(
'{*}op'):
815 if beforeOp
is not None:
816 io = list(elem).index(op)
819 if prev.tail
is None:
820 prev.tail =
' ' * beforeOp
822 prev.tail = prev.tail.rstrip(
' ') +
' ' * beforeOp
823 if afterOp
is not None:
825 op.tail =
' ' * afterOp
827 op.tail = op.tail.lstrip(
' ') +
' ' * afterOp
829 for oo
in op.findall(
'{*}o'):
830 if oo.tail
is not None:
831 oo.tail = oo.tail.strip(
' ')
834 elif tag(elem)
in (
'a-stmt',
'pointer-a-stmt'):
836 for aff
in elem.findall(
'{*}a'):
837 if beforeAffectation
is not None:
838 prev = elem[list(elem).index(aff) - 1]
839 if prev.tail
is None:
840 prev.tail =
' ' * beforeAffectation
842 prev.tail = prev.tail.rstrip(
' ') +
' ' * beforeAffectation
843 if afterAffectation
is not None:
845 aff.tail =
' ' * afterAffectation
847 aff.tail = aff.tail.lstrip(
' ') +
' ' * afterAffectation
849 aff.text = aff.text.replace(
' ',
'')
853 elif tag(elem)
in (
'if-stmt',
'if-then-stmt',
'else-if-stmt',
854 'where-stmt',
'where-construct-stmt',
'else-where-stmt',
855 'select-case-stmt',
'case-stmt',
856 'forall-stmt',
'forall-construct-stmt'):
857 if afterIfwherecase
is not None and elem.text
is not None:
858 if tag(elem) ==
'case-stmt':
860 elem.text = elem.text.rstrip(
' ') +
' ' * afterIfwherecase
862 elem.text = re.sub(
r'[ ]*\(',
' ' * afterIfwherecase +
'(',
864 if tag(elem)
in (
'if-then-stmt',
'else-if-stmt')
and beforeThen
is not None:
865 cond = elem.find(
'{*}condition-E')
866 cond.tail = re.sub(
r'\)[ ]*([a-zA-Z]*$)',
')' +
' ' * beforeThen +
r'\1',
868 elif tag(elem) ==
'if-stmt' and beforeIfaction
is not None:
869 cond = elem.find(
'{*}condition-E')
870 cond.tail = re.sub(
r'\)[ ]*$',
')' +
' ' * beforeIfaction, cond.tail)
871 elif tag(elem) ==
'where-stmt' and beforeIfaction
is not None:
872 cond = elem.find(
'{*}mask-E')
873 cond.tail = re.sub(
r'\)[ ]*$',
')' +
' ' * beforeIfaction, cond.tail)
874 elif tag(elem) ==
'forall-stmt' and beforeIfaction
is not None:
875 sub = elem.find(
'{*}forall-triplet-spec-LT')
876 sub.tail = re.sub(
r'\)[ ]*$',
')' +
' ' * beforeIfaction, sub.tail)
879 if beforeEndcnt
is not None or afterBegincnt
is not None:
880 for elem
in self.findall(
'.//{*}cnt/..'):
881 for cnt
in elem.findall(
'{*}cnt'):
882 ic = list(elem).index(cnt)
891 if '\n' in pstring
and '\n' in cnt.tail:
894 elif '\n' in pstring
and afterBegincnt
is not None:
896 cnt.tail =
' ' * afterBegincnt + cnt.tail.lstrip(
' ')
897 elif beforeEndcnt
is not None:
901 prev.text = prev.text.rstrip(
' ') +
' ' * beforeEndcnt
903 prev.tail = prev.tail.rstrip(
' ') +
' ' * beforeEndcnt
906 for key, val
in adjaKeyDesc.items():
907 num = getvalAdja(key)
909 for node
in self.findall(val[1]):
910 lf =
"[ ]*".join([
"(" + p +
")" for p
in key.split(
'_')])
911 repl = (
" " * num).join([
r"\{i}".format(i=i + 1)
912 for i, _
in enumerate(key.split(
'_'))])
913 node.text = re.sub(lf, repl, node.text, flags=re.IGNORECASE)