예제 #1
0
    def get_time_signature (self):
        "Return time sig as a (beat, beat-type) tuple. For compound signatures,"
        "return either (beat, beat,..., beat-type) or ((beat,..., type), "
        "(beat,..., type), ...)."
        if self._time_signature_cache:
            return self._time_signature_cache

        try:
            mxl = self.get_named_attribute ('time')
            if not mxl:
                return None

            if mxl.get_maybe_exist_named_child ('senza-misura'):
                # TODO: Handle pieces without a time signature!
                ly.warning (_ ("Senza-misura time signatures are not yet supported!"))
                return (4, 4)
            else:
                signature = []
                current_sig = []
                for i in mxl.get_all_children ():
                    if isinstance (i, Beats):
                        beats = string.split (i.get_text ().strip (), "+")
                        current_sig = [int (j) for j in beats]
                    elif isinstance (i, BeatType):
                        current_sig.append (int (i.get_text ()))
                        signature.append (current_sig)
                        current_sig = []
                if isinstance (signature[0], list) and len (signature) == 1:
                    signature = signature[0]
                self._time_signature_cache = signature
                return signature
        except (KeyError, ValueError):
            self.message (_ ("Unable to interpret time signature! Falling back to 4/4."))
            return (4, 4)
예제 #2
0
    def message (self, msg):
        ly.warning (msg)

        p = self
        while p:
            ly.progress ('  In: <%s %s>\n' % (p._name, ' '.join (['%s=%s' % item for item in p._attribute_dict.items ()])))
            p = p.get_parent ()
예제 #3
0
def main():
    files = do_options()

    # should parse files[] to read \version?
    if global_options.show_rules:
        show_rules(sys.stdout, global_options.from_version,
                   global_options.to_version)
        sys.exit(0)

    identify()

    errors = 0
    for f in files:
        if f == '-':
            f = ''
        elif not os.path.isfile(f):
            ly.error(_("%s: Unable to open file") % f)
            errors += 1
            continue
        try:
            errors += do_one_file(f)
        except UnknownVersion:
            ly.error(_("%s: Unable to determine version.  Skipping") % f)
            errors += 1
        except InvalidVersion as v:
            ly.error(_("%s: Invalid version string `%s' \n"
                       "Valid version strings consist of three numbers, "
                       "separated by dots, e.g. `2.8.12'") % (f, v.version))
            errors += 1

    if errors:
        ly.warning(gettext.ngettext("There was %d error.",
                                    "There were %d errors.", errors) % errors)
        sys.exit(1)
예제 #4
0
    def message(self, msg):
        ly.warning(msg)

        p = self
        while p:
            ly.progress('  In: <%s %s>\n' % (p._name, ' '.join(
                ['%s=%s' % item for item in p._attribute_dict.items()])))
            p = p.get_parent()
예제 #5
0
    def get_instrument(self, id):
        if not self._id_instrument_name_dict:
            self.generate_id_instrument_dict()

        instrument_name = self._id_instrument_name_dict.get(id)
        if instrument_name:
            return instrument_name
        else:
            ly.warning(_("Unable to find instrument for ID=%s\n") % id)
            return "Grand Piano"
예제 #6
0
    def get_instrument (self, id):
        if not self._id_instrument_name_dict:
            self.generate_id_instrument_dict()

        instrument_name = self._id_instrument_name_dict.get (id)
        if instrument_name:
            return instrument_name
        else:
            ly.warning (_ ("Unable to find instrument for ID=%s\n") % id)
            return "Grand Piano"
예제 #7
0
def rational_to_lily_duration(rational_len):
    d = musicexp.Duration()

    rational_len.normalize_self()
    d_log = {
        1: 0,
        2: 1,
        4: 2,
        8: 3,
        16: 4,
        32: 5,
        64: 6,
        128: 7,
        256: 8,
        512: 9
    }.get(rational_len.denominator(), -1)

    # Duration of the form 1/2^n or 3/2^n can be converted to a simple lilypond duration
    dots = {
        1: 0,
        3: 1,
        7: 2,
        15: 3,
        31: 4,
        63: 5,
        127: 6
    }.get(rational_len.numerator(), -1)
    if (d_log >= dots >= 0):
        # account for the dots!
        d.duration_log = d_log - dots
        d.dots = dots
    elif (d_log >= 0):
        d.duration_log = d_log
        d.factor = Rational(rational_len.numerator())
    else:
        ly.warning(
            _("Encountered rational duration with denominator %s, "
              "unable to convert to lilypond duration") %
            rational_len.denominator())
        # TODO: Test the above error message
        return None

    return d
예제 #8
0
    def write_ly(self):
        base = self.basename()
        path = os.path.join(self.global_options.lily_output_dir, base)
        directory = os.path.split(path)[0]
        os.makedirs(directory, exist_ok=True)
        filename = path + '.ly'
        if os.path.exists(filename):
            existing = open(filename, 'r', encoding='utf-8').read()

            if self.relevant_contents(existing) != self.relevant_contents(self.full_ly()):
                ly.warning("%s: duplicate filename but different contents of original file,\n\
printing diff against existing file." % filename)
                encoded = self.full_ly().encode('utf-8')
                cmd = 'diff -u %s -' % filename
                sys.stderr.write(self.filter_pipe(
                    encoded, cmd).decode('utf-8'))
        else:
            out = open(filename, 'w', encoding='utf-8')
            out.write(self.full_ly())
예제 #9
0
def main():
    files = do_options()

    # should parse files[] to read \version?
    if global_options.show_rules:
        show_rules(sys.stdout, global_options.from_version, global_options.to_version)
        sys.exit(0)

    identify()

    errors = 0
    for f in files:
        f = f.decode(sys.stdin.encoding or "utf-8")
        if f == "-":
            f = ""
        elif not os.path.isfile(f):
            ly.error(_(u"%s: Unable to open file") % f)
            errors += 1
            continue
        try:
            errors += do_one_file(f)
        except UnknownVersion:
            ly.error(_(u"%s: Unable to determine version.  Skipping") % f)
            errors += 1
        except InvalidVersion:
            # Compat code for 2.x and 3.0 syntax ("except .. as v" doesn't
            # work in python 2.4!):
            t, v, b = sys.exc_info()
            ly.error(
                _(
                    u"%s: Invalid version string `%s' \n"
                    "Valid version strings consist of three numbers, "
                    "separated by dots, e.g. `2.8.12'"
                )
                % (f, v.version)
            )
            errors += 1

    if errors:
        ly.warning(ly.ungettext("There was %d error.", "There were %d errors.", errors) % errors)
        sys.exit(1)
예제 #10
0
def main():
    files = do_options()

    # should parse files[] to read \version?
    if global_options.show_rules:
        show_rules(sys.stdout, global_options.from_version,
                   global_options.to_version)
        sys.exit(0)

    identify()

    errors = 0
    for f in files:
        f = f.decode(sys.stdin.encoding or "utf-8")
        if f == '-':
            f = ''
        elif not os.path.isfile(f):
            ly.error(_(u"%s: Unable to open file") % f)
            errors += 1
            continue
        try:
            errors += do_one_file(f)
        except UnknownVersion:
            ly.error(_(u"%s: Unable to determine version.  Skipping") % f)
            errors += 1
        except InvalidVersion:
            # Compat code for 2.x and 3.0 syntax ("except .. as v" doesn't
            # work in python 2.4!):
            t, v, b = sys.exc_info()
            ly.error(
                _(u"%s: Invalid version string `%s' \n"
                  "Valid version strings consist of three numbers, "
                  "separated by dots, e.g. `2.8.12'") % (f, v.version))
            errors += 1

    if errors:
        ly.warning(
            ly.ungettext("There was %d error.", "There were %d errors.",
                         errors) % errors)
        sys.exit(1)
예제 #11
0
    def write_ly(self):
        base = self.basename()
        path = os.path.join(self.global_options.lily_output_dir, base)
        directory = os.path.split(path)[0]
        os.makedirs(directory, exist_ok=True)

        # First write the XML to a file (so we can link it!)
        if self.compressed:
            xmlfilename = path + '.mxl'
        else:
            xmlfilename = path + '.xml'
        if os.path.exists(xmlfilename):
            diff_against_existing = self.filter_pipe(
                self.get_contents(), 'diff -u %s - ' % xmlfilename)
            if diff_against_existing:
                ly.warning(_("%s: duplicate filename but different contents of original file,\n\
printing diff against existing file.") % xmlfilename)
                sys.stderr.write(diff_against_existing.decode('utf-8'))
        else:
            out = open(xmlfilename, 'wb')
            out.write(self.get_contents())
            out.close()

        # also write the converted lilypond
        filename = path + '.ly'
        if os.path.exists(filename):
            encoded = self.full_ly().encode('utf-8')
            cmd = 'diff -u %s -' % filename
            diff_against_existing = self.filter_pipe(
                encoded, cmd).decode('utf-8')
            if diff_against_existing:
                ly.warning(_("%s: duplicate filename but different contents of converted lilypond file,\n\
printing diff against existing file.") % filename)
                sys.stderr.write(diff_against_existing.decode('utf-8'))
        else:
            out = open(filename, 'w', encoding='utf-8')
            out.write(self.full_ly())
            out.close()
예제 #12
0
    def get_time_signature(self):
        "Return time sig as a (beat, beat-type) tuple. For compound signatures,"
        "return either (beat, beat,..., beat-type) or ((beat,..., type), "
        "(beat,..., type), ...)."
        if self._time_signature_cache:
            return self._time_signature_cache

        try:
            mxl = self.get_named_attribute('time')
            if not mxl:
                return None

            if mxl.get_maybe_exist_named_child('senza-misura'):
                # TODO: Handle pieces without a time signature!
                ly.warning(
                    _("Senza-misura time signatures are not yet supported!"))
                return (4, 4)
            else:
                signature = []
                current_sig = []
                for i in mxl.get_all_children():
                    if isinstance(i, Beats):
                        beats = string.split(i.get_text().strip(), "+")
                        current_sig = [int(j) for j in beats]
                    elif isinstance(i, BeatType):
                        current_sig.append(int(i.get_text()))
                        signature.append(current_sig)
                        current_sig = []
                if isinstance(signature[0], list) and len(signature) == 1:
                    signature = signature[0]
                self._time_signature_cache = signature
                return signature
        except (KeyError, ValueError):
            self.message(
                _("Unable to interpret time signature! Falling back to 4/4."))
            return (4, 4)
예제 #13
0
    def parse_snippet_options(self, option_string, type):
        self.snippet_option_dict = {}

        # Split option string and create raw option_dict from it
        options = self.split_options(option_string)

        for option in options:
            (key, value) = (option, None)
            if '=' in option:
                (key, value) = re.split(r'\s*=\s*', option)
            else:
                # a no... option removes a previous option if present!
                if key in no_options:
                    if no_options[key] in self.option_dict:
                        del self.snippet_option_dict[no_options[key]]
                        key = None
            # Check for deprecated options, replace them by new ones
            (c_key, c_value) = classic_lilypond_book_compatibility(key, value)
            if c_key:
                if c_value:
                    ly.warning(
                        _("deprecated ly-option used: %s=%s") % (key, value))
                    ly.warning(
                        _("compatibility mode translation: %s=%s") % (c_key, c_value))
                else:
                    ly.warning(
                        _("deprecated ly-option used: %s") % key)
                    ly.warning(
                        _("compatibility mode translation: %s") % c_key)
                (key, value) = (c_key, c_value)
            # Finally, insert the option:
            if key:
                self.snippet_option_dict[key] = value

        # If LINE_WIDTH is used without parameter, set it to default.
        has_line_width = LINE_WIDTH in self.snippet_option_dict
        if has_line_width and self.snippet_option_dict[LINE_WIDTH] is None:
            del self.snippet_option_dict[LINE_WIDTH]

        # RELATIVE does not work without FRAGMENT, so imply that
        if RELATIVE in self.snippet_option_dict:
            self.snippet_option_dict[FRAGMENT] = None

        # Now get the default options from the formatter object (HTML, latex,
        # texinfo, etc.) and insert the explicit snippet options to get the
        # list of all options for this snippet
        # first, make sure we have an INDENT value as a fallback
        self.option_dict = {INDENT: '0\\mm'}
        self.option_dict.update(self.formatter.default_snippet_options)
        self.option_dict.update(self.snippet_option_dict)

        # also construct a list of all options (as strings) that influence the
        # visual appearance of the snippet
        lst = [x_y for x_y in iter(self.option_dict.items())
                     if x_y[0] not in PROCESSING_INDEPENDENT_OPTIONS]
        option_list = []
        for (key, value) in lst:
            if value is None:
                option_list.append(key)
            else:
                option_list.append(key + "=" + value)
        option_list.sort()
        self.outputrelevant_option_list = option_list
예제 #14
0
def get_latex_textwidth(source, global_options):
    # default value
    textwidth = 550.0

    m = re.search(r'''(?P<preamble>\\begin\s*{document})''', source)
    if m is None:
        ly.warning(_("cannot find \\begin{document} in LaTeX document"))
        return textwidth

    preamble = source[:m.start(0)]
    latex_document = LATEX_INSPECTION_DOCUMENT % {'preamble': preamble}

    (handle, tmpfile) = tempfile.mkstemp('.tex')
    tmpfileroot = os.path.splitext(tmpfile)[0]
    tmpfileroot = os.path.split(tmpfileroot)[1]
    auxfile = tmpfileroot + '.aux'
    logfile = tmpfileroot + '.log'

    tmp_handle = os.fdopen(handle, 'w')
    tmp_handle.write(latex_document)
    tmp_handle.close()

    ly.progress(
        _("Running `%s' on file `%s' to detect default page settings.\n") %
        (global_options.latex_program, tmpfile))
    cmd = '%s %s' % (global_options.latex_program, tmpfile)
    ly.debug_output("Executing: %s\n" % cmd)
    run_env = os.environ.copy()
    run_env['LC_ALL'] = 'C'
    run_env['TEXINPUTS'] = os.path.pathsep.join(
        (global_options.input_dir, run_env.get('TEXINPUTS', '')))

    # unknown why this is necessary
    universal_newlines = True
    if sys.platform == 'mingw32':
        universal_newlines = False
        # use os.system to avoid weird sleep() problems on
        # GUB's python 2.4.2 on mingw
        # make file to write to
        output_dir = tempfile.mkdtemp()
        output_filename = os.path.join(output_dir, 'output.txt')
        # call command
        cmd += " > %s" % output_filename
        oldtexinputs = os.environ.get('TEXINPUTS')
        os.environ['TEXINPUTS'] = run_env['TEXINPUTS']
        returncode = os.system(cmd)
        if oldtexinputs:
            os.environ['TEXINPUTS'] = oldtexinputs
        else:
            del os.environ['TEXINPUTS']
        parameter_string = open(output_filename, encoding="utf8").read()
        if returncode != 0:
            ly.warning(_("Unable to auto-detect default settings:\n"))
        # clean up
        os.remove(output_filename)
        os.rmdir(output_dir)
    else:
        proc = subprocess.Popen(cmd,
                                env=run_env,
                                universal_newlines=universal_newlines,
                                shell=True,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
        (parameter_string, error_string) = proc.communicate()
        if proc.returncode != 0:
            ly.warning(
                _("Unable to auto-detect default settings:\n%s") %
                error_string)
    os.unlink(tmpfile)
    if os.path.exists(auxfile):
        os.unlink(auxfile)
    if os.path.exists(logfile):
        parameter_string = open(logfile, encoding="utf8").read()
        os.unlink(logfile)

    columns = 0
    m = re.search('columns=([0-9.]+)', parameter_string)
    if m:
        columns = int(m.group(1))

    columnsep = 0
    m = re.search('columnsep=([0-9.]+)pt', parameter_string)
    if m:
        columnsep = float(m.group(1))

    m = re.search('textwidth=([0-9.]+)pt', parameter_string)
    if m:
        textwidth = float(m.group(1))
    else:
        ly.warning(_("cannot detect textwidth from LaTeX"))
        return textwidth

    ly.debug_output('Detected values:')
    ly.debug_output('  columns = %s' % columns)
    ly.debug_output('  columnsep = %s' % columnsep)
    ly.debug_output('  textwidth = %s' % textwidth)

    if m and columns:
        textwidth = (textwidth - columnsep) / columns
        ly.debug_output('Adjusted value:')
        ly.debug_output('  textwidth = %s' % textwidth)

    return textwidth
예제 #15
0
def dump_track(track, n):
    s = '\n'
    track_name = get_track_name(n)

    average_pitch = track_average_pitch(track)
    voices = len([x for x in average_pitch[1:] if x])
    clef = get_best_clef(average_pitch[0])

    c = 0
    vv = 0
    for channel in track:
        v = 0
        channel_name = get_channel_name(c)
        c += 1
        for voice in channel:
            voice_name = get_voice_name(v)
            voice_id = track_name + channel_name + voice_name
            item = voice_first_item(voice)

            if item and item.__class__ == Note:
                skip = 'r'
                if global_options.skip:
                    skip = 's'
                s += '%(voice_id)s = ' % locals()
                if not global_options.absolute_pitches:
                    s += '\\relative c '
            elif item and item.__class__ == Text:
                skip = '" "'
                s += '%(voice_id)s = \\lyricmode ' % locals()
            else:
                skip = '\\skip '
                s += '%(voice_id)s = ' % locals()
            s += '{\n'
            if not n and not vv and global_options.key:
                s += global_options.key.dump()
            if average_pitch[vv+1] and voices > 1:
                vl = get_voice_layout(average_pitch[1:])[vv]
                if vl:
                    s += '  \\voice' + vl + '\n'
                else:
                    if not global_options.quiet:
                        ly.warning(
                            _('found more than 5 voices on a staff, expect bad output'))
            s += '  ' + dump_voice(voice, skip)
            s += '}\n\n'
            v += 1
            vv += 1

    s += '%(track_name)s = <<\n' % locals()

    if clef.type != 2:
        s += clef.dump() + '\n'

    c = 0
    vv = 0
    for channel in track:
        v = 0
        channel_name = get_channel_name(c)
        c += 1
        for voice in channel:
            voice_context_name = get_voice_name(vv, zero_too_p=True)
            voice_name = get_voice_name(v)
            v += 1
            vv += 1
            voice_id = track_name + channel_name + voice_name
            item = voice_first_item(voice)
            context = 'Voice'
            if item and item.__class__ == Text:
                context = 'Lyrics'
            s += '  \\context %(context)s = %(voice_context_name)s \\%(voice_id)s\n' % locals()
    s += '>>\n\n'
    return s
예제 #16
0
    def compose_ly(self, code):

        # Defaults.
        relative = 1
        override = {}
        # The original concept of the `exampleindent' option is broken.
        # It is not possible to get a sane value for @exampleindent at all
        # without processing the document itself.  Saying
        #
        #   @exampleindent 0
        #   @example
        #   ...
        #   @end example
        #   @exampleindent 5
        #
        # causes ugly results with the TeX backend of texinfo since the
        # default value for @exampleindent isn't 5em but 0.4in (or a smaller
        # value).  Executing the above code changes the environment
        # indentation to an unknown value because we don't know the amount
        # of 1em in advance since it is font-dependent.  Modifying
        # @exampleindent in the middle of a document is simply not
        # supported within texinfo.
        #
        # As a consequence, the only function of @exampleindent is now to
        # specify the amount of indentation for the `quote' option.
        #
        # To set @exampleindent locally to zero, we use the @format
        # environment for non-quoted snippets.
        #
        # Update: since July 2011 we are running texinfo on a test file
        #         to detect the default exampleindent, so we might reintroduce
        #         further usage of exampleindent again.
        #
        # First, make sure we have some falback default value, auto-detected
        # values and explicitly specified values will always override them:
        override[EXAMPLEINDENT] = r'0.4\in'
        override[LINE_WIDTH] = '5\\in'
        override.update(self.formatter.default_snippet_options)
        override['padding_mm'] = self.global_options.padding_mm

        option_string = ','.join(self.get_outputrelevant_option_strings())
        compose_dict = {}
        compose_types = [NOTES, PREAMBLE, LAYOUT, PAPER]
        for a in compose_types:
            compose_dict[a] = []

        option_names = sorted(self.option_dict.keys())
        for key in option_names:
            value = self.option_dict[key]

            if value:
                override[key] = value
            else:
                if key not in override:
                    override[key] = None

            found = 0
            for typ in compose_types:
                if key in snippet_options[typ]:
                    compose_dict[typ].append(snippet_options[typ][key])
                    found = 1
                    break

            if not found and key not in simple_options and key not in self.snippet_options():
                ly.warning(_("ignoring unknown ly option: %s") % key)

        # URGS
        if RELATIVE in override and override[RELATIVE]:
            relative = int(override[RELATIVE])

        relative_quotes = ''

        # 1 = central C
        if relative < 0:
            relative_quotes += ',' * (- relative)
        elif relative > 0:
            relative_quotes += "'" * relative

        if INLINE in override:
            # For inline images, try to make left and right padding equal,
            # ignoring the `--left-padding` value.
            #
            # URGH Value 0 makes LilyPond apply no left padding at all, but
            #      still having some right padding.  This is a bug (#6116).
            override['padding_mm'] = 0.0001

        # put paper-size first, if it exists
        for i, elem in enumerate(compose_dict[PAPER]):
            if elem.startswith("#(set-paper-size"):
                compose_dict[PAPER].insert(0, compose_dict[PAPER].pop(i))
                break

        paper_string = '\n  '.join(compose_dict[PAPER]) % override
        layout_string = '\n  '.join(compose_dict[LAYOUT]) % override
        notes_string = '\n  '.join(compose_dict[NOTES]) % vars()
        preamble_string = '\n  '.join(compose_dict[PREAMBLE]) % override

        padding_mm = override['padding_mm']
        if padding_mm != 0:
            padding_mm_string = \
                "#(ly:set-option 'eps-box-padding %f)" % padding_mm
        else:
            padding_mm_string = ""

        if self.global_options.safe_mode:
            safe_mode_string = "#(ly:set-option 'safe #t)"
        else:
            safe_mode_string = ""

        d = globals().copy()
        d.update(locals())
        d.update(self.global_options.information)
        if FRAGMENT in self.option_dict:
            body = FRAGMENT_LY
        else:
            body = FULL_LY
        return (PREAMBLE_LY + body) % d
예제 #17
0
 def print_ly(self, printer):
     ly.warning(_("Encountered unprocessed marker %s\n") % self)
     pass
예제 #18
0
def get_texinfo_width_indent(source, global_options):
    #TODO: Check for end of header command "@c %**end of header"
    #      only use material before that comment ?

    # extract all relevant papter settings from the input:
    pagesize = None
    texinfo_paper_size_regexp = r'''(@(?:afourpaper|afourwide|afourlatex|afivepaper|smallbook|letterpaper))'''
    m = re.search(texinfo_paper_size_regexp, source)
    if m:
        pagesize = m.group(1)

    relevant_settings_regexp = r'''(@(?:fonttextsize|pagesizes|cropmarks|exampleindent).*)\n'''
    m = re.findall(relevant_settings_regexp, source)
    if pagesize:
        m.insert(0, pagesize)
    # all relevant options to insert into the test document:
    preamble = "\n".join(m)

    texinfo_document = TEXINFO_INSPECTION_DOCUMENT % {'preamble': preamble}

    (handle, tmpfile) = tempfile.mkstemp('.texi')
    outfile = os.path.splitext(tmpfile)[0] + '.pdf'

    tmp_handle = os.fdopen(handle, 'w')
    tmp_handle.write(texinfo_document)
    tmp_handle.close()

    # Work around a texi2pdf bug: if LANG=C is not given, a broken regexp is
    # used to detect relative/absolute paths, so the absolute path is not
    # detected as such and this command fails:
    ly.progress(
        _("Running texi2pdf on file %s to detect default page settings.\n") %
        tmpfile)

    # execute the command and pipe stdout to the parameter_string:
    cmd = '%s --batch -c -o %s %s' % (global_options.texinfo_program, outfile,
                                      tmpfile)
    ly.debug_output("Executing: %s\n" % cmd)
    run_env = os.environ.copy()
    run_env['LC_ALL'] = 'C'

    ### unknown why this is necessary
    universal_newlines = True
    if sys.platform == 'mingw32':
        universal_newlines = False
        ### use os.system to avoid weird sleep() problems on
        ### GUB's python 2.4.2 on mingw
        # make file to write to
        output_dir = tempfile.mkdtemp()
        output_filename = os.path.join(output_dir, 'output.txt')
        # call command
        cmd += " > %s" % output_filename
        returncode = os.system(cmd)
        parameter_string = open(output_filename).read()
        if returncode != 0:
            ly.warning(_("Unable to auto-detect default settings:\n"))
        # clean up
        os.remove(output_filename)
        os.rmdir(output_dir)
    else:
        proc = subprocess.Popen(cmd,
                                env=run_env,
                                universal_newlines=universal_newlines,
                                shell=True,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
        (parameter_string, error_string) = proc.communicate()
        if proc.returncode != 0:
            ly.warning(
                _("Unable to auto-detect default settings:\n%s") %
                error_string)
    os.unlink(tmpfile)
    if os.path.exists(outfile):
        os.unlink(outfile)

    # Find textwidth and exampleindent and format it as \\mm or \\in
    # Use defaults if they cannot be extracted
    textwidth = 0
    m = re.search('textwidth=([0-9.]+)pt', parameter_string)
    if m:
        val = float(m.group(1)) / 72.27
        if pagesize and pagesize.startswith("@afour"):
            textwidth = "%g\\mm" % round(val * 25.4, 3)
        else:
            textwidth = "%g\\in" % round(val, 3)
    else:
        textwidth = texinfo_line_widths.get(pagesize, "6\\in")

    exampleindent = 0
    m = re.search('exampleindent=([0-9.]+)pt', parameter_string)
    if m:
        val = float(m.group(1)) / 72.27
        if pagesize and pagesize.startswith("@afour"):
            exampleindent = "%g\\mm" % round(val * 25.4, 3)
        else:
            exampleindent = "%g\\in" % round(val, 3)
    else:
        exampleindent = "0.4\\in"

    retval = {
        book_snippets.LINE_WIDTH: textwidth,
        book_snippets.EXAMPLEINDENT: exampleindent
    }
    ly.debug_output("Auto-detected values are: %s\n" % retval)
    return retval