Merge pull request #932 from lmckenzi/IGRenderingChanges

Ig rendering changes
This commit is contained in:
Grahame Grieve 2022-10-07 08:05:28 +11:00 committed by GitHub
commit d820eea278
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 225 additions and 74 deletions

View File

@ -2,6 +2,7 @@ package org.hl7.fhir.r5.conformance;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.hl7.fhir.exceptions.DefinitionException;
@ -32,10 +33,46 @@ public class AdditionalBindingsRenderer {
private String doco;
private String docoShort;
private UsageContext usage;
private boolean any;
private boolean unchanged;
private boolean any = false;
private boolean isUnchanged = false;
private boolean matched = false;
private boolean removed = false;
private AdditionalBindingDetail compare;
private int count = 1;
private String getKey() {
// Todo: Consider extending this with content from usageContext if purpose isn't sufficiently differentiating
return purpose + Integer.toString(count);
}
private void incrementCount() {
count++;
}
private void setCompare(AdditionalBindingDetail match) {
compare = match;
match.matched = true;
}
private boolean alreadyMatched() {
return matched;
}
public String getDoco(boolean full) {
return full ? doco : docoShort;
}
public boolean unchanged() {
if (!isUnchanged)
return false;
if (compare==null)
return true;
isUnchanged = true;
isUnchanged = isUnchanged && ((purpose==null && compare.purpose==null) || purpose.equals(compare.purpose));
isUnchanged = isUnchanged && ((valueSet==null && compare.valueSet==null) || valueSet.equals(compare.valueSet));
isUnchanged = isUnchanged && ((doco==null && compare.doco==null) || doco.equals(compare.doco));
isUnchanged = isUnchanged && ((usage==null && compare.usage==null) || usage.equals(compare.usage));
return isUnchanged;
}
}
private static String STYLE_UNCHANGED = "opacity: 0.5;";
private static String STYLE_REMOVED = STYLE_UNCHANGED + "text-decoration: line-through;";
private List<AdditionalBindingDetail> bindings = new ArrayList<>();
private ProfileKnowledgeProvider pkp;
private String corePath;
@ -53,35 +90,87 @@ public class AdditionalBindingsRenderer {
this.md = md;
}
public void seeMaxBinding(Extension ext) {
public void seeMaxBinding(Extension ext) {
seeMaxBinding(ext, null, false);
}
public void seeMaxBinding(Extension ext, Extension compExt, boolean compare) {
seeBinding(ext, compExt, compare, "maximum");
}
protected void seeBinding(Extension ext, Extension compExt, boolean compare, String label) {
AdditionalBindingDetail abr = new AdditionalBindingDetail();
abr.purpose = "maximum";
abr.purpose = label;
abr.valueSet = ext.getValue().primitiveValue();
abr.unchanged = ext.hasUserData(ProfileUtilities.DERIVATION_EQUALS);
bindings.add(abr);
if (compare) {
abr.isUnchanged = compExt!=null && ext.getValue().primitiveValue().equals(compExt.getValue().primitiveValue());
abr.compare = new AdditionalBindingDetail();
abr.compare.valueSet = compExt==null ? null : compExt.getValue().primitiveValue();
} else {
abr.isUnchanged = ext.hasUserData(ProfileUtilities.DERIVATION_EQUALS);
}
bindings.add(abr);
}
public void seeMinBinding(Extension ext) {
AdditionalBindingDetail abr = new AdditionalBindingDetail();
abr.purpose = "minimum";
abr.valueSet = ext.getValue().primitiveValue();
abr.unchanged = ext.hasUserData(ProfileUtilities.DERIVATION_EQUALS);
bindings.add(abr);
seeMinBinding(ext, null, false);
}
public void seeMinBinding(Extension ext, Extension compExt, boolean compare) {
seeBinding(ext, compExt, compare, "minimum");
}
public void seeAdditionalBindings(List<Extension> list) {
for (Extension ext : list) {
AdditionalBindingDetail abr = new AdditionalBindingDetail();
abr.purpose = ext.getExtensionString("purpose");
abr.valueSet = ext.getExtensionString("valueSet");
abr.doco = ext.getExtensionString("documentation");
abr.docoShort = ext.getExtensionString("shortDoco");
abr.usage = (ext.hasExtension("usage")) && ext.getExtensionByUrl("usage").hasValueUsageContext() ? ext.getExtensionByUrl("usage").getValueUsageContext() : null;
abr.any = "any".equals(ext.getExtensionString("scope"));
abr.unchanged = ext.hasUserData(ProfileUtilities.DERIVATION_EQUALS);
bindings.add(abr);
seeAdditionalBindings(list, null, false);
}
public void seeAdditionalBindings(List<Extension> list, List<Extension> compList, boolean compare) {
HashMap<String, AdditionalBindingDetail> compBindings = new HashMap<String, AdditionalBindingDetail>();
if (compare && compList!=null) {
for (Extension ext : compList) {
AdditionalBindingDetail abr = additionalBinding(ext);
if (compBindings.containsKey(abr.getKey())) {
abr.incrementCount();
}
compBindings.put(abr.getKey(), abr);
}
}
}
for (Extension ext : list) {
AdditionalBindingDetail abr = additionalBinding(ext);
if (compare && compList!=null) {
AdditionalBindingDetail match = null;
do {
match = compBindings.get(abr.getKey());
if (abr.alreadyMatched())
abr.incrementCount();
} while (match!=null && abr.alreadyMatched());
if (match!=null)
abr.setCompare(match);
bindings.add(abr);
if (abr.compare!=null)
compBindings.remove(abr.compare.getKey());
} else
bindings.add(abr);
}
for (AdditionalBindingDetail b: compBindings.values()) {
b.removed = true;
bindings.add(b);
}
}
protected AdditionalBindingDetail additionalBinding(Extension ext) {
AdditionalBindingDetail abr = new AdditionalBindingDetail();
abr.purpose = ext.getExtensionString("purpose");
abr.valueSet = ext.getExtensionString("valueSet");
abr.doco = ext.getExtensionString("documentation");
abr.docoShort = ext.getExtensionString("shortDoco");
abr.usage = (ext.hasExtension("usage")) && ext.getExtensionByUrl("usage").hasValueUsageContext() ? ext.getExtensionByUrl("usage").getValueUsageContext() : null;
abr.any = "any".equals(ext.getExtensionString("scope"));
abr.isUnchanged = ext.hasUserData(ProfileUtilities.DERIVATION_EQUALS);
return abr;
}
public String render() throws IOException {
if (bindings.isEmpty()) {
@ -109,12 +198,11 @@ public class AdditionalBindingsRenderer {
boolean usage = false;
boolean any = false;
for (AdditionalBindingDetail binding : bindings) {
doco = doco || (fullDoco && binding.doco != null) || (!fullDoco && binding.docoShort != null) ;
usage = usage || binding.usage != null;
any = any || binding.any;
doco = doco || binding.getDoco(fullDoco)!=null || (binding.compare!=null && binding.compare.getDoco(fullDoco)!=null);
usage = usage || binding.usage != null || (binding.compare!=null && binding.compare.usage!=null);
any = any || binding.any || (binding.compare!=null && binding.compare.any);
}
XhtmlNode tr = new XhtmlNode(NodeType.Element, "tr");
children.add(tr);
tr.td().style("font-size: 11px").b().tx("Additional Bindings");
@ -130,37 +218,62 @@ public class AdditionalBindingsRenderer {
}
for (AdditionalBindingDetail binding : bindings) {
tr = new XhtmlNode(NodeType.Element, "tr");
if (binding.unchanged) {
tr.style("opacity: 0.5");
if (binding.unchanged()) {
tr.style(STYLE_REMOVED);
} else if (binding.removed) {
tr.style(STYLE_REMOVED);
}
children.add(tr);
BindingResolution br = pkp == null ? makeNullBr(binding) : pkp.resolveBinding(profile, binding.valueSet, path);
BindingResolution compBr = null;
if (binding.compare!=null && binding.compare.valueSet!=null)
compBr = pkp == null ? makeNullBr(binding.compare) : pkp.resolveBinding(profile, binding.compare.valueSet, path);
XhtmlNode valueset = tr.td().style("font-size: 11px");
if (binding.compare!=null && binding.valueSet.equals(binding.compare.valueSet))
valueset.style(STYLE_UNCHANGED);
if (br.url != null) {
tr.td().style("font-size: 11px").ah(Utilities.isAbsoluteUrl(br.url) || !pkp.prependLinks() ? br.url : corePath+br.url, binding.valueSet).tx(br.display);
valueset.ah(determineUrl(br.url), binding.valueSet).tx(br.display);
} else {
tr.td().style("font-size: 11px").span(null, binding.valueSet).tx(br.display);
valueset.span(null, binding.valueSet).tx(br.display);
}
if (binding.compare!=null && binding.compare.valueSet!=null && !binding.valueSet.equals(binding.compare.valueSet)) {
valueset.br();
valueset = valueset.span(STYLE_REMOVED, null);
if (compBr.url != null) {
valueset.ah(determineUrl(compBr.url), binding.compare.valueSet).tx(compBr.display);
} else {
valueset.span(null, binding.compare.valueSet).tx(compBr.display);
}
}
XhtmlNode purpose = tr.td().style("font-size: 11px");
if (binding.compare!=null && binding.purpose.equals(binding.compare.purpose))
purpose.style("font-color: darkgray");
renderPurpose(purpose, binding.purpose);
if (binding.compare!=null && binding.compare.purpose!=null && !binding.purpose.equals(binding.compare.purpose)) {
purpose.br();
purpose = purpose.span(STYLE_UNCHANGED, null);
renderPurpose(purpose, binding.compare.purpose);
}
renderPurpose(tr.td().style("font-size: 11px"), binding.purpose);
if (usage) {
if (binding.usage != null) {
// TODO: This isn't rendered at all yet. Ideally, we want it to render with comparison...
new DataRenderer(context).render(tr.td(), binding.usage);
} else {
tr.td();
}
}
if (any) {
if (binding.any) {
tr.td().style("font-size: 11px").tx("Any repeat");
} else {
tr.td().style("font-size: 11px").tx("All repeats");
}
String newRepeat = binding.any ? "Any repeats" : "All repeats";
String oldRepeat = binding.compare!=null && binding.compare.any ? "Any repeats" : "All repeats";
compareString(tr.td().style("font-size: 11px"), newRepeat, oldRepeat);
}
if (doco) {
String ds = fullDoco ? binding.doco : binding.docoShort;
if (ds != null) {
String d = fullDoco ? md.processMarkdown("Binding.description", ds) : ds;
tr.td().style("font-size: 11px").innerHTML(d);
if (binding.doco != null) {
String d = md.processMarkdown("Binding.description", fullDoco ? binding.doco : binding.docoShort);
String oldD = binding.compare==null ? null : md.processMarkdown("Binding.description.compare", fullDoco ? binding.compare.doco : binding.compare.docoShort);
tr.td().style("font-size: 11px").innerHTML(compareHtml(d, oldD));
} else {
tr.td().style("font-size: 11px");
}
@ -168,6 +281,28 @@ public class AdditionalBindingsRenderer {
}
}
private XhtmlNode compareString(XhtmlNode node, String newS, String oldS) {
if (oldS==null)
return node.tx(newS);
if (newS.equals(oldS))
return node.style(STYLE_UNCHANGED).tx(newS);
node.tx(newS);
node.br();
return node.span(STYLE_REMOVED,null).tx(oldS);
}
private String compareHtml(String newS, String oldS) {
if (oldS==null)
return newS;
if (newS.equals(oldS))
return "<span style=\"" + STYLE_UNCHANGED + "\">" + newS + "</span>";
return newS + "<br/><span style=\"" + STYLE_REMOVED + "\">" + oldS + "</span>";
}
private String determineUrl(String url) {
return Utilities.isAbsoluteUrl(url) || !pkp.prependLinks() ? url : corePath + url;
}
private void renderPurpose(XhtmlNode td, String purpose) {
switch (purpose) {
case "maximum":

View File

@ -325,7 +325,8 @@ public class ProfileUtilities extends TranslatingUtilities {
public static final int STATUS_ERROR = 3;
public static final int STATUS_FATAL = 4;
public static final String BASE_MODEL = "base.model";
public static final String BASE_PATH = "base.path";
public static final String DERIVATION_EQUALS = "derivation.equals";
public static final String DERIVATION_POINTER = "derived.pointer";
public static final String IS_DERIVED = "derived.fact";
@ -430,8 +431,6 @@ public class ProfileUtilities extends TranslatingUtilities {
String getLinkForUrl(String corePath, String s);
}
public List<ElementDefinition> getChildMap(StructureDefinition profile, ElementDefinition element) throws DefinitionException {
if (childMapCache .containsKey(element)) {
return childMapCache.get(element);
@ -504,7 +503,7 @@ public class ProfileUtilities extends TranslatingUtilities {
/**
* Given a Structure, navigate to the element given by the path and return the direct children of that element
*
* @param structure The structure to navigate into
* @param profile The structure to navigate into
* @param path The path of the element within the structure to get the children for
* @return A List containing the element children (all of them are Elements)
*/
@ -615,10 +614,9 @@ public class ProfileUtilities extends TranslatingUtilities {
* Given a base (snapshot) profile structure, and a differential profile, generate a new snapshot profile
*
* @param base - the base structure on which the differential will be applied
* @param differential - the differential to apply to the base
* @param derived - the differential to apply to the base
* @param url - where the base has relative urls for profile references, these need to be converted to absolutes by prepending this URL (e.g. the canonical URL)
* @param webUrl - where the base has relative urls in markdown, these need to be converted to absolutes by prepending this URL (this is not the same as the canonical URL)
* @param trimDifferential - if this is true, then the snap short generator will remove any material in the element definitions that is not different to the base
* @return
* @throws FHIRException
* @throws DefinitionException
@ -1142,7 +1140,7 @@ public class ProfileUtilities extends TranslatingUtilities {
// so we just copy it in
ElementDefinition outcome = updateURLs(url, webUrl, currentBase.copy());
outcome.setPath(fixedPathDest(contextPathDst, outcome.getPath(), redirector, contextPathSrc));
updateFromBase(outcome, currentBase);
updateFromBase(outcome, currentBase, srcSD.getUrl());
updateConstraintSources(outcome, srcSD.getUrl());
markDerived(outcome);
if (resultPathBase == null)
@ -1289,7 +1287,7 @@ public class ProfileUtilities extends TranslatingUtilities {
outcome.setPath(fixedPathDest(contextPathDst, outcome.getPath(), redirector, contextPathSrc));
if (res == null)
res = outcome;
updateFromBase(outcome, currentBase);
updateFromBase(outcome, currentBase, srcSD.getUrl());
if (diffMatches.get(0).hasSliceName()) {
outcome.setSliceName(diffMatches.get(0).getSliceName());
if (!diffMatches.get(0).hasMin() && (diffMatches.size() > 1 || slicer == null || slicer.getSlicing().getRules() != SlicingRules.CLOSED) && !currentBase.hasSliceName()) {
@ -1552,7 +1550,7 @@ public class ProfileUtilities extends TranslatingUtilities {
// we're just going to accept the differential slicing at face value
ElementDefinition outcome = updateURLs(url, webUrl, currentBase.copy());
outcome.setPath(fixedPathDest(contextPathDst, outcome.getPath(), redirector, contextPathSrc));
updateFromBase(outcome, currentBase);
updateFromBase(outcome, currentBase, srcSD.getUrl());
if (!diffMatches.get(0).hasSlicing())
outcome.setSlicing(makeExtensionSlicing());
@ -1627,7 +1625,7 @@ public class ProfileUtilities extends TranslatingUtilities {
// so we just copy it in
ElementDefinition outcome = updateURLs(url, webUrl, currentBase.copy());
outcome.setPath(fixedPathDest(contextPathDst, outcome.getPath(), redirector, contextPathSrc));
updateFromBase(outcome, currentBase);
updateFromBase(outcome, currentBase, srcSD.getUrl());
markDerived(outcome);
if (resultPathBase == null)
resultPathBase = outcome.getPath();
@ -1664,6 +1662,8 @@ public class ProfileUtilities extends TranslatingUtilities {
if (!outcome.getPath().startsWith(resultPathBase))
throw new DefinitionException(context.formatMessage(I18nConstants.ADDING_WRONG_PATH_IN_PROFILE___VS_, profileName, outcome.getPath(), resultPathBase));
result.getElement().add(outcome); // so we just copy it in
outcome.setUserData(BASE_MODEL, srcSD.getUrl());
outcome.setUserData(BASE_PATH, resultPathBase);
baseCursor++;
}
}
@ -1824,7 +1824,7 @@ public class ProfileUtilities extends TranslatingUtilities {
}
ElementDefinition outcome = updateURLs(url, webUrl, currentBase.copy());
outcome.setPath(fixedPathDest(contextPathDst, outcome.getPath(), redirector, contextPathSrc));
updateFromBase(outcome, currentBase);
updateFromBase(outcome, currentBase, srcSD.getUrl());
if (diffMatches.get(0).hasSlicing() || !diffMatches.get(0).hasSliceName()) {
updateFromSlicing(outcome.getSlicing(), diffMatches.get(0).getSlicing());
updateFromDefinition(outcome, diffMatches.get(0), profileName, closed, url, srcSD); // if there's no slice, we don't want to update the unsliced description
@ -1876,7 +1876,7 @@ public class ProfileUtilities extends TranslatingUtilities {
for (ElementDefinition baseItem : baseMatches) {
baseCursor = base.getElement().indexOf(baseItem);
outcome = updateURLs(url, webUrl, baseItem.copy());
updateFromBase(outcome, currentBase);
updateFromBase(outcome, currentBase, srcSD.getUrl());
outcome.setPath(fixedPathDest(contextPathDst, outcome.getPath(), redirector, contextPathSrc));
outcome.setSlicing(null);
if (!outcome.getPath().startsWith(resultPathBase))
@ -1903,6 +1903,8 @@ public class ProfileUtilities extends TranslatingUtilities {
outcome.setPath(fixedPathDest(contextPathDst, outcome.getPath(), redirector, contextPathSrc));
if (!outcome.getPath().startsWith(resultPathBase))
throw new DefinitionException(context.formatMessage(I18nConstants.ADDING_WRONG_PATH));
outcome.setUserData(BASE_PATH, outcome.getPath());
outcome.setUserData(BASE_MODEL, srcSD.getUrl());
result.getElement().add(outcome);
baseCursor++;
}
@ -1932,7 +1934,7 @@ public class ProfileUtilities extends TranslatingUtilities {
outcome = updateURLs(url, webUrl, currentBase.copy());
// outcome = updateURLs(url, diffItem.copy());
outcome.setPath(fixedPathDest(contextPathDst, outcome.getPath(), redirector, contextPathSrc));
updateFromBase(outcome, currentBase);
updateFromBase(outcome, currentBase, srcSD.getUrl());
outcome.setSlicing(null);
outcome.setMin(0); // we're in a slice, so it's only a mandatory if it's explicitly marked so
if (!outcome.getPath().startsWith(resultPathBase))
@ -2439,7 +2441,9 @@ public class ProfileUtilities extends TranslatingUtilities {
}
private void updateFromBase(ElementDefinition derived, ElementDefinition base) {
private void updateFromBase(ElementDefinition derived, ElementDefinition base, String baseProfileUrl) {
derived.setUserData(BASE_MODEL, baseProfileUrl);
derived.setUserData(BASE_PATH, base.getPath());
if (base.hasBase()) {
if (!derived.hasBase())
derived.setBase(new ElementDefinitionBaseComponent());
@ -3535,7 +3539,7 @@ public class ProfileUtilities extends TranslatingUtilities {
if (!child.getPath().endsWith(".id")) {
List<StructureDefinition> sdl = new ArrayList<>();
sdl.add(ed);
genElement(defFile == null ? "" : defFile+"-definitions.html#extension.", gen, r.getSubRows(), child, ed.getSnapshot().getElement(), sdl, true, defFile, true, full, corePath, imagePath, true, false, false, false, null, false, rc);
genElement(defFile == null ? "" : defFile+"-definitions.html#extension.", gen, r.getSubRows(), child, ed.getSnapshot().getElement(), sdl, true, defFile, true, full, corePath, imagePath, true, false, false, false, null, false, rc, "");
}
} else if (deep) {
List<ElementDefinition> children = new ArrayList<ElementDefinition>();
@ -4016,19 +4020,14 @@ public class ProfileUtilities extends TranslatingUtilities {
return piece;
}
public XhtmlNode generateTable(String defFile, StructureDefinition profile, boolean diff, String imageFolder, boolean inlineGraphics, String profileBaseFileName, boolean snapshot, String corePath, String imagePath,
boolean logicalModel, boolean allInvariants, Set<String> outputTracker, boolean active, boolean mustSupport, RenderingContext rc) throws IOException, FHIRException {
assert(diff != snapshot);// check it's ok to get rid of one of these
HierarchicalTableGenerator gen = new HierarchicalTableGenerator(imageFolder, inlineGraphics, true);
gen.setTranslator(getTranslator());
TableModel model = gen.initNormalTable(corePath, false, true, profile.getId()+(diff ? "d" : "s"), active);
public XhtmlNode generateTable(String defFile, StructureDefinition profile, boolean diff, String imageFolder, boolean inlineGraphics, String profileBaseFileName, boolean snapshot, String corePath, String imagePath,
boolean logicalModel, boolean allInvariants, Set<String> outputTracker, boolean active, boolean mustSupport, RenderingContext rc) throws IOException, FHIRException {
return generateTable(defFile, profile, diff, imageFolder, inlineGraphics, profileBaseFileName, snapshot, corePath, imagePath, logicalModel, allInvariants, outputTracker, active, mustSupport, rc, "");
}
public List<ElementDefinition> supplementMissingDiffElements(StructureDefinition profile) {
List<ElementDefinition> list = new ArrayList<>();
if (diff)
list.addAll(profile.getDifferential().getElement());
else
list.addAll(profile.getSnapshot().getElement());
List<StructureDefinition> profiles = new ArrayList<StructureDefinition>();
profiles.add(profile);
list.addAll(profile.getDifferential().getElement());
if (list.isEmpty()) {
ElementDefinition root = new ElementDefinition().setPath(profile.getType());
root.setId(profile.getType());
@ -4040,10 +4039,27 @@ public class ProfileUtilities extends TranslatingUtilities {
list.add(0, root);
}
}
if (diff) {
insertMissingSparseElements(list);
insertMissingSparseElements(list);
return list;
}
public XhtmlNode generateTable(String defFile, StructureDefinition profile, boolean diff, String imageFolder, boolean inlineGraphics, String profileBaseFileName, boolean snapshot, String corePath, String imagePath,
boolean logicalModel, boolean allInvariants, Set<String> outputTracker, boolean active, boolean mustSupport, RenderingContext rc, String anchorPrefix) throws IOException, FHIRException {
assert(diff != snapshot);// check it's ok to get rid of one of these
HierarchicalTableGenerator gen = new HierarchicalTableGenerator(imageFolder, inlineGraphics, true);
gen.setTranslator(getTranslator());
TableModel model = gen.initNormalTable(corePath, false, true, profile.getId()+(diff ? "d" : "s"), active);
List<ElementDefinition> list;
if (diff)
list = supplementMissingDiffElements(profile);
else {
list = new ArrayList<>();
list.addAll(profile.getSnapshot().getElement());
}
genElement(defFile == null ? null : defFile+"#", gen, model.getRows(), list.get(0), list, profiles, diff, profileBaseFileName, null, snapshot, corePath, imagePath, true, logicalModel, profile.getDerivation() == TypeDerivationRule.CONSTRAINT && usesMustSupport(list), allInvariants, null, mustSupport, rc);
List<StructureDefinition> profiles = new ArrayList<StructureDefinition>();
profiles.add(profile);
genElement(defFile == null ? null : defFile+"#", gen, model.getRows(), list.get(0), list, profiles, diff, profileBaseFileName, null, snapshot, corePath, imagePath, true, logicalModel, profile.getDerivation() == TypeDerivationRule.CONSTRAINT && usesMustSupport(list), allInvariants, null, mustSupport, rc, anchorPrefix);
try {
return gen.generate(model, imagePath, 0, outputTracker);
} catch (org.hl7.fhir.exceptions.FHIRException e) {
@ -4139,7 +4155,7 @@ public class ProfileUtilities extends TranslatingUtilities {
private Row genElement(String defPath, HierarchicalTableGenerator gen, List<Row> rows, ElementDefinition element, List<ElementDefinition> all, List<StructureDefinition> profiles, boolean showMissing, String profileBaseFileName, Boolean extensions,
boolean snapshot, String corePath, String imagePath, boolean root, boolean logicalModel, boolean isConstraintMode, boolean allInvariants, Row slicingRow, boolean mustSupport, RenderingContext rc) throws IOException, FHIRException {
boolean snapshot, String corePath, String imagePath, boolean root, boolean logicalModel, boolean isConstraintMode, boolean allInvariants, Row slicingRow, boolean mustSupport, RenderingContext rc, String anchorPrefix) throws IOException, FHIRException {
Row originalRow = slicingRow;
StructureDefinition profile = profiles == null ? null : profiles.get(profiles.size()-1);
Row typesRow = null;
@ -4201,7 +4217,7 @@ public class ProfileUtilities extends TranslatingUtilities {
row.setOpacity("0.5");
}
UnusedTracker used = new UnusedTracker();
String ref = defPath == null ? null : defPath + element.getId();
String ref = defPath == null ? null : defPath + anchorPrefix + element.getId();
String sName = tail(element.getPath());
if (element.hasSliceName())
sName = sName +":"+element.getSliceName();
@ -4276,7 +4292,7 @@ public class ProfileUtilities extends TranslatingUtilities {
Row childRow = chooseChildRowByGroup(gen, currRow, groups, child, element, isConstraintMode);
if (logicalModel || !child.getPath().endsWith(".id") || (child.getPath().endsWith(".id") && (profile != null) && (profile.getDerivation() == TypeDerivationRule.CONSTRAINT))) {
currRow = genElement(defPath, gen, childRow.getSubRows(), child, all, profiles, showMissing, profileBaseFileName, isExtension, snapshot, corePath, imagePath, false, logicalModel, isConstraintMode, allInvariants, currRow, mustSupport, rc);
currRow = genElement(defPath, gen, childRow.getSubRows(), child, all, profiles, showMissing, profileBaseFileName, isExtension, snapshot, corePath, imagePath, false, logicalModel, isConstraintMode, allInvariants, currRow, mustSupport, rc, anchorPrefix);
}
}
}

View File

@ -28,7 +28,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
}
public boolean render(XhtmlNode x, StructureDefinition sd) throws FHIRFormatError, DefinitionException, IOException {
x.getChildNodes().add(context.getProfileUtilities().generateTable(context.getDefinitionsTarget(), sd, true, context.getDestDir(), false, sd.getId(), false, context.getSpecificationLink(), "", false, false, null, false, false, context));
x.getChildNodes().add(context.getProfileUtilities().generateTable(context.getDefinitionsTarget(), sd, true, context.getDestDir(), false, sd.getId(), false, context.getSpecificationLink(), "", false, false, null, false, false, context, ""));
return true;
}