如何输出不带“的多列html”;寡妇;?

如何输出不带“的多列html”;寡妇;?,html,algorithm,page-layout,Html,Algorithm,Page Layout,我需要输出到HTML的分类链接列表中正好有三列文本。它们必须像报纸或杂志上的专栏一样展示。例如,如果总共有20行,第一列和第二列将包含7行,最后一列将包含6行。列表必须是动态的;它将定期更换 棘手的是链接是用标题分类的,而这个标题不能是“寡妇”。如果你有页面布局背景,你就会知道这意味着标题不能显示在列的底部——它们下面必须至少有一个链接,否则它们应该跳到下一列(我知道,如果我真的在做页面布局,技术上应该是两行,但在这种情况下,一行是可以接受的)。我很难弄明白如何完成这件事 这里有一个例子来说明我

我需要输出到HTML的分类链接列表中正好有三列文本。它们必须像报纸或杂志上的专栏一样展示。例如,如果总共有20行,第一列和第二列将包含7行,最后一列将包含6行。列表必须是动态的;它将定期更换

棘手的是链接是用标题分类的,而这个标题不能是“寡妇”。如果你有页面布局背景,你就会知道这意味着标题不能显示在列的底部——它们下面必须至少有一个链接,否则它们应该跳到下一列(我知道,如果我真的在做页面布局,技术上应该是两行,但在这种情况下,一行是可以接受的)。我很难弄明白如何完成这件事

这里有一个例子来说明我的意思:

Shopping Link 3 Link1 Link 1 Link 4 Link2 Link 2 Link 3 Link 3 Cars Link 1 Music Games Link 2 Link 1 Link 1 Link 2 News 购物链接3链接1 链接1链接4链接2 链接2链接3 连接3辆车 链接1音乐 游戏链接2链接1 链接1 链接2新闻 如您所见,“新闻”标题位于中间一栏的底部,“寡妇”也位于底部。这是不能接受的。我可以将它添加到下一列,但这会在第二列的底部产生不必要的大量空白。相反,整个清单需要重新平衡


我想知道是否有人对如何实现这一点有什么建议,或者是源代码或插件。Python更好,但任何语言都可以。我只是想把一般概念写下来。

一般要点是建立一个所有“可流动”项目(包括类别)的主列表,然后遍历该列表,根据需要调整每列的行数,这样就不会有类别保持寡居状态(或任何其他情况)

模块1
Dim类别作为新字典(字符串、列表(字符串))
副标题()
常量列为整数=3
'创建类别项目
Dim ShoppingList作为新列表(字符串)
Dim GamesList作为新列表(字符串)
Dim CarsList作为新列表(字符串)
将新闻列表变暗为新列表(字符串)
Dim MusicList作为新列表(字符串)
购物清单。添加(“链接1”)
购物清单。添加(“链接2”)
ShoppingList.Add(“Link3”)
GamesList.Add(“Link1”)
GamesList.Add(“Link2”)
GamesList.Add(“Link3”)
GamesList.Add(“Link4”)
CarsList.Add(“Link1”)
CarsList.Add(“Link2”)
新闻列表。添加(“链接1”)
新闻列表。添加(“链接2”)
新闻列表。添加(“链接3”)
音乐列表添加(“链接1”)
'创建类别
类别。添加(“购物”,购物清单)
类别。添加(“游戏”,游戏列表)
类别。添加(“汽车”,汽车列表)
类别。添加(“新闻”,新闻列表)
类别。添加(“音乐”,MusicList)
'统计每个类别及其项目
Dim TotalRows作为整数=类别。计数
对于类别中的每个kvp作为KeyValuePair(字符串的,列表(字符串的))的
TotalRows+=kvp.Value.Count
下一个
'在每个类别之间添加一个空格
TotalRows+=(Categories.Count-1)
'确定每列的行数
Dim RowsPerColumn As Integer=Int(TotalRows/Columns)+If((TotalRows Mod Columns)>0,1,0)
'建立一个主列表
Dim master作为新列表(字符串)
对于类别中的每个kvp作为KeyValuePair(字符串的,列表(字符串的))的
主添加(kvp.Key)
以kvp.Value中的字符串形式显示每个项目
主添加(项目)
下一个
母版。添加(“”)
下一个
'删除最后一个无效的空白项
master.RemoveAt(master.Count-1)
'确保列表中的RowsPerColumn'第项不是类别
尺寸调整为布尔值
做
已调整=错误
对于i As Integer=1的master.Count-1步骤RowsPerColumn-1
如果Categories.Keys.Contains(master(i))则
RowsPerColumn+=1'调整每列的行数(可以向上或向下)
调整后=正确
如果结束
下一个
调整时循环
'输出结果表
将sw用作新的IO.StreamWriter(“test.htm”)
西南书写线(“”)
西南书写线(“”)
西南书写线(“”)
对于j,将其作为整数=0到RowsPerColumn-1
西南书写线(“”)
Dim columnCount As Integer=0'列已写入
对于i As Integer=j到master.Count-1步RowsPerColumn
软件写入线(“&master(i)&”)
columnCount+=1
下一个
'如果实际写入的列数小于常量列数
如果columnCount
这看起来与我知道的其他页面布局算法类似。我们可以改变箱子的高度吗?如果我们少了一行,那么这些词“刚好合适”,底部没有多余的空间。此外,我们是否更喜欢最后一列的空格而不是其他列的空格?哇,这是一个多么好、彻底的答案啊。非常感谢您抽出时间。非常有用。
Module Module1

    Dim Categories As New Dictionary(Of String, List(Of String))

    Sub Main()

        Const Columns As Integer = 3

        ' create the category items
        Dim ShoppingList As New List(Of String)
        Dim GamesList As New List(Of String)
        Dim CarsList As New List(Of String)
        Dim NewsList As New List(Of String)
        Dim MusicList As New List(Of String)

        ShoppingList.Add("Link1")
        ShoppingList.Add("Link2")
        ShoppingList.Add("Link3")

        GamesList.Add("Link1")
        GamesList.Add("Link2")
        GamesList.Add("Link3")
        GamesList.Add("Link4")

        CarsList.Add("Link1")
        CarsList.Add("Link2")

        NewsList.Add("Link1")
        NewsList.Add("Link2")
        NewsList.Add("Link3")

        MusicList.Add("Link1")

        ' create the categories
        Categories.Add("Shopping", ShoppingList)
        Categories.Add("Games", GamesList)
        Categories.Add("Cars", CarsList)
        Categories.Add("News", NewsList)
        Categories.Add("Music", MusicList)

        ' count each category and its items
        Dim TotalRows As Integer = Categories.Count
        For Each kvp As KeyValuePair(Of String, List(Of String)) In Categories
            TotalRows += kvp.Value.Count
        Next

        ' add a space between each category
        TotalRows += (Categories.Count - 1)

        ' determine the number of rows per column
        Dim RowsPerColumn As Integer = Int(TotalRows / Columns) + If((TotalRows Mod Columns) > 0, 1, 0)

        ' build a master list
        Dim master As New List(Of String)
        For Each kvp As KeyValuePair(Of String, List(Of String)) In Categories
            master.Add(kvp.Key)
            For Each item As String In kvp.Value
                master.Add(item)
            Next
            master.Add(" ")
        Next

        ' remove the last invalid blank item
        master.RemoveAt(master.Count - 1)

        ' ensure that the RowsPerColumn'th-item in the list is not a category
        Dim adjusted As Boolean
        Do
            adjusted = False
            For i As Integer = 1 To master.Count - 1 Step RowsPerColumn - 1
                If Categories.Keys.Contains(master(i)) Then
                    RowsPerColumn += 1 ' adjust rows per column (could go up or down)
                    adjusted = True
                End If
            Next
        Loop While adjusted

        ' output resulting table
        Using sw As New IO.StreamWriter("test.htm")
            sw.WriteLine("<html>")
            sw.WriteLine("<body>")
            sw.WriteLine("<table cellspacing=""0"" cellpadding=""3"" border=""1"">")
            For j As Integer = 0 To RowsPerColumn - 1
                sw.WriteLine("<tr>")
                Dim columnCount As Integer = 0 ' columns written
                For i As Integer = j To master.Count - 1 Step RowsPerColumn
                    sw.WriteLine("<td>" & master(i) & "</td>")
                    columnCount += 1
                Next
                ' if the number of columns actually written was less than Columns constant
                If columnCount < Columns Then
                    For c As Integer = 0 To Columns - columnCount - 1
                        sw.WriteLine("<td>&nbsp;</td>")
                    Next
                End If
                sw.WriteLine("</tr>")
            Next
            sw.WriteLine("</table>")
            sw.WriteLine("</body>")
            sw.WriteLine("</html>")
        End Using

    End Sub

End Module