Rendering improvements for showing difference analysis (WIP)

This commit is contained in:
Grahame Grieve 2023-08-14 15:34:54 +10:00
parent b45f6caf60
commit 0fc4398dfc
3 changed files with 78 additions and 48 deletions

View File

@ -9,9 +9,12 @@ import java.util.Map;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.r5.comparison.VersionComparisonAnnotation;
import org.hl7.fhir.r5.model.BooleanType;
import org.hl7.fhir.r5.model.CodeSystem;
import org.hl7.fhir.r5.model.Enumerations.CodeSystemContentMode;
import org.hl7.fhir.r5.model.CodeSystem.CodeSystemFilterComponent;
import org.hl7.fhir.r5.model.CodeSystem.CodeSystemHierarchyMeaning;
import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent;
import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionDesignationComponent;
import org.hl7.fhir.r5.model.CodeSystem.ConceptPropertyComponent;
@ -29,6 +32,7 @@ import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.utilities.LoincLinker;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.i18n.I18nConstants;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
public class CodeSystemRenderer extends TerminologyRenderer {
@ -84,12 +88,12 @@ public class CodeSystemRenderer extends TerminologyRenderer {
tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Value", getContext().getLang()));
for (CodeSystemFilterComponent f : cs.getFilter()) {
tr = tbl.tr();
tr.td().tx(f.getCode());
tr.td().tx(f.getDescription());
VersionComparisonAnnotation.render(f, tr.td()).tx(f.getCode());
VersionComparisonAnnotation.render(f.getDescriptionElement(), tr.td()).tx(f.getDescription());
XhtmlNode td = tr.td();
for (Enumeration<org.hl7.fhir.r5.model.Enumerations.FilterOperator> t : f.getOperator())
td.tx(t.asStringValue()+" ");
tr.td().tx(f.getValue());
VersionComparisonAnnotation.render(t, td).tx(t.asStringValue()+" ");
VersionComparisonAnnotation.render(f.getValueElement(), tr.td()).tx(f.getValue());
}
}
}
@ -125,13 +129,13 @@ public class CodeSystemRenderer extends TerminologyRenderer {
if (hasRendered) {
tr.td().tx(ToolingExtensions.getPresentation(p, p.getCodeElement()));
}
tr.td().tx(p.getCode());
VersionComparisonAnnotation.render(p, tr.td()).tx(p.getCode());
if (hasURI) {
tr.td().tx(p.getUri());
VersionComparisonAnnotation.render(p.getUriElement(), tr.td()).tx(p.getUri());
}
tr.td().tx(p.hasType() ? p.getType().toCode() : "");
VersionComparisonAnnotation.render(p.getTypeElement(), tr.td()).tx(p.hasType() ? p.getType().toCode() : "");
if (hasDescription) {
tr.td().tx(p.getDescription());
VersionComparisonAnnotation.render(p.getDescriptionElement(), tr.td()).tx(p.getDescription());
}
}
return true;
@ -160,8 +164,9 @@ public class CodeSystemRenderer extends TerminologyRenderer {
features = "features"; // ?
}
return context.getContext().formatMessage(I18nConstants.RND_CS_CONTENT_SUPPLEMENT, features);
default:
throw new FHIRException("Unknown CodeSystemContentMode mode");
}
throw new FHIRException("Unknown CodeSystemContentMode mode");
}
private boolean generateCodeSystemContent(XhtmlNode x, CodeSystem cs, boolean hasExtensions, List<UsedConceptMap> maps, boolean props) throws FHIRFormatError, DefinitionException, IOException {
@ -169,7 +174,10 @@ public class CodeSystemRenderer extends TerminologyRenderer {
x.para().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Concepts", getContext().getLang()));
}
XhtmlNode p = x.para();
p.param("cs").code().tx(cs.getUrl());
VersionComparisonAnnotation.render(cs.getUrlElement(), p.param("cs")).code().tx(cs.getUrl());
makeCasedParam(p.param("cased"), cs, cs.getCaseSensitiveElement());
makeHierarchyParam(p.param("h"), cs, cs.getHierarchyMeaningElement());
p.paramValue("code-count", CodeSystemUtilities.countCodes(cs));
p.sentenceForParams(sentenceForContent(cs.getContent(), cs));
if (cs.getContent() == CodeSystemContentMode.NOTPRESENT) {
@ -236,6 +244,30 @@ public class CodeSystemRenderer extends TerminologyRenderer {
return hasExtensions;
}
private void makeHierarchyParam(XhtmlNode x, CodeSystem cs, Enumeration<CodeSystemHierarchyMeaning> hm) {
if (hm.hasValue()) {
String s = hm.getValue().getDisplay();
VersionComparisonAnnotation.render(hm, x).tx(" in a "+s+" heirarchy");
} else if (VersionComparisonAnnotation.hasDeleted(cs, "hierarchyMeaning")) {
makeHierarchyParam(x, null, (Enumeration<CodeSystemHierarchyMeaning>) VersionComparisonAnnotation.getDeleted(cs, "hierarchyMeaning").get(0));
} else if (CodeSystemUtilities.hasHierarchy(cs)) {
x.tx(" in an undefined heirarchy");
} else {
x.tx("");
}
}
private void makeCasedParam(XhtmlNode x, CodeSystem cs, BooleanType caseSensitiveElement) {
if (caseSensitiveElement.hasValue()) {
String s = caseSensitiveElement.getValue() == true? "case-sensitive" : "case-insensitive";
VersionComparisonAnnotation.render(caseSensitiveElement, x).tx(s);
} else if (VersionComparisonAnnotation.hasDeleted(cs, "caseSensitive")) {
makeCasedParam(x, null, (BooleanType) VersionComparisonAnnotation.getDeleted(cs, "caseSensitive").get(0));
} else {
x.tx("");
}
}
private void listConceptLanguages(CodeSystem cs, ConceptDefinitionComponent c, List<String> langs) {
for (ConceptDefinitionDesignationComponent cd : c.getDesignation()) {
if (cd.hasLanguage() && !langs.contains(cd.getLanguage()) && (!cs.hasLanguage() || !cs.getLanguage().equals(cd.getLanguage()))) {
@ -377,7 +409,7 @@ public class CodeSystemRenderer extends TerminologyRenderer {
if (link != null) {
td.ah(link).attribute("style", "white-space:nowrap").addText(c.getCode());
} else {
td.attribute("style", "white-space:nowrap").addText(c.getCode());
VersionComparisonAnnotation.render(c, td.attribute("style", "white-space:nowrap")).addText(c.getCode());
}
XhtmlNode a;
if (c.hasCodeElement()) {
@ -390,13 +422,13 @@ public class CodeSystemRenderer extends TerminologyRenderer {
}
if (hasDefinitions) {
td = tr.td();
if (c != null &&
c.hasDefinitionElement()) {
if (c != null &&c.hasDefinitionElement()) {
if (getContext().getLang() == null) {
if (hasMarkdownInDefinitions(cs))
addMarkdown(td, c.getDefinition());
else
td.addText(c.getDefinition());
if (hasMarkdownInDefinitions(cs)) {
addMarkdown(VersionComparisonAnnotation.renderDiv(c.getDefinitionElement(), td), c.getDefinition());
} else {
VersionComparisonAnnotation.render(c.getDefinitionElement(), td).addText(c.getDefinition());
}
} else if (getContext().getLang().equals("*")) {
boolean sl = false;
for (ConceptDefinitionDesignationComponent cd : c.getDesignation())
@ -404,9 +436,9 @@ public class CodeSystemRenderer extends TerminologyRenderer {
sl = true;
td.addText((sl ? cs.getLanguage("en")+": " : ""));
if (hasMarkdownInDefinitions(cs))
addMarkdown(td, c.getDefinition());
addMarkdown(VersionComparisonAnnotation.renderDiv(c.getDefinitionElement(), td), c.getDefinition());
else
td.addText(c.getDefinition());
VersionComparisonAnnotation.render(c.getDefinitionElement(), td).addText(c.getDefinition());
for (ConceptDefinitionDesignationComponent cd : c.getDesignation()) {
if (cd.getUse().is("http://terminology.hl7.org/CodeSystem/designation-usage", "definition") && cd.hasLanguage() && !c.getDefinition().equalsIgnoreCase(cd.getValue())) {
td.br();
@ -414,7 +446,7 @@ public class CodeSystemRenderer extends TerminologyRenderer {
}
}
} else if (getContext().getLang().equals(cs.getLanguage()) || (getContext().getLang().equals("en") && !cs.hasLanguage())) {
td.addText(c.getDefinition());
VersionComparisonAnnotation.render(c.getDefinitionElement(), td).addText(c.getDefinition());
} else {
for (ConceptDefinitionDesignationComponent cd : c.getDesignation()) {
if (cd.getUse().is("http://terminology.hl7.org/CodeSystem/designation-usage", "definition") && cd.hasLanguage() && cd.getLanguage().equals(getContext().getLang())) {
@ -591,7 +623,7 @@ public class CodeSystemRenderer extends TerminologyRenderer {
public void renderDisplayName(ConceptDefinitionComponent c, CodeSystem cs, XhtmlNode td) {
if (c.hasDisplayElement()) {
if (getContext().getLang() == null) {
td.addText(c.getDisplay());
VersionComparisonAnnotation.render(c.getDisplayElement(), td).addText(c.getDisplay());
} else if (getContext().getLang().equals("*")) {
boolean sl = false;
for (ConceptDefinitionDesignationComponent cd : c.getDesignation())
@ -605,7 +637,7 @@ public class CodeSystemRenderer extends TerminologyRenderer {
}
}
} else if (getContext().getLang().equals(cs.getLanguage()) || (getContext().getLang().equals("en") && !cs.hasLanguage())) {
td.addText(c.getDisplay());
VersionComparisonAnnotation.render(c.getDisplayElement(), td).addText(c.getDisplay());
} else {
for (ConceptDefinitionDesignationComponent cd : c.getDesignation()) {
if (cd.getUse().is("http://terminology.hl7.org/CodeSystem/designation-usage", "display") && cd.hasLanguage() && cd.getLanguage().equals(getContext().getLang())) {

View File

@ -2727,30 +2727,24 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
return ed.getPath().substring(ed.getPath().indexOf(".")+1);
}
public static String formatTypeSpecifiers(IWorkerContext context, ElementDefinition d) {
StringBuilder b = new StringBuilder();
public XhtmlNode formatTypeSpecifiers(IWorkerContext context, ElementDefinition d) {
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
boolean first = true;
for (Extension e : d.getExtensionsByUrl(ToolingExtensions.EXT_TYPE_SPEC)) {
if (first) first = false; else b.append("<br/>");
if (first) first = false; else x.br();
String cond = ToolingExtensions.readStringExtension(e, "condition");
String type = ToolingExtensions.readStringExtension(e, "type");
b.append("If <code>");
b.append(Utilities.escapeXml(cond));
b.append("</code> then the type is ");
x.tx("If ");
x.code().tx(cond);
x.tx(" then the type is ");
StructureDefinition sd = context.fetchTypeDefinition(type);
if (sd == null) {
b.append("<code>");
b.append(Utilities.escapeXml(type));
b.append("</code>");
x.code().tx(type);
} else {
b.append("<a href=\"");
b.append(sd.getWebPath());
b.append("\">");
b.append(Utilities.escapeXml(sd.getTypeName()));
b.append("</a>");
x.ah(sd.getWebPath()).tx(sd.getTypeName());
}
}
return b.toString();
return first ? null : x;
}
public XhtmlNode generateExtensionTable(String defFile, StructureDefinition ed, String imageFolder, boolean inlineGraphics, boolean full, String corePath, String imagePath, Set<String> outputTracker, RenderingContext rc) throws IOException, FHIRException {

View File

@ -1234,33 +1234,34 @@ public class ValueSetRenderer extends TerminologyRenderer {
li.tx(", ");
}
}
XhtmlNode wli = VersionComparisonAnnotation.render(f, li);
if (f.getOp() == FilterOperator.EXISTS) {
if (f.getValue().equals("true")) {
li.tx(f.getProperty()+" exists");
wli.tx(f.getProperty()+" exists");
} else {
li.tx(f.getProperty()+" doesn't exist");
wli.tx(f.getProperty()+" doesn't exist");
}
} else {
li.tx(f.getProperty()+" "+describe(f.getOp())+" ");
wli.tx(f.getProperty()+" "+describe(f.getOp())+" ");
if (e != null && codeExistsInValueSet(e, f.getValue())) {
String href = getContext().fixReference(getCsRef(e));
if (href.contains("#"))
href = href + "-"+Utilities.nmtokenize(f.getValue());
else
href = href + "#"+e.getId()+"-"+Utilities.nmtokenize(f.getValue());
li.ah(href).addText(f.getValue());
wli.ah(href).addText(f.getValue());
} else if ("concept".equals(f.getProperty()) && inc.hasSystem()) {
li.addText(f.getValue());
wli.addText(f.getValue());
ValidationResult vr = getContext().getWorker().validateCode(getContext().getTerminologyServiceOptions(), inc.getSystem(), inc.getVersion(), f.getValue(), null);
if (vr.isOk()) {
li.tx(" ("+vr.getDisplay()+")");
wli.tx(" ("+vr.getDisplay()+")");
}
}
else
li.addText(f.getValue());
wli.addText(f.getValue());
String disp = ToolingExtensions.getDisplayHint(f);
if (disp != null)
li.tx(" ("+disp+")");
wli.tx(" ("+disp+")");
}
}
}
@ -1273,7 +1274,8 @@ public class ValueSetRenderer extends TerminologyRenderer {
first = false;
else
li.tx(", ");
AddVsRef(vs.asStringValue(), li, vsRes);
XhtmlNode wli = VersionComparisonAnnotation.render(vs, li);
AddVsRef(vs.asStringValue(), wli, vsRes);
}
}
if (inc.hasExtension(ToolingExtensions.EXT_EXPAND_RULES) || inc.hasExtension(ToolingExtensions.EXT_EXPAND_GROUP)) {
@ -1289,12 +1291,14 @@ public class ValueSetRenderer extends TerminologyRenderer {
first = false;
else
li.tx(", ");
AddVsRef(vs.asStringValue(), li, vsRes);
XhtmlNode wli = VersionComparisonAnnotation.render(vs, li);
AddVsRef(vs.asStringValue(), wli, vsRes);
}
} else {
XhtmlNode xul = li.ul();
for (UriType vs : inc.getValueSet()) {
AddVsRef(vs.asStringValue(), xul.li(), vsRes);
XhtmlNode wli = VersionComparisonAnnotation.render(vs, xul.li());
AddVsRef(vs.asStringValue(), wli, vsRes);
}
}