private void buildFromDocstring(@NotNull final PsiElement elementDefinition, boolean isProperty) { PyClass pyClass = null; final PyStringLiteralExpression docStringExpression = ((PyDocStringOwner) elementDefinition).getDocStringExpression(); if (elementDefinition instanceof PyClass) { pyClass = (PyClass) elementDefinition; myBody.add(PythonDocumentationProvider.describeDecorators(pyClass, TagItalic, BR, LCombUp)); myBody.add(PythonDocumentationProvider.describeClass(pyClass, TagBold, true, false)); } else if (elementDefinition instanceof PyFunction) { PyFunction pyFunction = (PyFunction) elementDefinition; if (!isProperty) { pyClass = pyFunction.getContainingClass(); if (pyClass != null) { myBody .addWith( TagSmall, PythonDocumentationProvider.describeClass(pyClass, TagCode, true, true)) .addItem(BR) .addItem(BR); } } myBody .add(PythonDocumentationProvider.describeDecorators(pyFunction, TagItalic, BR, LCombUp)) .add(PythonDocumentationProvider.describeFunction(pyFunction, TagBold, LCombUp)); if (docStringExpression == null) { addInheritedDocString(pyFunction, pyClass); } } else if (elementDefinition instanceof PyFile) { addModulePath((PyFile) elementDefinition); } if (docStringExpression != null) { myBody.addItem(BR); addFormattedDocString(myElement, docStringExpression.getStringValue(), myBody, myEpilog); } }
private static void addFormattedDocString( PsiElement element, @NotNull String docstring, ChainIterable<String> formattedOutput, ChainIterable<String> unformattedOutput) { final Project project = element.getProject(); List<String> formatted = PyStructuredDocstringFormatter.formatDocstring(element, docstring); if (formatted != null) { unformattedOutput.add(formatted); return; } boolean isFirstLine; final List<String> result = new ArrayList<String>(); String[] lines = removeCommonIndentation(docstring); // reconstruct back, dropping first empty fragment as needed isFirstLine = true; int tabSize = CodeStyleSettingsManager.getSettings(project).getTabSize(PythonFileType.INSTANCE); for (String line : lines) { if (isFirstLine && ourSpacesPattern.matcher(line).matches()) continue; // ignore all initial whitespace if (isFirstLine) { isFirstLine = false; } else { result.add(BR); } int leadingTabs = 0; while (leadingTabs < line.length() && line.charAt(leadingTabs) == '\t') { leadingTabs++; } if (leadingTabs > 0) { line = StringUtil.repeatSymbol(' ', tabSize * leadingTabs) + line.substring(leadingTabs); } result.add(combUp(line)); } formattedOutput.add(result); }
public PyDocumentationBuilder(PsiElement element, PsiElement originalElement) { myElement = element; myOriginalElement = originalElement; myResult = new ChainIterable<String>(); myProlog = new ChainIterable<String>(); myBody = new ChainIterable<String>(); myEpilog = new ChainIterable<String>(); myResult .add(myProlog) .addWith(TagCode, myBody) .add(myEpilog); // pre-assemble; then add stuff to individual cats as needed myResult = wrapInTag("html", wrapInTag("body", myResult)); myReassignmentChain = new ChainIterable<String>(); }
public String build() { final TypeEvalContext context = TypeEvalContext.userInitiated(myElement.getProject(), myElement.getContainingFile()); final PsiElement outerElement = myOriginalElement != null ? myOriginalElement.getParent() : null; final PsiElement elementDefinition = resolveToDocStringOwner(); final boolean isProperty = buildFromProperty(elementDefinition, outerElement, context); if (myProlog.isEmpty() && !isProperty && !isAttribute()) { myProlog.add(myReassignmentChain); } if (elementDefinition instanceof PyDocStringOwner) { buildFromDocstring(elementDefinition, isProperty); } else if (isAttribute()) { buildFromAttributeDoc(); } else if (elementDefinition instanceof PyNamedParameter) { buildFromParameter(context, outerElement, elementDefinition); } else if (elementDefinition != null && outerElement instanceof PyReferenceExpression) { myBody.addItem(combUp("\nInferred type: ")); PythonDocumentationProvider.describeExpressionTypeWithLinks( myBody, (PyReferenceExpression) outerElement, context); } if (elementDefinition != null && PythonDialectsTokenSetProvider.INSTANCE .getKeywordTokens() .contains(elementDefinition.getNode().getElementType())) { buildForKeyword(elementDefinition.getText()); } if (myBody.isEmpty() && myEpilog.isEmpty()) { return null; // got nothing substantial to say! } else { return myResult.toString(); } }