Skip to content

Commit

Permalink
[Core] Implemented multi-row / multi-column spans in DocBook
Browse files Browse the repository at this point in the history
  • Loading branch information
0x8000-0000 committed Apr 25, 2020
1 parent 6a93817 commit aef3e21
Show file tree
Hide file tree
Showing 10 changed files with 649 additions and 352 deletions.
53 changes: 49 additions & 4 deletions src/main/java/net/signbit/samx/AttributeVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public String getReference()
private String idAttribute = null;
private String nameAttribute = null;
private String referenceAttribute = null;
private String citationAttribute = null;

@Override
public Void visitClassAttr(SamXParser.ClassAttrContext ctx)
Expand Down Expand Up @@ -84,19 +85,26 @@ public Void visitReferenceAttr(SamXParser.ReferenceAttrContext ctx)
return null;
}

@Override
public Void visitCitationAttr(SamXParser.CitationAttrContext ctx)
{
citationAttribute = ctx.text().getText();
return null;
}

@Override
public String toString()
{
StringBuilder builder = new StringBuilder();

boolean isEmpty = true;

if ((! classAttributes.isEmpty()) || (idAttribute != null) || (nameAttribute != null))
if ((!classAttributes.isEmpty()) || (idAttribute != null) || (nameAttribute != null))
{
builder.append(' ');
}

if (! classAttributes.isEmpty())
if (!classAttributes.isEmpty())
{
if (docBookMode)
{
Expand Down Expand Up @@ -162,11 +170,48 @@ public String toString()

public void setDocBookMode()
{
docBookMode = true;
docBookMode = true;
}

public void setDitaMode()
{
ditaMode = true;
ditaMode = true;
}

private StringBuilder visitAttribute(char sigil, String text)
{
StringBuilder builder = new StringBuilder();

builder.append('(');
builder.append(sigil);
builder.append(text);
builder.append(')');

return builder;
}

public String toPlainString()
{
StringBuilder builder = new StringBuilder();

boolean isEmpty = true;

if (idAttribute != null)
{
builder.append(visitAttribute('#', idAttribute));
}

if (nameAttribute != null)
{
builder.append(visitAttribute('*', nameAttribute));
}

for (String className : classAttributes)
{
builder.append(visitAttribute('.', className));
}

return builder.toString();
}

}
220 changes: 220 additions & 0 deletions src/main/java/net/signbit/samx/GridVisitor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
/*
Copyright 2020 Florin Iucha
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package net.signbit.samx;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import org.antlr.v4.runtime.BufferedTokenStream;

import net.signbit.samx.parser.SamXParser;
import net.signbit.samx.parser.SamXParserBaseVisitor;
import net.signbit.samx.parser.SamXParserVisitor;

public class GridVisitor extends SamXParserBaseVisitor<StringBuilder>
{
private final BufferedTokenStream tokenStream;

public GridVisitor(BufferedTokenStream tokenStream)
{
this.tokenStream = tokenStream;
}

static class GridCell
{
int rowSpan = 1;
int colSpan = 1;

final List<SamXParser.AttributeContext> attributes;
final SamXParser.FlowContext flow;

GridCell(List<SamXParser.AttributeContext> attributes, SamXParser.OptionalFlowContext optionalFlowContext)
{
this.attributes = attributes;
if (optionalFlowContext != null)
{
flow = optionalFlowContext.flow();
}
else
{
flow = null;
}
}

void setSpan(String span)
{
for (char ch : span.toCharArray())
{
if (ch == '|')
{
colSpan++;
}
else if (ch == '-')
{
rowSpan++;
}
else
{
// error
}
}

if (colSpan > 1)
{
colSpan--;
}

if (rowSpan > 1)
{
rowSpan--;
}
}

public String getContent(SamXParserVisitor<StringBuilder> visitor)
{
StringBuilder builder = new StringBuilder();
if (flow != null)
{
builder.append(visitor.visitFlow(flow));
}
return builder.toString();
}

public boolean hasContent()
{
return flow != null && (!flow.getText().isEmpty());
}

public Object renderContent(SamXParserVisitor<Object> visitor)
{
return visitor.visitFlow(flow);
}

public String getAttributesPlain()
{
AttributeVisitor av = new AttributeVisitor();
for (SamXParser.AttributeContext ac : attributes)
{
av.visit(ac);
}
return av.toPlainString();
}
}

static class GeneralGridRow
{
final SamXParser.MetadataContext metadataContext;

final ArrayList<GridCell> cells = new ArrayList<>();

public int getColumnCount()
{
return cells.size();
}

GeneralGridRow(SamXParser.GeneralGridRowDataContext rdc)
{
metadataContext = rdc.metadata();

for (SamXParser.GeneralGridElementContext ggec : rdc.generalGridElement())
{
if (ggec.gridElement() != null)
{
GridVisitor.GridCell gc = new GridVisitor.GridCell(ggec.gridElement().attribute(), ggec.gridElement().optionalFlow());
cells.add(gc);
}
else if (ggec.spanGridElement() != null)
{
GridVisitor.GridCell gc = new GridVisitor.GridCell(ggec.spanGridElement().attribute(), ggec.spanGridElement().optionalFlow());
gc.setSpan(ggec.spanGridElement().MUL_COLSEP().getText());

for (int ii = 0; ii < gc.colSpan; ++ii)
{
cells.add(gc);
}
}
}
}
}

static class GeneralGridGroup
{
ArrayList<GridVisitor.GeneralGridRow> rows = new ArrayList<>();

int conditionColumnWidth = 0;
int columnWidths[];

GeneralGridGroup(SamXParser.GeneralGridGroupContext gggc, SamXParserVisitor<StringBuilder> visitor)
{
HashSet<Integer> columnCount = new HashSet<>();
for (SamXParser.GeneralGridRowContext rc : gggc.generalGridRow())
{
final SamXParser.GeneralGridRowDataContext rdc = rc.generalGridRowData();
if (rdc != null)
{
final GridVisitor.GeneralGridRow ggr = new GridVisitor.GeneralGridRow(rdc);

if (visitor != null)
{
final String attributeCondition = visitor.visitMetadata(ggr.metadataContext).toString();

if (conditionColumnWidth < attributeCondition.length())
{
conditionColumnWidth = attributeCondition.length();
}
}

rows.add(ggr);
columnCount.add(ggr.getColumnCount());
}
}

if (columnCount.size() != 1)
{
throw new RuntimeException("Invalid table specification: multiple table column sizes: " + columnCount.toString());
}

columnWidths = new int[columnCount.iterator().next()];

if (visitor != null)
{
for (GridVisitor.GeneralGridRow ggr : rows)
{
for (int ii = 0; ii < ggr.cells.size(); ++ii)
{
final GridVisitor.GridCell gc = ggr.cells.get(ii);
final String content = gc.getContent(visitor);

int rowSpanIndicator = 0;
if (gc.rowSpan > 1)
{
rowSpanIndicator = gc.rowSpan;
}

final int thisWidth = (int) Math.ceil((content.length() + rowSpanIndicator) / (double) (gc.colSpan));

if (columnWidths[ii] < thisWidth)
{
columnWidths[ii] = thisWidth;
}
}
}
}
}
}
}
Loading

0 comments on commit aef3e21

Please sign in to comment.