void (@NotNull final PyDocStringOwner elementDefinition, boolean isProperty) { final PyStringLiteralExpression ownDocstring = getEffectiveDocStringExpression(elementDefinition); final PyStringLiteralExpression effectiveDocstring = modifyDocStringByOwnerType(ownDocstring, elementDefinition, isProperty); if (PyUtil.isTopLevel(elementDefinition)) { final PsiFile containing = elementDefinition.getContainingFile(); if (containing instanceof PyFile) { final HtmlChunk linkToModule = getLinkToModule((PyFile)containing); if (linkToModule != null) { myProlog.append(HtmlChunk.div() .setClass("bottom") .children( HtmlChunk.icon("AllIcons.Nodes.Package", AllIcons.Nodes.Package), HtmlChunk.nbsp(), linkToModule.code() )); } } } if (elementDefinition instanceof PyClass pyClass) { myBody.append(PythonDocumentationProvider.describeDecorators(pyClass, HtmlChunk.br())); myBody.append(PythonDocumentationProvider.describeClass(pyClass, myContext)); if (effectiveDocstring != null) { // add class attributes described either in the init doc or class doc addAttributesSection(effectiveDocstring); if (effectiveDocstring == ownDocstring) { final PyFunction init = pyClass.findMethodByName(PyNames.INIT, false, myContext); if (init != null) { // add init parameters described in the class doc addFunctionSpecificSections(effectiveDocstring, init); } } } } else if (elementDefinition instanceof PyFunction pyFunction) { myBody.append(PythonDocumentationProvider.describeDecorators(pyFunction, HtmlChunk.br())); myBody.append(PythonDocumentationProvider.describeFunction(pyFunction, myContext, false)); final PyClass pyClass = pyFunction.getContainingClass(); if (!isProperty && pyClass != null) { final HtmlChunk link = getLinkToClass(pyClass, true); if (link != null) { myProlog.append(HtmlChunk.div() .setClass("bottom") .children( HtmlChunk.icon("AllIcons.Nodes.Class", AllIcons.Nodes.Class), HtmlChunk.nbsp(), link.code() )); } } if (effectiveDocstring != null) { addFunctionSpecificSections(effectiveDocstring, pyFunction); // if function is init without doc we will take attributes from the class doc if (effectiveDocstring != ownDocstring && PyUtil.isInitOrNewMethod(pyFunction)) { addAttributesSection(effectiveDocstring); } } } else if (elementDefinition instanceof PyFile pyFile) { addModulePath(pyFile); } else if (elementDefinition instanceof PyTargetExpression target) { addTargetDocumentation(target, isProperty); } final String formatterInput = effectiveDocstring != null && !isProperty ? effectiveDocstring.getStringValue() : null; if (StringUtil.isEmpty(formatterInput) && myFormatterFragments.isEmpty()) return; final DocstringFormatterRequest output = PyStructuredDocstringFormatter.formatDocstring(myElement, new DocstringFormatterRequest( StringUtil.notNullize(formatterInput), myFormatterFragments), List.of(PyStructuredDocstringFormatter.FORMATTER_FRAGMENTS_FLAG)); if (output != null) { myContent.appendRaw(output.getBody()); fillFormattedSections(output.getFragments()); } else { // if docstring turned out PLAIN, but suddenly we have fragments or body to handle if (effectiveDocstring != null) { myContent.append(updateLines(myElement, Strings.notNullize(formatterInput))); } fillFormattedSections(myFormatterFragments); } }