Skip to content

Commit

Permalink
Make it possible to "peek" Evaluate and PageNumberReference segments (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
bertfrees authored and kalaspuffar committed Aug 26, 2019
1 parent cc5077c commit d95131a
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 22 deletions.
56 changes: 43 additions & 13 deletions src/org/daisy/dotify/formatter/impl/row/SegmentProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Function;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
Expand Down Expand Up @@ -57,6 +58,8 @@ class SegmentProcessor implements SegmentProcessing {
private CurrentResult cr;
private boolean closed;
private String blockId;
private Function<PageNumberReference,String> pagenumResolver;
private Function<Evaluate,String> expressionResolver;

SegmentProcessor(String blockId, List<Segment> segments, int flowWidth, CrossReferenceHandler refs, Context context, int available, BlockMargin margins, FormatterCoreContext fcontext, RowDataProperties rdp) {
this.refs = refs;
Expand All @@ -70,6 +73,17 @@ class SegmentProcessor implements SegmentProcessing {
this.significantContent = calculateSignificantContent(this.segments, context, rdp);
this.spc = new SegmentProcessorContext(fcontext, rdp, margins, flowWidth, available);
this.blockId = blockId;
this.pagenumResolver = (refs == null)
? (rs)->"??"
: (rs)->{
Integer page = refs.getPageNumber(rs.getRefId());
if (page==null) {
return "??";
} else {
return "" + rs.getNumeralStyle().format(page);
}
};
this.expressionResolver = (e)->e.getExpression().render(getContext());
initFields();
}

Expand Down Expand Up @@ -99,6 +113,9 @@ class SegmentProcessor implements SegmentProcessing {
this.closed = template.closed;
this.significantContent = template.significantContent;
this.blockId = template.blockId;
this.pagenumResolver = template.pagenumResolver;
// can't simply copy because getContext() of template would be used
this.expressionResolver = (e)->e.getExpression().render(getContext());
}

/**
Expand Down Expand Up @@ -239,6 +256,20 @@ private void initFields() {
if (blockId != null && !"".equals(blockId)) {
groupIdentifiers.add(blockId);
}
// reset resolved values and (re)set resolvers
for (Segment s : segments) {
switch (s.getSegmentType()) {
case Reference:
PageNumberReference rs = (PageNumberReference)s;
rs.setResolver(pagenumResolver);
break;
case Evaluate:
Evaluate e = (Evaluate)s;
e.setResolver(expressionResolver);
break;
default:
}
}
// produce group markers and anchors
getNext(false, LineProperties.DEFAULT);
}
Expand Down Expand Up @@ -446,18 +477,12 @@ private Optional<CurrentResult> layoutLeaderSegment(LeaderSegment ls) {
}

private Optional<CurrentResult> layoutPageSegment(PageNumberReference rs) {
if (refs!=null) {
rs.setResolver(()->{
Integer page = refs.getPageNumber(rs.getRefId());
if (page==null) {
return "??";
} else {
return "" + rs.getNumeralStyle().format(page);
}
});
} else {
rs.setResolver(()->"??");
}
// This is done to reset the state of the PageNumberReference, i.e. to "unfreeze" its
// value. It is safe to do this because by the time we get here the translator has not had
// the chance to resolve() the segment yet (the segment has only been available as a
// FollowingText). Still, it would be nicer if deep copies would be made of the segments
// when needed, or if the segments would be completely stateless.
rs.setResolver(pagenumResolver);
//TODO: translate references using custom language?
TranslatableWithContext spec;
spec = TranslatableWithContext.from(segments, segmentIndex-1)
Expand All @@ -475,7 +500,12 @@ private Optional<CurrentResult> layoutPageSegment(PageNumberReference rs) {
}

private Optional<CurrentResult> layoutEvaluate(Evaluate e) {
e.setResolver(()->e.getExpression().render(getContext()));
// This is done to reset the state of the Evaluate, i.e. to "unfreeze" its value. It is safe
// to do this because by the time we get here the translator has not had the chance to
// resolve() the segment yet (the segment has only been available as a FollowingText).
// Still, it would be nicer if deep copies would be made of the segments when needed, or if
// the segments would be completely stateless.
e.setResolver(expressionResolver);
if (!e.peek().isEmpty()) { // Don't create a new row if the evaluated expression is empty
// Note: this could be handled more generally (also for regular text) in layout().
TranslatableWithContext spec = TranslatableWithContext.from(segments, segmentIndex-1)
Expand Down
10 changes: 5 additions & 5 deletions src/org/daisy/dotify/formatter/impl/segment/Evaluate.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.daisy.dotify.formatter.impl.segment;

import java.util.Optional;
import java.util.function.Supplier;
import java.util.function.Function;

import org.daisy.dotify.api.formatter.DynamicContent;
import org.daisy.dotify.api.formatter.TextProperties;
Expand All @@ -17,7 +17,7 @@ public class Evaluate implements Segment {
private final DynamicContent expression;
private final TextProperties props;
private final boolean markCapitalLetters;
private Supplier<String> v = ()->"";
private Function<Evaluate,String> v = (x)->"";
private String resolved;

/**
Expand Down Expand Up @@ -84,21 +84,21 @@ public boolean equals(Object obj) {

@Override
public String peek() {
return resolved==null?v.get():resolved;
return resolved==null?v.apply(this):resolved;
}

@Override
public String resolve() {
if (resolved==null) {
resolved = v.get();
resolved = v.apply(this);
if (resolved == null) {
resolved = "";
}
}
return resolved;
}

public void setResolver(Supplier<String> v) {
public void setResolver(Function<Evaluate,String> v) {
this.resolved = null;
this.v = v;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.daisy.dotify.formatter.impl.segment;

import java.util.function.Supplier;
import java.util.function.Function;

import org.daisy.dotify.api.formatter.NumeralStyle;

Expand All @@ -14,7 +14,7 @@ public class PageNumberReference implements Segment {
private final String refid;
private final NumeralStyle style;
private final boolean markCapitalLetters;
private Supplier<String> v=()->"";
private Function<PageNumberReference,String> v = (x)->"";
private String resolved;

public PageNumberReference(String refid, NumeralStyle style, boolean markCapitalLetters) {
Expand Down Expand Up @@ -90,15 +90,15 @@ public String peek() {
@Override
public String resolve() {
if (resolved==null) {
resolved = v.get();
resolved = v.apply(this);
if (resolved == null) {
resolved = "";
}
}
return resolved;
}

public void setResolver(Supplier<String> v) {
public void setResolver(Function<PageNumberReference,String> v) {
this.resolved = null;
this.v = v;
}
Expand Down

0 comments on commit d95131a

Please sign in to comment.