Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #1265. Support setting column widths #1270

Merged
merged 4 commits into from
Mar 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Improvement::
Bug Fixes::

* -s CLI option should be changed to -e to align with Asciidoctor (#1237) (@mojavelinux)
* Column#setWidth is ignored (#1265) (@Vampire)

=== Compatible changes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,5 @@ enum VerticalAlignment {
*/
void setGrid(String grid);

void assignColumnWidths();
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.asciidoctor.jruby.internal.RubyObjectWrapper;
import org.jruby.RubyArray;
import org.jruby.RubyNil;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;

import java.util.AbstractList;
Expand Down Expand Up @@ -72,6 +73,26 @@ public List<Row> getHeader() {
return rows.getHeader();
}

@Override
public void assignColumnWidths() {
int widthBase = 0;
RubyArray autowidthCols = getRuntime().newArray();
for (Column column : getColumns()) {
int width = column.getWidth();
if (width < 0) {
autowidthCols.add(((ColumnImpl)column).getRubyObject());
} else {
widthBase += width;
}
}
ThreadContext threadContext = getRuntime().getThreadService().getCurrentContext();

getRubyObject().callMethod(threadContext, "assign_column_widths", new IRubyObject[] {
getRuntime().newFixnum(widthBase),
autowidthCols.isEmpty() ? getRuntime().getNil() : autowidthCols
});
}

private class Rows extends RubyObjectWrapper {

public Rows(IRubyObject rubyNode) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import org.asciidoctor.util.TestHttpServer
class GithubContributorsBlockMacro extends BlockMacroProcessor {

private static final String IMAGE = 'image'
private static final String WIDTHS = 'widths'

GithubContributorsBlockMacro(String macroName) {
super(macroName)
Expand All @@ -29,12 +30,22 @@ class GithubContributorsBlockMacro extends BlockMacroProcessor {
table.grid = 'rows'
table.title = "Github contributors of $target"

List<Integer> widths = [1,2,2]
if (attributes.containsKey(WIDTHS)) {
widths = (attributes[WIDTHS] as String).split(',').collect {Integer.parseInt(it) }
}
// Create the columns 'Login' and 'Contributions'
Column avatarColumn = createTableColumn(table, 0)
avatarColumn.width = widths[0]
Column loginColumn = createTableColumn(table, 1)
loginColumn.width = widths[1]
Column contributionsColumn = createTableColumn(table, 2)
contributionsColumn.width = widths[2]
contributionsColumn.horizontalAlignment = Table.HorizontalAlignment.CENTER

table.columns << avatarColumn
table.columns << loginColumn
table.columns << contributionsColumn
table.assignColumnWidths()
// Create the single header row with the column titles
Row headerRow = createTableRow(table)
headerRow.cells << createTableCell(avatarColumn, 'Avatar')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,35 @@ import org.asciidoctor.test.extension.ClasspathHelper
import org.asciidoctor.util.TestHttpServer
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import org.jsoup.select.Elements
import spock.lang.Specification
import spock.lang.TempDir

import static java.nio.charset.StandardCharsets.UTF_8

class WhenABlockMacroProcessorCreatesATable extends Specification {

public static final String FIRST_TD = 'td:first-child'
public static final String SECOND_TD = 'td:nth-child(2)'
public static final String THIRD_TD = 'td:nth-child(3)'
public static final String IMG_ELEMENT = 'img'
public static final String COL = 'col'
public static final String STYLE = 'style'
public static final String WIDTH = 'width'
public static final String WIDTH_2 = '2%'
public static final String WIDTH_3 = '3%'
public static final String WIDTH_20 = '20%'
public static final String WIDTH_40 = '40%'
public static final String CONTRIBUTOR = 'bob'
public static final String BLOCKMACRO_NAME = 'githubcontributors'

public static final String AVATAR_URL_REGEXP = /https:\/\/avatars.githubusercontent.com\/u\/.*/
public static final String CSS_QUERY_TABLE = 'table'
public static final String CLASS_GRID_ROWS = 'grid-rows'
public static final String CLASS_HALIGN_LEFT = 'halign-left'
public static final String CLASS_HALIGN_CENTER = 'halign-center'
public static final String ATTR_SRC = 'src'
public static final int THREE = 3

private Asciidoctor asciidoctor

Expand All @@ -30,6 +46,12 @@ class WhenABlockMacroProcessorCreatesATable extends Specification {
= AsciidoctorJRuby contributors

githubcontributors::asciidoctor/asciidoctorj[]
'''

private static final String DOCUMENT_WITH_NEGATIVE_WIDTHS = '''
= AsciidoctorJRuby contributors

githubcontributors::asciidoctor/asciidoctorj[widths="2,3,-1"]
'''

private ClasspathHelper classpathResources
Expand Down Expand Up @@ -60,18 +82,62 @@ githubcontributors::asciidoctor/asciidoctorj[]
asciidoctor.convert(DOCUMENT, options)

then:
Document htmlDocument = Jsoup.parse(resultFile, 'UTF-8')
Document htmlDocument = Jsoup.parse(resultFile, UTF_8.name())

Elements cols = htmlDocument.select(COL)
cols.size() == THREE
cols.get(0).attr(STYLE).contains(WIDTH_20) || cols.get(0).attr(WIDTH).equals(WIDTH_20)
cols.get(1).attr(STYLE).contains(WIDTH_40) || cols.get(1).attr(WIDTH).equals(WIDTH_40)
cols.get(2).attr(STYLE).contains(WIDTH_40) || cols.get(2).attr(WIDTH).equals(WIDTH_40)

htmlDocument.select(CSS_QUERY_TABLE).hasClass(CLASS_GRID_ROWS)

htmlDocument.select(FIRST_TD).every { tdElement -> tdElement.select(IMG_ELEMENT).size() == 1 }
htmlDocument.select(FIRST_TD).every { tdElement -> tdElement.select(IMG_ELEMENT)[0].attr(ATTR_SRC) =~ AVATAR_URL_REGEXP }

htmlDocument.select(SECOND_TD).size() == htmlDocument.select(SECOND_TD) != 0
htmlDocument.select(SECOND_TD).size() != 0

htmlDocument.select(SECOND_TD).every { tdElement -> tdElement.hasClass(CLASS_HALIGN_LEFT) }
htmlDocument.select(THIRD_TD).every { tdElement -> tdElement.hasClass(CLASS_HALIGN_CENTER) }

htmlDocument.select(SECOND_TD).find { tdElement -> tdElement.text() == CONTRIBUTOR } != null
}

def "the table should be rendered to html with negative widths"() {
given:
asciidoctor.javaExtensionRegistry().blockMacro(BLOCKMACRO_NAME, GithubContributorsBlockMacro)
File resultFile = new File(tempDir, 'resultWithNegativeWidth.html')

when:
def options = Options.builder()
.safe(SafeMode.SAFE)
.inPlace(false)
.baseDir(tempDir)
.toDir(tempDir)
.toFile(resultFile)
.build()
asciidoctor.convert(DOCUMENT_WITH_NEGATIVE_WIDTHS, options)

then:
Document htmlDocument = Jsoup.parse(resultFile, UTF_8.name())

Elements cols = htmlDocument.select(COL)
cols.size() == THREE
cols.get(0).attr(STYLE).contains(WIDTH_2) || cols.get(0).attr(WIDTH).equals(WIDTH_2)
cols.get(1).attr(STYLE).contains(WIDTH_3) || cols.get(1).attr(WIDTH).equals(WIDTH_3)
cols.get(2).attr(STYLE).length() == 0 && cols.get(2).attr(WIDTH).length() == 0

htmlDocument.select('table').hasClass('grid-rows')
htmlDocument.select(CSS_QUERY_TABLE).hasClass(CLASS_GRID_ROWS)

htmlDocument.select(FIRST_TD).every { tdElement -> tdElement.select(IMG_ELEMENT).size() == 1 }
htmlDocument.select(FIRST_TD).every { tdElement -> tdElement.select(IMG_ELEMENT)[0].attr('src') =~ AVATAR_URL_REGEXP }
htmlDocument.select(FIRST_TD).every { tdElement -> tdElement.select(IMG_ELEMENT)[0].attr(ATTR_SRC) =~ AVATAR_URL_REGEXP }

htmlDocument.select(SECOND_TD).size() == htmlDocument.select(SECOND_TD) != 0
htmlDocument.select(SECOND_TD).size() != 0

htmlDocument.select(SECOND_TD).every { tdElement -> tdElement.hasClass('halign-left') }
htmlDocument.select(THIRD_TD).every { tdElement -> tdElement.hasClass('halign-center') }
htmlDocument.select(SECOND_TD).every { tdElement -> tdElement.hasClass(CLASS_HALIGN_LEFT) }
htmlDocument.select(THIRD_TD).every { tdElement -> tdElement.hasClass(CLASS_HALIGN_CENTER) }

htmlDocument.select(SECOND_TD).find { tdElement -> tdElement.text() == CONTRIBUTOR } != null
}
Expand Down
4 changes: 3 additions & 1 deletion config/codenarc/codenarc.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ ruleset {
ruleset('rulesets/braces.xml') {
exclude 'IfStatementBraces'
}
ruleset('rulesets/size.xml')
ruleset('rulesets/size.xml') {
exclude 'AbcMetric'
}
ruleset('rulesets/junit.xml') {
// Does not play well with Spock tests
exclude 'JUnitPublicNonTestMethod'
Expand Down
Loading