https://bitbucket.org/daniel_fort/magic-lantern
Raw File
Tip revision: 433cdd26e6990437e9dfe98beed54357b43564be authored by Daniel Fort on 25 January 2017, 03:38:10 UTC
Closed branch 550D_10bit_12bit
Tip revision: 433cdd2
readme2modulestrings.py
# extract module strings from README.rst

import sys, re
import subprocess
from datetime import datetime

from align_string_proportional import word_wrap
from rbf_read import extent_func, rbf_init_font
rbf_init_font("../../data/fonts/argnor23.rbf")

def run(cmd):
    try:
        p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        out = p.communicate()
        if p.returncode or out[1]:
            print >> sys.stderr, cmd
            print >> sys.stderr, out[0]
            print >> sys.stderr, out[1]
            exit(1)
        return out[0]
    except:
        print >> sys.stderr, sys.exc_info()
        exit(1)

# see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37506 for how to place some strings in a custom section
# (you must declare all strings as variables, not only the pointers)

def c_repr(name):
    if "\n" in name:
        s = "\n"
        for l in name.split("\n"):
            s += "    %s\n" % ('"%s\\n"' % l.replace('"', r'\"'))
        return s
    else:
        return '"%s"' % name.replace('"', r'\"')

strings = []
def add_string(name, value):
    a = chr(ord('a') + len(strings))
    print "static char __module_string_%s_name [] MODULE_STRINGS_SECTION = %s;" % (a, c_repr(name))
    print "static char __module_string_%s_value[] MODULE_STRINGS_SECTION = %s;" % (a, c_repr(value))

    strings.append((name, value))

def declare_string_section():
    print
    print('MODULE_STRINGS_START()')
    for i, s in enumerate(strings):
        a = chr(ord('a') + i)
        print "    MODULE_STRING(__module_string_%s_name, __module_string_%s_value)" % (a, a)
    print('MODULE_STRINGS_END()')
    
def is_command_available(name):
    """Check if command `name` is on PATH."""
    from distutils.spawn import find_executable
    return find_executable(name) is not None

# return the first command of the list that can be found on the OS
def get_command_of(commands):
    """Return the first command of the list `commands` that can be found on the OS."""
    for command in commands: 
        if is_command_available(command) == True:
            return command

inp = open("README.rst").read().replace("\r\n", "\n")
lines = inp.strip("\n").split("\n")
title = lines[0]

used_lines = []
for l in lines[2:]:
    if l.startswith("..") or l.strip().startswith(":"):
        continue
    
    used_lines.append(l)

inp = "\n".join(used_lines)
inp = inp.split("\n\n")

add_string("Name", title)

# extract user metadata from RST meta tags
tags = {}
for l in lines[2:]:
    l = l.strip()
    m = re.match("^:([^:]+):(.+)$", l)
    if m:
        name = m.groups()[0].strip()
        value = m.groups()[1].strip()
        if value.startswith("<") and value.endswith(">"):
            continue
        add_string(name, value)
        tags[name] = value

if "Author" not in tags and "Authors" not in tags:
    print >> sys.stderr, "Warning: 'Author/Authors' tag is missing. You should tell the world who wrote your module ;)"

if "License" not in tags:
    print >> sys.stderr, "Warning: 'License' tag is missing. Under what conditions we can use your module? Can we publish modified versions?"

if "Summary" not in tags:
    print >> sys.stderr, "Warning: 'Summary' tag is missing. It should be displayed as help in the Modules tab."

# extract readme body:
# intro -> "Description" tag;
# each section will become "Help page 1", "Help page 2" and so on

# possible available commands to check 
rst2htmlCommands = ["rst2html", "rst2html5", "rst2html.py", "rst2html5.py"]
rst2htmlCommand = get_command_of(rst2htmlCommands)

# render the RST as html -> txt without the metadata tags
# sed command at end is because Windows inserts CR characters all over the place. Removing them should be benign on other platforms. 
txt = run('cat README.rst | grep -v -E "^:([^:])+:.+$" | ' + rst2htmlCommand + ' | python ../html2text.py -b 700 | sed "s/\r$//"')

desc = ""
last_str = "Description"
help_page_num = 0
lines_per_page = 0
for p in txt.strip("\n").split("\n")[2:]:
    if p.startswith("# "): # new section
        help_page_num += 1
        add_string(last_str, desc)
        desc = ""
        last_str = "Help page %d" % help_page_num
        print >> sys.stderr, "Help page %d: %s" % (help_page_num, p.strip('# '))
        lines_per_page = 0
        p = p[2:].strip()
    desc += "%s\n" % p
    lines_per_page += 1
    if lines_per_page > 18:
        print >> sys.stderr, "Too many lines per page\n"
        exit(1)

add_string(last_str, desc)

# extract version info
# (prints the latest changeset that affected this module)
last_change_info = run("sh ../last_change_info.sh")

if len(last_change_info):
    last_change_date, last_changeset, author, commit_msg = last_change_info.split("\n")
    split = last_change_date.split(" ")
    seconds = float(split[0])
    last_change_date = datetime.utcfromtimestamp(seconds).strftime("%Y-%m-%d %H:%M:%S UTC")
    
    # trim changeset to 7 chars, like Bitbucket does
    last_changeset = last_changeset[:7]
    
    # trim commit msg to 700px
    size = extent_func(commit_msg)[0]
    if size > 700:
        new_size = 0
        new_msg = ""
        for c in commit_msg:
            new_size += extent_func(c)[0]
            if new_size > 700:
                break
            new_msg += c
        commit_msg = new_msg + "..."
        
    add_string("Last update", "%s on %s by %s:\n%s" % (last_changeset, last_change_date, author, commit_msg))

build_date = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S UTC")

# echo called from python in Windows behaves differently, better to avoid it.
if sys.platform == 'win32':
	build_user = run('whoami').replace("\n", "") + "@" + run('hostname').replace("\n", "")
else:
	build_user = run("echo `whoami`@`hostname`")

add_string("Build date", build_date)
add_string("Build user", build_user)

declare_string_section()
back to top