Создавать таблицы Markdown?

Есть ли способ сгенерировать таблицы из объектов (Python / Ruby / Java / C #)?

Я хочу программно создать простую таблицу. У меня есть несколько объектов, и я хотел бы сопоставить некоторые свойства с заголовками, а коллекцию - с строками.

Почему именно Markdown? Потому что позже я хотел бы отредактировать этот документ вручную. Прямо сейчас весь процесс выглядит так:

  • механизм отчетов находится на C #
  • есть объекты, из которых генерируется DOCX (есть промежуточный XML или что-то в этом роде)
  • почти всегда мне нужно делать мелкие исправления, и мне нужно открывать эти документы docx в MS Word
  • сложно просить команду разработчиков исправить каждую ошибку, потому что у них просто нет времени делать это немедленно, и мне нужно ждать следующего выпуска.

Я понял, что если бы я получил документ Markdown, я мог бы легко его отредактировать, вставить некоторые переменные и использовать pandoc для замены этих переменных заданными данными. Но чтобы получить Markdown, я должен знать, как разработчики могут создавать таблицы в Markdown.


person Simon    schedule 15.11.2012    source источник
comment
Вы не упоминаете Haskell. Если вы можете написать простой скрипт на Haskell, вы можете использовать pandoc API (в частности, Text.Pandoc.Builder), чтобы довольно легко создавать таблицы и записывать их в любом формате, поддерживаемом pandoc, включая markdown.   -  person John MacFarlane    schedule 16.11.2012
comment
Я не упомянул об этом, потому что не знаю haskell. пока что. Хм щас искал готовое решение. ‹Заголовки, строки› = ›таблица уценки. Если такого решения нет, я попробую написать что-то подобное, но как, черт возьми, интегрировать haskell в .NET-код? Нужно провести небольшое исследование ...   -  person Simon    schedule 16.11.2012
comment
К сожалению, Markdown (пока?) Не поддерживает таблицы, но некоторые расширения поддерживают. В частности, у Doxygen есть хорошее расширение таблицы для Markdown.   -  person Codie CodeMonkey    schedule 16.03.2013
comment
Пакет R pander - это то, что вы ищете.   -  person Stéphane Laurent    schedule 25.10.2013


Ответы (3)


Мне нужно было сделать примерно то же самое для создания таблиц Doxygen Markdown, поэтому я решил поделиться. Я успешно выполнил пример кода как в Python 2.7, так и в 3.3, хотя не могу утверждать, что тщательно тестировал его.

# Generates tables for Doxygen flavored Markdown.  See the Doxygen
# documentation for details:
#   http://www.doxygen.nl/manual/markdown.html#md_tables

# Translation dictionaries for table alignment
left_rule = {'<': ':', '^': ':', '>': '-'}
right_rule = {'<': '-', '^': ':', '>': ':'}

def evalute_field(record, field_spec):
    """
    Evalute a field of a record using the type of the field_spec as a guide.
    """
    if type(field_spec) is int:
        return str(record[field_spec])
    elif type(field_spec) is str:
        return str(getattr(record, field_spec))
    else:
        return str(field_spec(record))

def table(file, records, fields, headings, alignment = None):
    """
    Generate a Doxygen-flavor Markdown table from records.

    file -- Any object with a 'write' method that takes a single string
        parameter.
    records -- Iterable.  Rows will be generated from this.
    fields -- List of fields for each row.  Each entry may be an integer,
        string or a function.  If the entry is an integer, it is assumed to be
        an index of each record.  If the entry is a string, it is assumed to be
        a field of each record.  If the entry is a function, it is called with
        the record and its return value is taken as the value of the field.
    headings -- List of column headings.
    alignment - List of pairs alignment characters.  The first of the pair
        specifies the alignment of the header, (Doxygen won't respect this, but
        it might look good, the second specifies the alignment of the cells in
        the column.

        Possible alignment characters are:
            '<' = Left align (default for cells)
            '>' = Right align
            '^' = Center (default for column headings)
    """

    num_columns = len(fields)
    assert len(headings) == num_columns

    # Compute the table cell data
    columns = [[] for i in range(num_columns)]
    for record in records:
        for i, field in enumerate(fields):
            columns[i].append(evalute_field(record, field))

    # Fill out any missing alignment characters.
    extended_align = alignment if alignment != None else []
    if len(extended_align) > num_columns:
        extended_align = extended_align[0:num_columns]
    elif len(extended_align) < num_columns:
        extended_align += [('^', '<')
                           for i in range[num_columns-len(extended_align)]]

    heading_align, cell_align = [x for x in zip(*extended_align)]

    field_widths = [len(max(column, key=len)) if len(column) > 0 else 0
                    for column in columns]
    heading_widths = [max(len(head), 2) for head in headings]
    column_widths = [max(x) for x in zip(field_widths, heading_widths)]

    _ = ' | '.join(['{:' + a + str(w) + '}'
                    for a, w in zip(heading_align, column_widths)])
    heading_template = '| ' + _ + ' |'
    _ = ' | '.join(['{:' + a + str(w) + '}'
                    for a, w in zip(cell_align, column_widths)])
    row_template = '| ' + _ + ' |'

    _ = ' | '.join([left_rule[a] + '-'*(w-2) + right_rule[a]
                    for a, w in zip(cell_align, column_widths)])
    ruling = '| ' + _ + ' |'

    file.write(heading_template.format(*headings).rstrip() + '\n')
    file.write(ruling.rstrip() + '\n')
    for row in zip(*columns):
        file.write(row_template.format(*row).rstrip() + '\n')

Вот простой тестовый пример:

import sys

sys.stdout.write('State Capitals (source: Wikipedia)\n\n')

headings = ['State', 'Abrev.', 'Capital', 'Capital since', 'Population',
            'Largest Population?']

data = [('Alabama', 'AL', '1819', 'Montgomery', '1846', 155.4, False,
         205764),
        ('Alaska', 'AK', '1959', 'Juneau', '1906', 2716.7, False, 31275),
        ('Arizona', 'AZ', '1912', 'Phoenix', '1889',474.9, True, 1445632),
        ('Arkansas', 'AR', '1836', 'Little Rock', '1821', 116.2, True,
         193524)]

fields = [0, 1, 3, 4, 7, lambda rec: 'Yes' if rec[6] else 'No']

align = [('^', '<'), ('^', '^'), ('^', '<'), ('^', '^'), ('^', '>'),
         ('^','^')]

table(sys.stdout, data, fields, headings, align)

Дает такой вывод:

State Capitals (source: Wikipedia)

|  State   | Abrev. |   Capital   | Capital since | Population | Largest Population? |
| :------- | :----: | :---------- | :-----------: | ---------: | :-----------------: |
| Alabama  |   AL   | Montgomery  |     1846      |     205764 |         No          |
| Alaska   |   AK   | Juneau      |     1906      |      31275 |         No          |
| Arizona  |   AZ   | Phoenix     |     1889      |    1445632 |         Yes         |
| Arkansas |   AR   | Little Rock |     1821      |     193524 |         Yes         |

Doxygen передает это как:

Образец

person Codie CodeMonkey    schedule 16.03.2013
comment
Ваша table() функция использует str() без указания кодировки. При использовании с входными данными Unicode это вызовет UnicodeEncodeErrors. - person Alastair McCormack; 26.12.2015
comment
@AlastairMcCormack, это было какое-то время, но, должно быть, это был код Python 2.7. - person Codie CodeMonkey; 31.12.2015
comment
Это скорее примечание для других :) Недавно я ответил на чей-то вопрос, который ссылался на этот ответ, но использовал строки Unicode :) - person Alastair McCormack; 31.12.2015

У меня было требование создать Markdown программно для недавнего проекта, поэтому я создал библиотеку и разместил ее на GitHub. Надеюсь, вам это пригодится.

Проект называется MarkdownLog, и это легкая (то есть с минимальными зависимостями) переносимая библиотека .NET (PCL), которая может создавать Markdown из структур данных .NET, таких как коллекции и словари. Я использую его для регистрации внутренних структур данных программы в диагностических целях, но он также должен соответствовать вашим потребностям.

Вот как создается таблица Markdown из коллекции:

var data = new[]
{
    new{Year = 1991, Album = "Out of Time", Songs=11, Rating = "* * * *"},
    new{Year = 1992, Album = "Automatic for the People", Songs=12, Rating = "* * * * *"},
    new{Year = 1994, Album = "Monster", Songs=12, Rating = "* * *"}
};

Console.Write(data.ToMarkdownTable());

// Produces:
//
//     Year | Album                    | Songs | Rating   
//     ----:| ------------------------ | -----:| --------- 
//     1991 | Out of Time              |    11 | * * * *  
//     1992 | Automatic for the People |    12 | * * * * *
//     1994 | Monster                  |    12 | * * *    

Обратите внимание, что когда этот вывод анализируется с помощью синтаксического анализатора Markdown со вкусом GitHub, он создает таблицу HTML.

По умолчанию столбцы выравниваются на основе их типа данных (числа выравниваются по правому краю, строки по левому краю), а имена заголовков создаются из имен свойств объекта. Если это не то, что вам нужно, есть ряд переопределений, которые дают вам больше контроля над выводом.

Встроенная поддержка всех стандартных элементов Markdown, а также таблицы GFM. Я также добавил несколько дополнительных типов элементов (гистограмма, iOS UITableView), которые мне нужны, которые реализованы как блоки кода, поэтому они по-прежнему соответствуют стандарту Markdown.

Я только недавно загрузил код на GitHub, так что пока документация является базовой. При этом в проекте есть множество модульных тестов, которые должны продемонстрировать, как это работает.

Я ценю, что этот вопрос давно не задавали, но я надеюсь, что этот проект будет кому-то полезен.

person Wheelie    schedule 08.07.2014
comment
Я забыл сказать, хотел бы услышать отзывы или предложения - person Wheelie; 08.07.2014

Использование Apache Freemarker для рендеринга HTML с помощью кода Java, а затем преобразование его в Markdown. Здесь нет возможности перенести HTML-таблицу в уценку.

Flexmark-java для преобразования HTML-таблицы в Markdown

person user452384    schedule 26.07.2021