34 def indent(self, nodeToUpdate=None, indentProgramunit=0, indentBranch=2,
37 :param nodeToUpdate: if None, the entire object is indented
38 :param indentProgramunit: number of space characters inside program unit
39 :param indentBranch: number of space characters fr other branches (do, if...)
40 :param exclDirectives: some lines are directives and must stay unindented. The cpp
41 directives are automatically recognized by fxtran but others
42 appear as FORTRAN comments and must be indentified here. This
43 option can take the following values:
44 - None: to recognize as directives the lines begining
45 with '!$OMP' (default)
46 - []: to suppress the exclusion
47 - [...]: to give another list of line beginings to consider
48 :return: same object but with indentation corrected
51 if nodeToUpdate
is None:
54 if exclDirectives
is None:
55 exclDirectives = [
'!$OMP']
57 def setLevel(elem, level, nextElem):
59 :param elem: element whose tail must be modifies
60 :param level: level of indentation
61 :param nextElem: next element
63 if elem.tail
is not None:
64 elem.tail = elem.tail.replace(
'\t',
' ')
65 excl = (nextElem
is not None and
66 (tag(nextElem) ==
'cpp' or
67 tag(nextElem) ==
'C' and
68 any(nextElem.text.startswith(d)
for d
in exclDirectives)))
70 elem.tail = re.sub(
'\n[ ]*',
'\n' +
' ' * level, elem.tail)
72 def indentRecur(elem, level, inConstruct):
74 :param elem: dom element
75 :param level: current level for elem
76 :param inConstruct: True if we are inside a construct
78 blocs = [
'file',
'program-unit',
'if-block',
'where-block',
'selectcase-block']
79 progstmt = [
'subroutine-stmt',
'program-stmt',
'module-stmt',
'function-stmt',
80 'submodule-stmt',
'procedure-stmt',
'interface-stmt']
81 endprogstmt = [
'end-' + s
for s
in progstmt]
82 interbranchstmt = [
'else-stmt',
'else-if-stmt',
'else-where-stmt']
83 branchstmt = [
'if-then-stmt',
'where-construct-stmt'] + interbranchstmt
84 endbranchstmt = [
'end-if-stmt',
'end-where-stmt']
89 for ie, sElem
in enumerate(elem):
92 if tag(sElem)
in progstmt:
93 currlevel += indentProgramunit
94 elif tag(sElem)
in branchstmt + [inConstruct +
'-stmt']:
95 currlevel += indentBranch
98 setLevel(sElem, currlevel, elem[ie + 1]
if ie + 1 < len(elem)
else None)
100 if tag(elem) ==
'selectcase-construct':
118 firstnumselect =
False
122 setLevel(laste[-1], level + indentBranch, sElem)
124 indentRecur(sElem, level + indentBranch * 2,
"")
125 if tag(sElem[-1]) ==
'end-select-case-stmt':
126 setLevel(sElem[-2], level, sElem[-1])
128 elif tag(sElem)
in blocs
or tag(sElem).endswith(
'-construct'):
130 if tag(sElem[0])
in interbranchstmt:
139 setLevel(laste[-1], level, sElem)
140 construct = tag(sElem)[:-10]
if tag(sElem).endswith(
'-construct')
else ""
141 indentRecur(sElem, currlevel, construct)
145 if tag(sElem)
in endprogstmt + endbranchstmt + [
'end-' + inConstruct +
'-stmt']:
146 setLevel(laste, level, sElem)
149 indentRecur(nodeToUpdate, 0,
"")
217 removeALL=False, addBegin=True, removeBegin=False):
219 :param nodeToUpdate: if None, the entire xml is updated
220 :param align: True to align begin of continued lines
221 :param removeALL: True to suppress all the continuation line characters ('&')
222 :param addBegin: True to add missing continuation line characters ('&')
223 at the begining of lines
224 :param removeBegin: True to suppress continuation line characters ('&')
225 at the begining of lines
227 When suppressed, the '&' are replaced by a space character
228 Comments after a '&' are lost
231 assert not (align
and removeALL),
"We cannot remove and align at the same time"
232 assert not (addBegin
and (removeALL
or removeBegin)), \
233 "We cannot remove and add, at the same time, continuation characters"
235 if nodeToUpdate
is None:
240 def recurReverse(elem, tail):
241 for ie
in range(len(elem))[::-1]:
243 parents[sElem] = elem
244 if tag(sElem) ==
'cnt':
248 while j < len(elem)
and tag(elem[j])
in (
'C',
'cpp'):
249 commentsAfter.append(elem[j])
251 nextNode = elem[j]
if j < len(elem)
else None
254 isend = ((sElem.tail
is not None and '\n' in sElem.tail)
or
255 len(commentsAfter) > 0)
258 if isend
and addBegin:
259 if sElem.tail
is not None and \
260 sElem.tail.replace(
'\n',
'').replace(
'\t',
'').lstrip(
' ') !=
'':
263 new = createElem(
'cnt', text=
'&')
266 while sElem.tail[i]
in (
' ',
'\n',
'\t'):
268 new.tail =
' ' + sElem.tail[i:]
269 sElem.tail = sElem.tail[:i]
270 elem.insert(ie + 1, new)
271 elif tag(nextNode) !=
'cnt':
273 new = createElem(
'cnt', text=
'&')
274 if len(commentsAfter) > 0:
278 while i < len(commentsAfter[-1].tail)
and \
279 commentsAfter[-1].tail[i]
in (
' ',
'\n',
'\t'):
281 new.tail =
' ' + commentsAfter[-1].tail[i:]
282 commentsAfter[-1].tail = commentsAfter[-1].tail[:i]
285 elem.insert(ie + 1 + len(commentsAfter), new)
288 if removeALL
or (removeBegin
and not isend):
290 for com
in commentsAfter[::-1]:
291 if tag(com) !=
'cpp':
298 if sElem.tail
is not None:
299 txt = sElem.tail.strip() +
' '
303 if elem[ie - 1].tail
is None:
304 elem[ie - 1].tail = txt
306 elem[ie - 1].tail += txt
310 recurReverse(sElem, tail)
312 def recurDirect(elem, ct, inCnt):
314 :param ct: current text
315 :param inCnt: -1 if we are not in a statement spanning several lines
316 elswhere contains the number of spaces to add
318 ignoreComment =
False
320 for ie, sElem
in enumerate(list(elem)):
322 isendcnt = tag(sElem) ==
'cnt' and \
323 ((sElem.tail
is not None and '\n' in sElem.tail)
or
324 (ie + 1 < len(elem)
and tag(elem[ie + 1]) ==
'C'))
325 ignoreComment = (ignoreComment
or
327 (ie + 1 < len(elem)
and tag(elem[ie + 1]) ==
'C')))
336 if isendcnt
or ignoreComment
or (inCnt != -1
and tag(sElem) ==
'cpp'):
339 if isendcnt
and inCnt == -1:
342 while not tag(topstmt).endswith(
'-stmt'):
343 topstmt = parents[topstmt]
346 if tag(topstmt) ==
'a-stmt':
347 patList = (
'=>',
'=',
r'\(')
348 elif tag(topstmt) ==
'call-stmt':
349 patList = (
r'\(',
r'call[ ]+\w',
'call ',
'call')
350 elif tag(topstmt) ==
'if-stmt':
351 patList = (
r'\(',
r'\)',
'if ',
'if')
352 elif tag(topstmt) ==
'where-stmt':
353 patList = (
r'\(',
r'\)',
'where ',
'where')
354 elif tag(topstmt) ==
'forall-stmt':
355 patList = (
r'\(',
r'\)',
'forall ',
'forall')
356 elif tag(topstmt) ==
'namelist-stmt':
357 patList = (
'/.*/',
'/',
'namelist')
358 elif tag(topstmt) ==
'subroutine-stmt':
359 patList = (
r'\(',
r'subroutine[ ]+\w',
'subroutine ',
'subroutine')
360 elif tag(topstmt) ==
'use-stmt':
361 patList = (
':',
r'use[ ]+\w',
'use ',
'use')
362 elif tag(topstmt) ==
'T-decl-stmt':
363 patList = (
'::',
r'\w,',
r'\w ',
r'\w')
364 elif tag(topstmt) ==
'print-stmt':
365 patList = (
'print', )
366 elif tag(topstmt) ==
'write-stmt':
367 patList = (
r'\)',
r'write[ ]*\(',
'write[ ]*',
'write')
368 elif tag(topstmt) ==
'procedure-stmt':
369 patList = (
'module[ ]+procedure[ ]*',
'module[ ]*',
'module')
371 patList = (
'::',
':',
r'\(',
'=>',
'=',
'[',
':',
'/')
377 mat = re.search(pat, ct, flags=re.IGNORECASE)
379 if ie + 1 < len(elem)
and tag(elem[ie + 1]) !=
'cnt':
385 inCnt = mat.end() - 1
390 if not (ie + 1 < len(elem)
and tag(elem[ie + 1]) ==
'cpp'):
391 if sElem.tail
is not None:
392 sElem.tail = re.sub(
'\n[ ]*',
'\n' +
' ' * inCnt, sElem.tail)
394 sElem.tail =
'\n' +
' ' * inCnt
396 if tag(sElem)
not in (
'C',
'cnt'):
397 ct += (sElem.text
if sElem.text
is not None else '')
398 ignoreComment =
False
402 ct, inCnt = recurDirect(sElem, ct, inCnt)
405 ct += (sElem.tail
if sElem.tail
is not None else '')
407 ct = ct.split(
'\n')[-1]
408 if tag(sElem)
not in (
'cnt',
'C',
'cpp'):
413 recurReverse(nodeToUpdate, 0)
414 recurDirect(nodeToUpdate,
"", -1)
421 beforeComma=0, afterComma=1,
422 beforeParenthesis=0, afterParenthesis=0,
423 beforeAffectation=1, afterAffectation=1, inAffectation=True,
424 beforeRangeDelim=0, afterRangeDelim=0,
425 beforeUseDelim=0, afterUseDelim=1,
426 beforeDeclDelim=1, afterDeclDelim=1,
427 inDeclDelim=True, afterTypeDecl=1,
428 beforeEqDo=0, afterEqDo=0,
429 beforeEqCall=0, afterEqCall=0,
430 beforeEqInit=0, afterEqInit=0,
431 beforeEndcnt=1, afterBegincnt=1,
432 afterIfwherecase=1, beforeThen=1, beforeIfaction=1,
434 endOfLine=True, afterName=0, inName=True,
435 beforeCmdsep=0, afterCmdsep=1,
436 adjacentKeywords=__NO_VALUE__, afterKeywords=__NO_VALUE__):
438 :param beforeOp, afterOp: number of spaces before and after operators
439 :param inOperator: True to suppress spaces in operators
440 :param beforeComma, afterComma: number of spaces before and after commas
441 :param beforeParenthesis, afterParenthesis: number of spaces before and after parenthesis
442 :param beforeAffectation, afterAffectation: number of spaces before and after
443 affectations or associations
444 :param inAffectation: True to suppress spaces in affectations and in association ('= >')
445 :param beforeRangeDelim, afterRangeDelim: number of spaces before and after range delimiters
446 :param beforeUseDelim, afterUseDelim: number of spaces before and after use delimiters (':')
447 :param beforeDeclDelim, afterDeclDelim: number of spaces before and after declaration and
448 enumerator delimiter ('::')
449 :param inDeclDelim: True to suppress spaces in declaration and enumerator delimiter (': :')
450 :param afterTypeDecl: number of spaces after the type in a declaration w/o '::'
451 (e.g. 'INTEGER I'); also for enumerators (minimum 1)
452 :param beforeEqDo, afterEqDo: number of spaces before and after '=' sign in DO and
454 :param beforeEqCall, afterEqCall: number of spaces before and after '=' sign
456 :param beforeEqInit, afterEqInit: number of spaces before and after '=' sign for init values
457 :param beforeEndcnt, afterBegincnt: number of spaces before a continuation chararcter at the
458 end of the line and after a continuation character
459 at the begining of a line
460 :param afterIfwherecase: number of spaces after the IF, ELSEIF, WHERE, ELSEWHERE,
461 SELECTCASE, CASE and FORALL keywords
462 :param beforeThen: number of spaces before the THEN keyword
463 :param beforeIfaction: number of spaces
464 between IF condition and action in one-line IF statement and
465 between FORALL specification and affectation in one-line FORALL
467 between WHERE mask and action in one-line WHERE statement
468 :param afterProgunit: between the program unit type (e.g. SUBROUTINE) and its name
469 :param endOfLine: True to suppress spaces at the end of the line
470 :param afterName: number of spaces after an indentifier, type or attribute name
471 :param inName: True to suppress spaces in identifier names
472 :param beforeCmdsep, afterCmdsep: number of spaces before and after command separator (';')
473 :param adjacentKeywords: describes the number of spaces to introduce between adjancent
474 keywords when this is legal (the list comes from the table
475 "6.2 Adjacent keywords where separating blanks are optional" of the
476 F2008 norm and has been complemented by "end select",
477 "implicit none" and "module procedure"; for the last two,
478 a minimum of 1 is required).
479 The allowed dictionnary keys are:
511 For example, use {'end_do':1} to write 'END DO' or
512 {'end_do':0} to write 'ENDDO' or
513 {'end_do':None} to not update the writting
514 or use adjacentKeywords=None to disable everything
515 :param afterKeywords: describes the number of spaces to introduce after keywords.
516 Some keywords need a more sophisticated treatment and are controled
517 by specific keys (e.g. CASE).
518 The keys are the keyword in lowercase, some names can be tricky
519 to guess (e.g. the key for ENDFILE is 'end-file'). By default
520 only a few are defined.
521 Use afterKeywords=None to disable everything.
523 To not update spaces, put None instead of an integer and False in booleans.
524 For example, to not change number of spaces after a comma, use afterComma=None
526 Updates are done in the following order:
530 'block_data': (1,
'.//{*}block-data-stmt'),
531 'double_precision': (1,
'.//{*}intrinsic-T-spec/{*}T-N'),
532 'else_if': (1,
'.//{*}else-if-stmt'),
533 'else_where': (0,
'.//{*}else-where-stmt'),
534 'end_associate': (1,
'.//{*}end-associate-stmt'),
535 'end_block': (1,
'.//{*}end-block-stmt'),
536 'end_block_data': (1,
'.//{*}end-block-data-stmt'),
537 'end_critical': (1,
'.//{*}end-critical-stmt'),
538 'end_do': (1,
'.//{*}end-do-stmt'),
539 'end_enum': (1,
'.//{*}end-enum-stmt'),
540 'end_file': (1,
'.//{*}end-file-stmt'),
541 'end_forall': (1,
'.//{*}end-forall-stmt'),
542 'end_function': (1,
'.//{*}end-function-stmt'),
543 'end_if': (1,
'.//{*}end-if-stmt'),
544 'end_interface': (1,
'.//{*}end-interface-stmt'),
545 'end_module': (1,
'.//{*}end-module-stmt'),
546 'end_procedure': (1,
'.//{*}end-procedure-stmt'),
547 'end_program': (1,
'.//{*}end-program-stmt'),
548 'end_selec': (1,
'.//{*}end-select-case-stmt'),
549 'end_select': (1,
'.//{*}end-select-T-stmt'),
550 'end_submodule': (1,
'.//{*}end-submodule-stmt'),
551 'end_subroutine': (1,
'.//{*}end-subroutine-stmt'),
552 'end_team': (1,
'.//{*}end-change-team-stmt'),
553 'end_type': (1,
'.//{*}end-T-stmt'),
554 'end_where': (1,
'.//{*}end-where-stmt'),
555 'go_to': (0,
'.//{*}goto-stmt'),
556 'in_out': (0,
'.//{*}intent-spec'),
557 'select_case': (1,
'.//{*}select-case-stmt'),
558 'select_type': (1,
'.//{*}select-T-stmt'),
559 'implicit_none': (1,
'.//{*}implicit-none-stmt'),
560 'module_procedure': (1,
'.//{*}procedure-stmt'),
572 assert adjacentKeywords
is None or adjacentKeywords == self.
__NO_VALUE__ or \
574 for k
in adjacentKeywords),
"Unknown key in **adjacentKeywords"
577 if adjacentKeywords
is None:
580 return adjaKeyDesc[key][0]
581 return adjacentKeywords.get(key, adjaKeyDesc[key][0])
583 def getvalAfter(key):
586 num = afterKeywords.get(key, afterKey.get(key,
None))
588 num = afterKey.get(key,
None)
591 assert afterProgunit
is None or afterProgunit >= 1
592 assert afterTypeDecl
is None or afterTypeDecl >= 1
593 for k
in (
'implicit_none',
'module_procedure'):
595 assert num
is None or num >= 1, \
596 "adjacentKeywords['" + k +
"'] must be at least 1 (is " + str(num) +
")"
597 for k
in (
'use',
'call',
'end-file',
'do'):
598 num = getvalAfter(k +
'-stmt')
599 assert num
is None or num >= 1, \
600 "afterKeywords['" + k +
"'] must be at least 1 (is " + str(num) +
")"
602 for elem
in self.iter():
603 isNotC = tag(elem) !=
'C'
605 if elem.tail
is None:
607 elem.tail = elem.tail.replace(
'\t',
' ')
610 if beforeParenthesis
is not None:
611 elem.tail = re.sub(
r"[ ]*\(",
" " * beforeParenthesis +
r"(", elem.tail)
612 elem.tail = re.sub(
r"[ ]*\)",
" " * beforeParenthesis +
r")", elem.tail)
613 if elem.text
is not None and isNotC:
614 elem.text = re.sub(
r"[ ]*\(",
" " * beforeParenthesis +
r"(", elem.text)
615 elem.text = re.sub(
r"[ ]*\)",
" " * beforeParenthesis +
r")", elem.text)
616 if afterParenthesis
is not None:
617 elem.tail = re.sub(
r"\([ ]*",
"(" +
" " * afterParenthesis, elem.tail)
618 elem.tail = re.sub(
r"\)[ ]*",
")" +
" " * afterParenthesis, elem.tail)
619 if elem.text
is not None and isNotC:
620 elem.text = re.sub(
r"\([ ]*",
"(" +
" " * afterParenthesis, elem.text)
621 elem.text = re.sub(
r"\)[ ]*",
")" +
" " * afterParenthesis, elem.text)
624 if beforeComma
is not None:
625 elem.tail = re.sub(
r"[ ]*,",
" " * beforeComma +
r",", elem.tail)
626 if elem.text
is not None and isNotC:
627 elem.text = re.sub(
r"[ ]*,",
" " * beforeComma +
r",", elem.text)
628 if afterComma
is not None:
629 elem.tail = re.sub(
r",[ ]*",
"," +
" " * afterComma, elem.tail)
630 if elem.text
is not None and isNotC:
631 elem.text = re.sub(
r",[ ]*",
"," +
" " * afterComma, elem.text)
635 elem.tail = re.sub(
r"[ ]*\n",
r"\n", elem.tail)
638 if tag(elem)
in (
'N',
'T-N',
'attribute-N'):
640 for nnn
in elem.findall(
'{*}n'):
641 if nnn.tail
is not None:
642 nnn.tail = nnn.tail.strip(
' ')
643 if elem.tail
is not None and afterName
is not None:
644 elem.tail =
' ' * afterName + elem.tail.lstrip(
' ')
647 elif tag(elem) ==
'lower-bound' and elem.tail
is not None and ':' in elem.tail:
648 if beforeRangeDelim
is not None:
649 elem.tail =
' ' * beforeRangeDelim + elem.tail.lstrip(
' ')
650 if afterRangeDelim
is not None:
651 elem.tail = elem.tail.rstrip(
' ') +
' ' * beforeRangeDelim
654 elif tag(elem) ==
'module-N' and elem.tail
is not None and ':' in elem.tail:
655 if beforeUseDelim
is not None:
656 elem.tail = re.sub(
r"[ ]*:",
" " * beforeUseDelim +
r":", elem.tail)
657 if afterUseDelim
is not None:
658 elem.tail = re.sub(
r":[ ]*",
":" +
" " * afterUseDelim, elem.tail)
662 elif tag(elem)
in (
'attribute',
'_T-spec_')
and elem.tail
is not None:
664 elem.tail = re.sub(
r":[ ]*:",
r"::", elem.tail)
665 if beforeDeclDelim
is not None:
666 elem.tail = re.sub(
r"[ ]*(:[ ]*:)",
' ' * beforeDeclDelim +
r"\1", elem.tail)
667 if afterDeclDelim
is not None:
668 elem.tail = re.sub(
r"(:[ ]*:)[ ]*",
r"\1" +
' ' * afterDeclDelim, elem.tail)
669 if tag(elem) ==
'_T-spec_' and afterTypeDecl
is not None:
670 elem.tail = elem.tail.rstrip(
' ') +
' ' * afterTypeDecl
674 elif tag(elem) ==
'enumerator-stmt' and elem.text
is not None:
677 elem.text = re.sub(
r":[ ]*:",
r"::", elem.text)
678 if beforeDeclDelim
is not None:
679 elem.text = re.sub(
r"[ ]*(:[ ]*:)",
' ' * beforeDeclDelim +
r"\1",
681 if afterDeclDelim
is not None:
682 elem.text = re.sub(
r"(:[ ]*:)[ ]*",
r"\1" +
' ' * afterDeclDelim,
684 elif afterTypeDecl
is not None:
685 elem.text = elem.text.rstrip(
' ') +
' ' * afterTypeDecl
688 elif (tag(elem)
in (
'subroutine-stmt',
'program-stmt',
'module-stmt',
'function-stmt',
689 'submodule-stmt',
'procedure-stmt',
'interface-stmt',
690 'end-subroutine-stmt',
'end-program-stmt',
691 'end-module-stmt',
'end-function-stmt',
692 'end-submodule-stmt',
'end-procedure-stmt',
'end-interface-stmt')
693 and afterProgunit
is not None):
694 if elem.text
is not None:
695 elem.text = elem.text.rstrip(
' ') +
' ' * afterProgunit
698 elif tag(elem)
in (
'do-V',
'V')
and elem.tail
is not None and '=' in elem.tail:
699 if beforeEqDo
is not None:
700 elem.tail = re.sub(
'[ ]*=',
' ' * beforeEqDo +
'=', elem.tail)
701 if afterEqDo
is not None:
702 elem.tail = re.sub(
'=[ ]*',
'=' +
' ' * beforeEqDo, elem.tail)
705 elif tag(elem) ==
'arg-N' and elem.tail
is not None and '=' in elem.tail:
706 if beforeEqCall
is not None:
707 elem.tail = re.sub(
'[ ]*=',
' ' * beforeEqCall +
'=', elem.tail)
708 if afterEqCall
is not None:
709 elem.tail = re.sub(
'=[ ]*',
'=' +
' ' * beforeEqCall, elem.tail)
712 elif (tag(elem)
in (
'EN-N',
'named-constant')
and
713 elem.tail
is not None and '=' in elem.tail):
714 if beforeEqInit
is not None:
715 elem.tail = re.sub(
'[ ]*=',
' ' * beforeEqInit +
'=', elem.tail)
716 if afterEqInit
is not None:
717 elem.tail = re.sub(
'=[ ]*',
'=' +
' ' * beforeEqInit, elem.tail)
719 elif tag(elem) ==
'smc':
720 if beforeCmdsep
is not None:
721 prev = self.getSiblings(elem, after=
False)
722 if len(prev) != 0
and prev[-1].tail
is not None:
723 prev[-1].tail =
' ' * beforeCmdsep + prev[-1].tail.lstrip(
' ')
724 if afterCmdsep
is not None and elem.tail
is not None:
725 elem.tail = elem.tail.rstrip(
' ') +
' ' * afterCmdsep
728 elif tag(elem) ==
'associate-N' and elem.tail
is not None and '=' in elem.tail:
729 if beforeAffectation
is not None:
730 elem.tail = re.sub(
'[ ]*=',
' ' * beforeAffectation +
'=', elem.tail)
731 if afterAffectation
is not None:
732 elem.tail = re.sub(
'>[ ]*',
'>' +
' ' * beforeAffectation, elem.tail)
734 elem.tail = re.sub(
r'=[ ]*>',
'=>', elem.tail)
748 for elem
in self.iter():
750 if tag(elem) ==
'op-E':
751 for op
in elem.findall(
'{*}op'):
752 if beforeOp
is not None:
753 io = list(elem).index(op)
756 if prev.tail
is None:
757 prev.tail =
' ' * beforeOp
759 prev.tail = prev.tail.rstrip(
' ') +
' ' * beforeOp
760 if afterOp
is not None:
762 op.tail =
' ' * afterOp
764 op.tail = op.tail.lstrip(
' ') +
' ' * afterOp
766 for oo
in op.findall(
'{*}o'):
767 if oo.tail
is not None:
768 oo.tail = oo.tail.strip(
' ')
771 elif tag(elem)
in (
'a-stmt',
'pointer-a-stmt'):
773 for aff
in elem.findall(
'{*}a'):
774 if beforeAffectation
is not None:
775 prev = elem[list(elem).index(aff) - 1]
776 if prev.tail
is None:
777 prev.tail =
' ' * beforeAffectation
779 prev.tail = prev.tail.rstrip(
' ') +
' ' * beforeAffectation
780 if afterAffectation
is not None:
782 aff.tail =
' ' * afterAffectation
784 aff.tail = aff.tail.lstrip(
' ') +
' ' * afterAffectation
786 aff.text = aff.text.replace(
' ',
'')
790 elif tag(elem)
in (
'if-stmt',
'if-then-stmt',
'else-if-stmt',
791 'where-stmt',
'where-construct-stmt',
'else-where-stmt',
792 'select-case-stmt',
'case-stmt',
793 'forall-stmt',
'forall-construct-stmt'):
794 if afterIfwherecase
is not None and elem.text
is not None:
795 if tag(elem) ==
'case-stmt':
797 elem.text = elem.text.rstrip(
' ') +
' ' * afterIfwherecase
799 elem.text = re.sub(
r'[ ]*\(',
' ' * afterIfwherecase +
'(',
801 if tag(elem)
in (
'if-then-stmt',
'else-if-stmt')
and beforeThen
is not None:
802 cond = elem.find(
'{*}condition-E')
803 cond.tail = re.sub(
r'\)[ ]*([a-zA-Z]*$)',
')' +
' ' * beforeThen +
r'\1',
805 elif tag(elem) ==
'if-stmt' and beforeIfaction
is not None:
806 cond = elem.find(
'{*}condition-E')
807 cond.tail = re.sub(
r'\)[ ]*$',
')' +
' ' * beforeIfaction, cond.tail)
808 elif tag(elem) ==
'where-stmt' and beforeIfaction
is not None:
809 cond = elem.find(
'{*}mask-E')
810 cond.tail = re.sub(
r'\)[ ]*$',
')' +
' ' * beforeIfaction, cond.tail)
811 elif tag(elem) ==
'forall-stmt' and beforeIfaction
is not None:
812 sub = elem.find(
'{*}forall-triplet-spec-LT')
813 sub.tail = re.sub(
r'\)[ ]*$',
')' +
' ' * beforeIfaction, sub.tail)
816 if beforeEndcnt
is not None or afterBegincnt
is not None:
817 for elem
in self.findall(
'.//{*}cnt/..'):
818 for cnt
in elem.findall(
'{*}cnt'):
819 ic = list(elem).index(cnt)
828 if '\n' in pstring
and '\n' in cnt.tail:
831 elif '\n' in pstring
and afterBegincnt
is not None:
833 cnt.tail =
' ' * afterBegincnt + cnt.tail.lstrip(
' ')
834 elif beforeEndcnt
is not None:
838 prev.text = prev.text.rstrip(
' ') +
' ' * beforeEndcnt
840 prev.tail = prev.tail.rstrip(
' ') +
' ' * beforeEndcnt
843 for key, val
in adjaKeyDesc.items():
844 num = getvalAdja(key)
846 for node
in self.findall(val[1]):
847 lf =
"[ ]*".join([
"(" + p +
")" for p
in key.split(
'_')])
848 repl = (
" " * num).join([
r"\{i}".format(i=i + 1)
849 for i, _
in enumerate(key.split(
'_'))])
850 node.text = re.sub(lf, repl, node.text, flags=re.IGNORECASE)