Exemple #1
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--names",
                        help="print family names",
                        action="store_true")
    parser.add_argument(
        "--each",
        help="for each code point, show supporting families",
        metavar="cp",
        nargs="+",
    )
    parser.add_argument(
        "--any",
        help="show families that support any of the codepoints",
        metavar="cp",
        nargs="+",
    )
    parser.add_argument(
        "--all",
        help="show families that support all of the codepoints",
        metavar="cp",
        nargs="+",
    )
    args = parser.parse_args()

    fonts = noto_fonts.get_noto_fonts()
    families = noto_fonts.get_families(fonts)
    run(args, families)
Exemple #2
0
def font_cmap_data(paths):
    """Return CmapData for (almost) all the noto font families."""
    args = [("paths", paths)] if paths else None
    metadata = cmap_data.create_metadata("noto_font_cmaps", args)

    def use_in_web(font):
        return (
            not font.subset
            and not font.fmt == "ttc"
            and not font.script in {"CJK", "HST"}
            and not font.family in {"Arimo", "Cousine", "Tinos"}
        )

    if not paths:
        paths = noto_fonts.NOTO_FONT_PATHS
    fonts = filter(use_in_web, noto_fonts.get_noto_fonts(paths=paths))
    families = noto_fonts.get_families(fonts)

    ScriptData = collections.namedtuple("ScriptData", "family_name,script,cpset")
    script_to_data = collections.defaultdict(list)
    for family in families.values():
        script = family.rep_member.script
        family_name = family.name
        cpset = family.charset
        script_to_data[script].append(ScriptData(family_name, script, cpset))

    def report_data_error(index, script_data):
        sys.stderr.write(
            "  %d: %s, %d, %s\n"
            % (
                index,
                script_data.family_name,
                script_data.script,
                len(script_data.cpset),
                lint_config.write_int_ranges(script_data.cpset),
            )
        )

    script_to_cmap = {}
    for script in sorted(script_to_data):
        data = script_to_data[script]
        selected_cpset = data[0].cpset
        if len(data) > 1:
            differ = False
            for i in range(1, len(data)):
                test_data = data[i]
                for j in range(i):
                    if data[j].cpset != test_data.cpset:
                        differ = True
                if len(test_data.cpset) > len(selected_cpset):
                    selected_cpset = test_data.cpset
            if differ:
                sys.stderr.write("\nscript %s cmaps differ\n" % script)
                differences = {i.family_name: i.cpset for i in data}
                report_set_differences(differences)
        script_to_cmap[script] = selected_cpset

    tabledata = cmap_data.create_table_from_map(script_to_cmap)
    return cmap_data.CmapData(metadata, tabledata)
def font_cmap_data(paths):
  """Return CmapData for (almost) all the noto font families."""
  args = [('paths', paths)] if paths else None
  metadata = cmap_data.create_metadata('noto_font_cmaps', args)

  def use_in_web(font):
    return (not font.subset and
            not font.fmt == 'ttc' and
            not font.script in {'CJK', 'HST'} and
            not font.family in {'Arimo', 'Cousine', 'Tinos'})

  if not paths:
    paths = noto_fonts.NOTO_FONT_PATHS
  fonts = filter(use_in_web, noto_fonts.get_noto_fonts(paths=paths))
  families = noto_fonts.get_families(fonts)

  ScriptData = collections.namedtuple('ScriptData', 'family_name,script,cpset')
  script_to_data = collections.defaultdict(list)
  for family in families.values():
    script = family.rep_member.script
    family_name = family.name
    cpset = family.charset
    script_to_data[script].append(ScriptData(family_name, script, cpset))

  def report_data_error(index, script_data):
    print >> sys.stderr, '  %d: %s, %d, %s' % (
        index, script_data.family_name, script_data.script,
        len(script_data.cpset),
        lint_config.write_int_ranges(script_data.cpset))

  script_to_cmap = {}
  for script in sorted(script_to_data):
    data = script_to_data[script]
    selected_cpset = data[0].cpset
    if len(data) > 1:
      differ = False
      for i in range(1, len(data)):
        test_data = data[i]
        for j in range(i):
          if data[j].cpset != test_data.cpset:
            differ = True
        if len(test_data.cpset) > len(selected_cpset):
          selected_cpset = test_data.cpset
      if differ:
        print >> sys.stderr, '\nscript %s cmaps differ' % script
        differences = {i.family_name: i.cpset for i in data}
        report_set_differences(differences)
    script_to_cmap[script] = selected_cpset

  tabledata = cmap_data.create_table_from_map(script_to_cmap)
  return cmap_data.CmapData(metadata, tabledata)
def main():
  parser = argparse.ArgumentParser()
  parser.add_argument('--names', help='print family names', action='store_true')
  parser.add_argument('--each', help='for each code point, show supporting families',
                      metavar='cp', nargs='+')
  parser.add_argument('--any', help='show families that support any of the codepoints',
                      metavar='cp', nargs='+')
  parser.add_argument('--all', help='show families that support all of the codepoints',
                      metavar='cp', nargs='+')
  args = parser.parse_args()

  fonts = noto_fonts.get_noto_fonts()
  families = noto_fonts.get_families(fonts)
  run(args, families)
def main():
  parser = argparse.ArgumentParser()
  parser.add_argument('--names', help='print family names', action='store_true')
  parser.add_argument('--each', help='for each code point, show supporting families',
                      metavar='cp', nargs='+')
  parser.add_argument('--any', help='show families that support any of the codepoints',
                      metavar='cp', nargs='+')
  parser.add_argument('--all', help='show families that support all of the codepoints',
                      metavar='cp', nargs='+')
  args = parser.parse_args()

  fonts = noto_fonts.get_noto_fonts()
  families = noto_fonts.get_families(fonts)
  run(args, families)
Exemple #6
0
def font_cmap_data():
    """Return CmapData for (almost) all the noto font families."""
    metadata = cmap_data.create_metadata('noto_font_cmaps')

    def use_in_web(font):
        return (not font.subset and not font.is_UI and not font.fmt == 'ttc'
                and not font.script in {'CJK', 'HST'}
                and not font.family in {'Arimo', 'Cousine', 'Tinos'})

    fonts = filter(use_in_web, noto_fonts.get_noto_fonts())
    families = noto_fonts.get_families(fonts)

    ScriptData = collections.namedtuple('ScriptData',
                                        'family_name,script,cpset')
    script_to_data = collections.defaultdict(list)
    for family in families.values():
        script = family.rep_member.script
        family_name = family.name
        cpset = family.charset
        script_to_data[script].append(ScriptData(family_name, script, cpset))

    def report_data_error(index, script_data):
        print >> sys.stderr, '  %d: %s, %d, %s' % (
            index, script_data.family_name, script_data.script,
            len(script_data.cpset),
            lint_config.write_int_ranges(script_data.cpset))

    script_to_cmap = {}
    for script in sorted(script_to_data):
        data = script_to_data[script]
        selected_cpset = data[0].cpset
        if len(data) > 1:
            differ = False
            for i in range(1, len(data)):
                test_data = data[i]
                for j in range(i):
                    if data[j].cpset != test_data.cpset:
                        differ = True
                if len(test_data.cpset) > len(selected_cpset):
                    selected_cpset = test_data.cpset
            if differ:
                print >> sys.stderr, '\nscript %s cmaps differ' % script
                differences = {i.family_name: i.cpset for i in data}
                report_set_differences(differences)
        script_to_cmap[script] = selected_cpset

    tabledata = cmap_data.create_table_from_map(script_to_cmap)
    return cmap_data.CmapData(metadata, tabledata)
  def generate(self):
    if self.clean:
      self.clean_target_dir()

    if not self.no_build:
      self.ensure_target_dirs_exist()

    # debug/print
    # ['families', 'script_to_family_ids', 'used_lang_data',
    #  'family_id_to_lang_scrs', 'family_id_to_default_lang_scr']
    debug = frozenset([])

    def use_in_web(font):
      return (not font.subset and
              not font.is_UI and
              not font.fmt == 'ttc' and
              not font.script in {'CJK', 'HST'} and
              not font.family in {'Arimo', 'Cousine', 'Tinos'})
    fonts = filter(use_in_web, noto_fonts.get_noto_fonts())
    families = noto_fonts.get_families(fonts)

    if 'families' in debug:
      print '\nfamilies'
      for family_id, family in sorted(families.iteritems()):
        print family_id, family.rep_member.script

    script_to_family_ids = get_script_to_family_ids(families)
    if 'script_to_family_ids' in debug:
      print '\nscript to family ids'
      for script, family_ids in sorted(script_to_family_ids.iteritems()):
        print script, family_ids

    all_lang_scrs = set(['und-' + script for script in script_to_family_ids])
    all_lang_scrs.update(lang_data.lang_scripts())

    lang_scr_to_sample_infos = {}
    for lang_scr in all_lang_scrs:
      lang, script = lang_scr.split('-')
      if not script in script_to_family_ids:
        print 'no family supports script in %s' % lang_scr
        continue

      sample_infos = get_sample_infos(lang_scr)
      if not sample_infos:
        continue

      lang_scr_to_sample_infos[lang_scr] = sample_infos

    if 'lang_scr_to_sample_infos' in debug:
      print '\nlang+script to sample infos'
      for lang_scr, info_list in sorted(lang_scr_to_sample_infos.iteritems()):
        for info in info_list:
          print '%s key: %s rtl: %s attrib: %s len: %d' % (
              lang_scr, info[3], info[0], info[2], len(info[1]))

    family_id_to_lang_scrs = get_family_id_to_lang_scrs(
        lang_scr_to_sample_infos.keys(), script_to_family_ids)

    family_id_to_lang_scr_to_sample_key, sample_key_to_info = get_family_id_to_lang_scr_to_sample_key(
        family_id_to_lang_scrs, families, lang_scr_to_sample_infos)

    family_id_to_regions = get_family_id_to_regions(family_id_to_lang_scr_to_sample_key)
    region_to_family_ids = get_region_to_family_ids(family_id_to_regions)

    family_id_to_default_lang_scr = get_family_id_to_default_lang_scr(
        family_id_to_lang_scrs, families)
    if 'family_id_to_default_lang_scr' in debug:
      print '\nfamily id to default lang scr'
      for family_id, lang_scr in family_id_to_default_lang_scr.iteritems():
        print family_id, lang_scr

    region_data = get_region_lat_lng_data(region_to_family_ids.keys())

    lang_scrs = get_named_lang_scrs(family_id_to_lang_scr_to_sample_key)
    lang_scr_sort_order = get_lang_scr_sort_order(lang_scrs)

    # sanity checks
    # all families have languages, and all those have samples.
    # all families have a default language, and that is in the sample list
    error_list = []
    for family in families.values():
      family_id = family.family_id
      if not family_id in family_id_to_lang_scr_to_sample_key:
        error_list.append('no entry for family %s' % family_id)
        continue

      lang_scr_to_sample_key = family_id_to_lang_scr_to_sample_key[family_id]
      if not lang_scr_to_sample_key:
        error_list.append('no langs for family %s' % family_id)
        continue

      for lang_scr in lang_scr_to_sample_key:
        sample_key = lang_scr_to_sample_key[lang_scr]
        if not sample_key:
          error_list.append('no sample key for lang %s in family %s' % (lang_scr, sample_key))
          continue
        if not sample_key in sample_key_to_info:
          error_list.append('no sample for sample key: %s' % sample_key)

      if not family_id in family_id_to_default_lang_scr:
        error_list.append('no default lang for family %s' % family_id)
        continue
      default_lang_scr = family_id_to_default_lang_scr[family_id]
      if not default_lang_scr in lang_scr_to_sample_key:
        error_list.append('default lang %s not in samples for family %s' %
                          (default_lang_scr, family_id))

    if error_list:
      print 'Errors:\n' + '\n  '.join(error_list)

    if error_list or self.no_build:
      print 'skipping build output'
      return

    # build outputs
    if self.no_zips:
      print 'skipping zip output'
    else:
      family_zip_info = self.build_zips(families)
      universal_zip_info = self.build_universal_zips(families)

      # build outputs not used by the json but linked to from the web page
      self.build_ttc_zips()

    if self.no_css:
      print 'skipping css output'
    else:
      family_css_info = self.build_css(families)

    if self.no_data:
      print 'skipping data output%s' % reason
    else:
      self.build_data_json(family_id_to_lang_scr_to_sample_key,
                           families, family_zip_info, universal_zip_info,
                           family_id_to_regions, region_to_family_ids)

      self.build_families_json(family_id_to_lang_scr_to_sample_key,
                               families, family_id_to_default_lang_scr,
                               family_id_to_regions, family_css_info,
                               lang_scr_sort_order)

      self.build_misc_json(sample_key_to_info, region_data)

    if self.no_images:
      print 'skipping image output'
    else:
      self.build_images(family_id_to_lang_scr_to_sample_key,
                        families,  family_id_to_default_lang_scr,
                        sample_key_to_info)
    'mk,ml,mn,mr,ms,my,ne,nl,no,pa,pl,pt-BR,pt-PT,ro,ru,si,sk,sl,sq,sr,'
    'sv,sw,ta,te,th,tl,tr,uk,ur,uz,vi,zh-CN,zh-TW,zu').split(',')

def accept_font(f):
  return (
      f.family == 'Noto' and  # exclude Arimo, Tinos, Cousine
      f.style != 'Nastaliq' and  # exclude Nastaliq, not suitable for maps
      f.script != 'HST' and  # exclude Historic, tool limitation
      f.weight == 'Regular' and  # to limit members of fonts
      f.width == 'Regular' and  # to limit members of fonts, we don't
      not f.slope and            #   care about weights
      f.fmt in ['ttf', 'otf'] and  # only support these formats
      (not f.is_cjk or f.subset))  # 'small' language-specific CJK subsets

fonts = filter(accept_font, noto_fonts.get_noto_fonts())
families = noto_fonts.get_families(fonts).values()

def write_csv_header(outfile):
  print >> outfile, 'Code,Script,Style,UI,Font Name'


def write_csv(outfile, lang, script, style, ui, members):
  if members:
    print >> outfile, ','.join(
        [lang, script, style, ui,
         noto_fonts.get_font_family_name(members[0].filepath)])


with open('lang_to_font_table.csv', 'w') as outfile:
  write_csv_header(outfile)
  for lang in LANGS:
Exemple #9
0
  def generate(self):
    if self.clean:
      self.clean_target_dir()

    if not self.no_build:
      self.ensure_target_dirs_exist()

    def use_in_web(font):
      return (not font.subset and
              not font.fmt == 'ttc' and
              not font.script in {'CJK', 'HST'} and
              not font.family in {'Arimo', 'Cousine', 'Tinos'})
    fonts = filter(use_in_web, noto_fonts.get_noto_fonts())
    families = noto_fonts.get_families(fonts)

    check_families(families)

    if 'families' in self.debug:
      print '\n#debug families'
      for family_id, family in sorted(families.iteritems()):
        print '%s (%s, %s)' % (
            family_id, family.name, noto_fonts.get_family_filename(family))
        if family.hinted_members:
          print '  hinted: %s' % ', '.join(sorted(
              [path.basename(m.filepath) for m in family.hinted_members]))
        if family.unhinted_members:
          print '  unhinted: %s' % ', '.join(sorted(
              [path.basename(m.filepath) for m in family.unhinted_members]))

    script_to_family_ids = get_script_to_family_ids(families)
    if 'script_to_family_ids' in self.debug:
      print '\n#debug script to family ids'
      for script, family_ids in sorted(script_to_family_ids.iteritems()):
        print '%s: %s' % (script, ', '.join(sorted(family_ids)))

    all_lang_scrs = set(['und-' + script for script in script_to_family_ids])
    all_lang_scrs.update(lang_data.lang_scripts())

    lang_scr_to_sample_infos = {}
    for lang_scr in all_lang_scrs:
      lang, script = lang_scr.split('-')
      if not script in script_to_family_ids:
        print 'no family supports script in %s' % lang_scr
        continue

      sample_infos = get_sample_infos(lang_scr)
      if not sample_infos:
        continue

      lang_scr_to_sample_infos[lang_scr] = sample_infos

    if 'lang_scr_to_sample_infos' in self.debug:
      print '\n#debug lang+script to sample infos'
      for lang_scr, info_list in sorted(lang_scr_to_sample_infos.iteritems()):
        for info in info_list:
          print '%s: %s, %s, len %d' % (
              lang_scr, info[2], info[1], len(info[0]))

    family_id_to_lang_scrs = get_family_id_to_lang_scrs(
        lang_scr_to_sample_infos.keys(), script_to_family_ids)
    if 'family_id_to_lang_scrs' in self.debug:
      print '\n#debug family id to list of lang+script'
      for family_id, lang_scrs in sorted(family_id_to_lang_scrs.iteritems()):
        print '%s: (%d) %s' % (
            family_id, len(lang_scrs), ' '.join(sorted(lang_scrs)))

    family_id_to_lang_scr_to_sample_key, sample_key_to_info = (
        get_family_id_to_lang_scr_to_sample_key(
            family_id_to_lang_scrs, families, lang_scr_to_sample_infos))
    if 'family_id_to_lang_scr_to_sample_key' in self.debug:
      print '\n#debug family id to map from lang+script to sample key'
      for family_id, lang_scr_to_sample_key in sorted(
          family_id_to_lang_scr_to_sample_key.iteritems()):
        print '%s (%d):' % (family_id, len(lang_scr_to_sample_key))
        for lang_scr, sample_key in sorted(lang_scr_to_sample_key.iteritems()):
          print '  %s: %s' % (lang_scr, sample_key)
    if 'sample_key_to_info' in self.debug:
      print '\n#debug sample key to sample info'
      for sample_key, info in sorted(sample_key_to_info.iteritems()):
        print '%s: %s, len %d' % (
            sample_key, info[1], len(info[0]))

    family_id_to_regions = get_family_id_to_regions(
        family_id_to_lang_scr_to_sample_key)
    if 'family_id_to_regions' in self.debug:
      print '\n#debug family id to regions'
      for family_id, regions in sorted(family_id_to_regions.iteritems()):
        print '%s: (%d) %s' % (
            family_id, len(regions), ', '.join(sorted(regions)))

    region_to_family_ids = get_region_to_family_ids(family_id_to_regions)
    if 'region_to_family_ids' in self.debug:
      print '\n#debug region to family ids'
      for region, family_ids in sorted(region_to_family_ids.iteritems()):
        print '%s: (%d) %s' % (
            region, len(family_ids), ', '.join(sorted(family_ids)))

    family_id_to_default_lang_scr = get_family_id_to_default_lang_scr(
        family_id_to_lang_scrs, families)
    if 'family_id_to_default_lang_scr' in self.debug:
      print '\n#debug family id to default lang scr'
      for family_id, lang_scr in sorted(
          family_id_to_default_lang_scr.iteritems()):
        print '%s: %s' % (family_id, lang_scr)

    region_data = get_region_lat_lng_data(region_to_family_ids.keys())

    lang_scrs = get_named_lang_scrs(family_id_to_lang_scr_to_sample_key)
    lang_scr_sort_order = get_lang_scr_sort_order(lang_scrs)

    # sanity checks
    # all families have languages, and all those have samples.
    # all families have a default language, and that is in the sample list
    error_list = []
    for family in families.values():
      family_id = family.family_id
      if not family_id in family_id_to_lang_scr_to_sample_key:
        error_list.append('no entry for family %s' % family_id)
        continue

      lang_scr_to_sample_key = family_id_to_lang_scr_to_sample_key[family_id]
      if not lang_scr_to_sample_key:
        error_list.append('no langs for family %s' % family_id)
        continue

      for lang_scr in lang_scr_to_sample_key:
        sample_key = lang_scr_to_sample_key[lang_scr]
        if not sample_key:
          error_list.append(
              'no sample key for lang %s in family %s' % (lang_scr, sample_key))
          continue
        if not sample_key in sample_key_to_info:
          error_list.append('no sample for sample key: %s' % sample_key)

      if not family_id in family_id_to_default_lang_scr:
        error_list.append('no default lang for family %s' % family_id)
        continue
      default_lang_scr = family_id_to_default_lang_scr[family_id]
      if not default_lang_scr in lang_scr_to_sample_key:
        error_list.append('default lang %s not in samples for family %s' %
                          (default_lang_scr, family_id))

    if error_list:
      print 'Errors:\n' + '\n  '.join(error_list)

    if error_list or self.no_build:
      print 'skipping build output'
      return

    # build outputs
    # zips are required for data
    if self.no_zips and self.no_data:
      print 'skipping zip output'
    else:
      self.build_readmes()

      family_zip_info = self.build_zips(families)
      universal_zip_info = self.build_universal_zips(families)

      # build outputs not used by the json but linked to from the web page
      if not self.no_zips:
        self.build_ttc_zips()

    if self.no_css:
      print 'skipping css output'
    else:
      family_css_info = self.build_css(families)

    if self.no_data:
      print 'skipping data output'
    else:
      self.build_data_json(family_id_to_lang_scr_to_sample_key,
                           families, family_zip_info, universal_zip_info,
                           family_id_to_regions, region_to_family_ids)

      self.build_families_json(family_id_to_lang_scr_to_sample_key,
                               families, family_id_to_default_lang_scr,
                               family_id_to_regions, family_css_info,
                               lang_scr_sort_order)

      self.build_misc_json(sample_key_to_info, region_data)

    if self.no_images:
      print 'skipping image output'
    else:
      self.build_images(family_id_to_lang_scr_to_sample_key,
                        families,  family_id_to_default_lang_scr,
                        sample_key_to_info)
    def generate(self):
        if self.clean:
            self.clean_target_dir()

        if not self.no_build:
            self.ensure_target_dirs_exist()

        # debug/print
        # ['families', 'script_to_family_ids', 'used_lang_data',
        #  'family_id_to_lang_tags', 'family_id_to_default_lang_tag']
        debug = frozenset([])

        fonts = noto_fonts.get_noto_fonts()
        families = noto_fonts.get_families(fonts)

        if 'families' in debug:
            print '\nfamilies'
            for family_id, family in sorted(families.iteritems()):
                print family_id, family.rep_member.script

        script_to_family_ids = get_script_to_family_ids(families)
        if 'script_to_family_ids' in debug:
            print '\nscript to family ids'
            for script, family_ids in sorted(script_to_family_ids.iteritems()):
                print script, family_ids

        supported_scripts = set(script_to_family_ids.keys())
        used_lang_data = get_used_lang_data(supported_scripts)
        if 'used_lang_data' in debug:
            print '\nused lang data'
            for lang, data in sorted(used_lang_data.iteritems()):
                used = ', '.join(data[0])
                unused = ', '.join(data[1])
                if unused:
                    unused = '(' + unused + ')'
                    if used:
                        unused = ' ' + unused
                print '%s: %s%s' % (lang, used, unused)

        langs_to_delete = []
        for lang in used_lang_data.keys():
            if not cldr_data.get_english_language_name(lang):
                langs_to_delete.append(lang)
        if langs_to_delete:
            print 'deleting languages with no english name: %s' % langs_to_delete
            for lang in langs_to_delete:
                del used_lang_data[lang]

        lang_tag_to_family_ids = get_lang_tag_to_family_ids(
            used_lang_data, script_to_family_ids)

        region_to_family_ids = get_region_to_family_ids(script_to_family_ids)

        family_id_to_lang_tags = get_family_id_to_lang_tags(
            lang_tag_to_family_ids, families)
        if 'family_id_to_lang_tags' in debug:
            print '\nfamily id to lang tags'
            for family_id, lang_tags in sorted(
                    family_id_to_lang_tags.iteritems()):
                print '%s: %s' % (family_id, ','.join(sorted(lang_tags)))

        family_id_to_regions = get_family_id_to_regions(
            region_to_family_ids, families)

        family_id_to_default_lang_tag = get_family_id_to_default_lang_tag(
            family_id_to_lang_tags)
        if 'family_id_to_default_lang_tag' in debug:
            print '\nfamily id to default lang tag'
            for family_id, lang_tag in family_id_to_default_lang_tag.iteritems(
            ):
                print family_id, lang_tag

        used_lang_tags = get_used_lang_tags(
            lang_tag_to_family_ids.keys(),
            family_id_to_default_lang_tag.values())
        lang_tag_to_sample_data = get_lang_tag_to_sample_data(used_lang_tags)

        # find the samples that can't be displayed.
        tested_keys = set()
        failed_keys = set()
        family_langs_to_remove = {}
        for lang_tag in sorted(lang_tag_to_sample_data):
            sample_info = lang_tag_to_sample_data[lang_tag]
            sample = sample_info[1]
            sample_key = sample_info[3]

            for family_id in sorted(lang_tag_to_family_ids[lang_tag]):
                full_key = sample_key + '-' + family_id
                if full_key in tested_keys:
                    if full_key in failed_keys:
                        print 'failed sample %s lang %s' % (full_key, lang_tag)
                        if family_id not in family_langs_to_remove:
                            family_langs_to_remove[family_id] = set()
                        family_langs_to_remove[family_id].add(lang_tag)
                    continue

                failed_cps = set()
                tested_keys.add(full_key)
                charset = families[family_id].charset
                for cp in sample:
                    if ord(cp) in [
                            0xa, 0x28, 0x29, 0x2c, 0x2d, 0x2e, 0x3b, 0x5b,
                            0x5d, 0x2010
                    ]:
                        continue
                    if ord(cp) not in charset:
                        failed_cps.add(ord(cp))
                if failed_cps:
                    print 'sample %s cannot be displayed in %s (lang %s):\n  %s' % (
                        sample_key, family_id, lang_tag, '\n  '.join(
                            '%04x (%s)' % (cp, unichr(cp))
                            for cp in sorted(failed_cps)))
                    failed_keys.add(full_key)
                    if family_id not in family_langs_to_remove:
                        family_langs_to_remove[family_id] = set()
                    family_langs_to_remove[family_id].add(lang_tag)

        for family_id in sorted(family_langs_to_remove):
            langs_to_remove = family_langs_to_remove[family_id]
            print 'remove from %s: %s' % (family_id, ','.join(
                sorted(langs_to_remove)))

            family_id_to_lang_tags[family_id] -= langs_to_remove
            default_lang_tag = family_id_to_default_lang_tag[family_id]
            if default_lang_tag in langs_to_remove:
                print '!removing default lang tag %s for family %s' % (
                    default_lang_tag, family_id)
            for lang in langs_to_remove:
                lang_tag_to_family_ids[lang] -= set([family_id])

        region_data = get_region_lat_lng_data(region_to_family_ids.keys())

        lang_tag_sort_order = get_lang_tag_sort_order(
            lang_tag_to_family_ids.keys())

        if self.no_build:
            print 'skipping build output'
            return

        # build outputs
        if self.no_zips:
            print 'skipping zip output'
        else:
            family_zip_info = self.build_zips(families)
            universal_zip_info = self.build_universal_zips(families)

            # build outputs not used by the json but linked to from the web page
            self.build_ttc_zips()

        if self.no_css:
            print 'skipping css output'
        else:
            family_css_info = self.build_css(families)

        if self.no_data or self.no_zips or self.no_css:
            reason = '' if self.no_data else 'no zips' if self.no_zips else 'no css'
            print 'skipping data output%s' % reason
        else:
            self.build_data_json(families, family_zip_info, universal_zip_info,
                                 family_id_to_lang_tags, family_id_to_regions,
                                 lang_tag_to_family_ids, region_to_family_ids)

            self.build_families_json(families, family_id_to_lang_tags,
                                     family_id_to_default_lang_tag,
                                     family_id_to_regions, family_css_info,
                                     lang_tag_sort_order)

            self.build_misc_json(lang_tag_to_sample_data, region_data)

        if self.no_images:
            print 'skipping image output'
        else:
            self.build_images(families, family_id_to_lang_tags,
                              family_id_to_default_lang_tag,
                              lang_tag_to_sample_data)
Exemple #11
0
    def generate(self):
        if self.clean:
            self.clean_target_dir()

        if not self.no_build:
            self.ensure_target_dirs_exist()

        # debug/print
        # ['families', 'script_to_family_ids', 'used_lang_data',
        #  'family_id_to_lang_scrs', 'family_id_to_default_lang_scr']
        debug = frozenset([])

        def use_in_web(font):
            return (not font.subset and not font.is_UI
                    and not font.fmt == 'ttc'
                    and not font.script in {'CJK', 'HST', 'Qaae'}
                    and not font.family in {'Arimo', 'Cousine', 'Tinos'})

        fonts = [
            font for font in noto_fonts.get_noto_fonts() if use_in_web(font)
        ]
        families = noto_fonts.get_families(fonts)

        if 'families' in debug:
            print '\nfamilies'
            for family_id, family in sorted(families.iteritems()):
                print family_id, family.rep_member.script

        script_to_family_ids = get_script_to_family_ids(families)
        if 'script_to_family_ids' in debug:
            print '\nscript to family ids'
            for script, family_ids in sorted(script_to_family_ids.iteritems()):
                print script, family_ids

        all_lang_scrs = set(
            ['und-' + script for script in script_to_family_ids])
        all_lang_scrs.update(lang_data.lang_scripts())

        lang_scr_to_sample_infos = {}
        for lang_scr in all_lang_scrs:
            lang, script = lang_scr.split('-')
            if not script in script_to_family_ids:
                print 'no family supports script in %s' % lang_scr
                continue

            rtl = cldr_data.is_rtl(lang_scr)
            sample_infos = get_sample_infos(lang_scr, rtl)
            if not sample_infos:
                continue

            lang_scr_to_sample_infos[lang_scr] = sample_infos

        if 'lang_scr_to_sample_infos' in debug:
            print '\nlang+script to sample infos'
            for lang_scr, info_list in sorted(
                    lang_scr_to_sample_infos.iteritems()):
                for info in info_list:
                    print '%s key: %s rtl: %s attrib: %s len: %d' % (
                        lang_scr, info[3], info[0], info[2], len(info[1]))

        family_id_to_lang_scrs = get_family_id_to_lang_scrs(
            lang_scr_to_sample_infos.keys(), script_to_family_ids)

        family_id_to_lang_scr_to_sample_key, sample_key_to_info = get_family_id_to_lang_scr_to_sample_key(
            family_id_to_lang_scrs, families, lang_scr_to_sample_infos)

        family_id_to_regions = get_family_id_to_regions(
            family_id_to_lang_scr_to_sample_key)
        region_to_family_ids = get_region_to_family_ids(family_id_to_regions)

        family_id_to_default_lang_scr = get_family_id_to_default_lang_scr(
            family_id_to_lang_scrs, families)
        if 'family_id_to_default_lang_scr' in debug:
            print '\nfamily id to default lang scr'
            for family_id, lang_scr in family_id_to_default_lang_scr.iteritems(
            ):
                print family_id, lang_scr

        region_data = get_region_lat_lng_data(region_to_family_ids.keys())

        lang_scrs = get_named_lang_scrs(family_id_to_lang_scr_to_sample_key)
        lang_scr_sort_order = get_lang_scr_sort_order(lang_scrs)

        # sanity checks
        # all families have languages, and all those have samples.
        # all families have a default language, and that is in the sample list
        error_list = []
        for family in families.values():
            family_id = family.family_id
            if not family_id in family_id_to_lang_scr_to_sample_key:
                error_list.append('no entry for family %s' % family_id)
                continue

            lang_scr_to_sample_key = family_id_to_lang_scr_to_sample_key[
                family_id]
            if not lang_scr_to_sample_key:
                error_list.append('no langs for family %s' % family_id)
                continue

            for lang_scr in lang_scr_to_sample_key:
                sample_key = lang_scr_to_sample_key[lang_scr]
                if not sample_key:
                    error_list.append(
                        'no sample key for lang %s in family %s' %
                        (lang_scr, sample_key))
                    continue
                if not sample_key in sample_key_to_info:
                    error_list.append('no sample for sample key: %s' %
                                      sample_key)

            if not family_id in family_id_to_default_lang_scr:
                error_list.append('no default lang for family %s' % family_id)
                continue
            default_lang_scr = family_id_to_default_lang_scr[family_id]
            if not default_lang_scr in lang_scr_to_sample_key:
                error_list.append(
                    'default lang %s not in samples for family %s' %
                    (default_lang_scr, family_id))

        if error_list:
            print 'Errors:\n' + '\n  '.join(error_list)

        if error_list or self.no_build:
            print 'skipping build output'
            return

        # build outputs
        if self.no_zips:
            print 'skipping zip output'
        else:
            family_zip_info = self.build_zips(families)
            universal_zip_info = self.build_universal_zips(families)

            # build outputs not used by the json but linked to from the web page
            self.build_ttc_zips()

        if self.no_css:
            print 'skipping css output'
        else:
            family_css_info = self.build_css(families)

        if self.no_data:
            print 'skipping data output%s' % reason
        else:
            self.build_data_json(family_id_to_lang_scr_to_sample_key, families,
                                 family_zip_info, universal_zip_info,
                                 family_id_to_regions, region_to_family_ids)

            self.build_families_json(family_id_to_lang_scr_to_sample_key,
                                     families, family_id_to_default_lang_scr,
                                     family_id_to_regions, family_css_info,
                                     lang_scr_sort_order)

            self.build_misc_json(sample_key_to_info, region_data)

        if self.no_images:
            print 'skipping image output'
        else:
            self.build_images(family_id_to_lang_scr_to_sample_key, families,
                              family_id_to_default_lang_scr,
                              sample_key_to_info)
  def generate(self):
    if self.clean:
      self.clean_target_dir()

    if not self.no_build:
      self.ensure_target_dirs_exist()

    # debug/print
    # ['families', 'script_to_family_ids', 'used_lang_data',
    #  'family_id_to_lang_tags', 'family_id_to_default_lang_tag']
    debug = frozenset([])

    fonts = noto_fonts.get_noto_fonts()
    families = noto_fonts.get_families(fonts)

    if 'families' in debug:
      print '\nfamilies'
      for family_id, family in sorted(families.iteritems()):
        print family_id, family.rep_member.script

    script_to_family_ids = get_script_to_family_ids(families)
    if 'script_to_family_ids' in debug:
      print '\nscript to family ids'
      for script, family_ids in sorted(script_to_family_ids.iteritems()):
        print script, family_ids

    supported_scripts = set(script_to_family_ids.keys())
    used_lang_data = get_used_lang_data(supported_scripts)
    if 'used_lang_data' in debug:
      print '\nused lang data'
      for lang, data in sorted(used_lang_data.iteritems()):
        used = ', '.join(data[0])
        unused = ', '.join(data[1])
        if unused:
          unused = '(' + unused + ')'
          if used:
            unused = ' ' + unused
        print '%s: %s%s' % (lang, used, unused)

    langs_to_delete = []
    for lang in used_lang_data.keys():
      if not cldr_data.get_english_language_name(lang):
        langs_to_delete.append(lang)
    if langs_to_delete:
      print 'deleting languages with no english name: %s' % langs_to_delete
      for lang in langs_to_delete:
        del used_lang_data[lang]

    lang_tag_to_family_ids = get_lang_tag_to_family_ids(used_lang_data, script_to_family_ids)

    region_to_family_ids = get_region_to_family_ids(script_to_family_ids)

    family_id_to_lang_tags = get_family_id_to_lang_tags(lang_tag_to_family_ids, families)
    if 'family_id_to_lang_tags' in debug:
      print '\nfamily id to lang tags'
      for family_id, lang_tags in sorted(family_id_to_lang_tags.iteritems()):
        print '%s: %s' % (family_id, ','.join(sorted(lang_tags)))

    family_id_to_regions = get_family_id_to_regions(region_to_family_ids, families)

    family_id_to_default_lang_tag = get_family_id_to_default_lang_tag(
        family_id_to_lang_tags)
    if 'family_id_to_default_lang_tag' in debug:
      print '\nfamily id to default lang tag'
      for family_id, lang_tag in family_id_to_default_lang_tag.iteritems():
        print family_id, lang_tag

    used_lang_tags = get_used_lang_tags(
        lang_tag_to_family_ids.keys(), family_id_to_default_lang_tag.values())
    lang_tag_to_sample_data = get_lang_tag_to_sample_data(used_lang_tags)

    # find the samples that can't be displayed.
    tested_keys = set()
    failed_keys = set()
    family_langs_to_remove = {}
    for lang_tag in sorted(lang_tag_to_sample_data):
      sample_info = lang_tag_to_sample_data[lang_tag]
      sample = sample_info[1]
      sample_key = sample_info[3]

      for family_id in sorted(lang_tag_to_family_ids[lang_tag]):
        full_key = sample_key + '-' + family_id
        if full_key in tested_keys:
          if full_key in failed_keys:
            print 'failed sample %s lang %s' % (full_key, lang_tag)
            if family_id not in family_langs_to_remove:
              family_langs_to_remove[family_id] = set()
            family_langs_to_remove[family_id].add(lang_tag)
          continue

        failed_cps = set()
        tested_keys.add(full_key)
        charset = families[family_id].charset
        for cp in sample:
          if ord(cp) in [0xa, 0x28, 0x29, 0x2c, 0x2d, 0x2e, 0x3b, 0x5b, 0x5d, 0x2010]:
            continue
          if ord(cp) not in charset:
            failed_cps.add(ord(cp))
        if failed_cps:
          print 'sample %s cannot be displayed in %s (lang %s):\n  %s' % (
              sample_key, family_id, lang_tag,
              '\n  '.join('%04x (%s)' % (cp, unichr(cp)) for cp in sorted(failed_cps)))
          failed_keys.add(full_key)
          if family_id not in family_langs_to_remove:
            family_langs_to_remove[family_id] = set()
          family_langs_to_remove[family_id].add(lang_tag)

    for family_id in sorted(family_langs_to_remove):
      langs_to_remove = family_langs_to_remove[family_id]
      print 'remove from %s: %s' % (family_id, ','.join(sorted(langs_to_remove)))

      family_id_to_lang_tags[family_id] -= langs_to_remove
      default_lang_tag = family_id_to_default_lang_tag[family_id]
      if default_lang_tag in langs_to_remove:
        print '!removing default lang tag %s for family %s' % (
            default_lang_tag, family_id)
      for lang in langs_to_remove:
        lang_tag_to_family_ids[lang] -= set([family_id])

    region_data = get_region_lat_lng_data(region_to_family_ids.keys())

    lang_tag_sort_order = get_lang_tag_sort_order(lang_tag_to_family_ids.keys())

    if self.no_build:
      print 'skipping build output'
      return

    # build outputs
    if self.no_zips:
      print 'skipping zip output'
    else:
      family_zip_info = self.build_zips(families)
      universal_zip_info = self.build_universal_zips(families)

      # build outputs not used by the json but linked to from the web page
      self.build_ttc_zips()

    if self.no_css:
      print 'skipping css output'
    else:
      family_css_info = self.build_css(families)

    if self.no_data or self.no_zips or self.no_css:
      reason = '' if self.no_data else 'no zips' if self.no_zips else 'no css'
      print 'skipping data output%s' % reason
    else:
      self.build_data_json(families, family_zip_info, universal_zip_info,
                           family_id_to_lang_tags, family_id_to_regions,
                           lang_tag_to_family_ids, region_to_family_ids)

      self.build_families_json(families, family_id_to_lang_tags,
                               family_id_to_default_lang_tag,
                               family_id_to_regions, family_css_info,
                               lang_tag_sort_order)

      self.build_misc_json(lang_tag_to_sample_data, region_data)

    if self.no_images:
      print 'skipping image output'
    else:
      self.build_images(families, family_id_to_lang_tags,
                        family_id_to_default_lang_tag, lang_tag_to_sample_data)
  def generate(self):
    if self.clean:
      self.clean_target_dir()

    if not self.no_build:
      self.ensure_target_dirs_exist()

    def use_in_web(font):
      return (not font.subset and
              not font.fmt == 'ttc' and
              not font.script in {'CJK', 'HST'} and
              not font.family in {'Arimo', 'Cousine', 'Tinos'})
    fonts = filter(use_in_web, noto_fonts.get_noto_fonts())
    families = noto_fonts.get_families(fonts)

    check_families(families)

    if 'families' in self.debug:
      print '\n#debug families'
      for family_id, family in sorted(families.iteritems()):
        print '%s (%s, %s)' % (
            family_id, family.name, noto_fonts.get_family_filename(family))
        if family.hinted_members:
          print '  hinted: %s' % ', '.join(sorted(
              [path.basename(m.filepath) for m in family.hinted_members]))
        if family.unhinted_members:
          print '  unhinted: %s' % ', '.join(sorted(
              [path.basename(m.filepath) for m in family.unhinted_members]))

    script_to_family_ids = get_script_to_family_ids(families)
    if 'script_to_family_ids' in self.debug:
      print '\n#debug script to family ids'
      for script, family_ids in sorted(script_to_family_ids.iteritems()):
        print '%s: %s' % (script, ', '.join(sorted(family_ids)))

    all_lang_scrs = set(['und-' + script for script in script_to_family_ids])
    all_lang_scrs.update(lang_data.lang_scripts())

    lang_scr_to_sample_infos = {}
    for lang_scr in all_lang_scrs:
      lang, script = lang_scr.split('-')
      if not script in script_to_family_ids:
        print 'no family supports script in %s' % lang_scr
        continue

      sample_infos = get_sample_infos(lang_scr)
      if not sample_infos:
        continue

      lang_scr_to_sample_infos[lang_scr] = sample_infos

    if 'lang_scr_to_sample_infos' in self.debug:
      print '\n#debug lang+script to sample infos'
      for lang_scr, info_list in sorted(lang_scr_to_sample_infos.iteritems()):
        for info in info_list:
          print '%s: %s, %s, len %d' % (
              lang_scr, info[2], info[1], len(info[0]))

    family_id_to_lang_scrs = get_family_id_to_lang_scrs(
        lang_scr_to_sample_infos.keys(), script_to_family_ids)
    if 'family_id_to_lang_scrs' in self.debug:
      print '\n#debug family id to list of lang+script'
      for family_id, lang_scrs in sorted(family_id_to_lang_scrs.iteritems()):
        print '%s: (%d) %s' % (
            family_id, len(lang_scrs), ' '.join(sorted(lang_scrs)))

    family_id_to_lang_scr_to_sample_key, sample_key_to_info = (
        get_family_id_to_lang_scr_to_sample_key(
            family_id_to_lang_scrs, families, lang_scr_to_sample_infos))
    if 'family_id_to_lang_scr_to_sample_key' in self.debug:
      print '\n#debug family id to map from lang+script to sample key'
      for family_id, lang_scr_to_sample_key in sorted(
          family_id_to_lang_scr_to_sample_key.iteritems()):
        print '%s (%d):' % (family_id, len(lang_scr_to_sample_key))
        for lang_scr, sample_key in sorted(lang_scr_to_sample_key.iteritems()):
          print '  %s: %s' % (lang_scr, sample_key)
    if 'sample_key_to_info' in self.debug:
      print '\n#debug sample key to sample info'
      for sample_key, info in sorted(sample_key_to_info.iteritems()):
        print '%s: %s, len %d' % (
            sample_key, info[1], len(info[0]))

    family_id_to_regions = get_family_id_to_regions(
        family_id_to_lang_scr_to_sample_key)
    if 'family_id_to_regions' in self.debug:
      print '\n#debug family id to regions'
      for family_id, regions in sorted(family_id_to_regions.iteritems()):
        print '%s: (%d) %s' % (
            family_id, len(regions), ', '.join(sorted(regions)))

    region_to_family_ids = get_region_to_family_ids(family_id_to_regions)
    if 'region_to_family_ids' in self.debug:
      print '\n#debug region to family ids'
      for region, family_ids in sorted(region_to_family_ids.iteritems()):
        print '%s: (%d) %s' % (
            region, len(family_ids), ', '.join(sorted(family_ids)))

    family_id_to_default_lang_scr = get_family_id_to_default_lang_scr(
        family_id_to_lang_scrs, families)
    if 'family_id_to_default_lang_scr' in self.debug:
      print '\n#debug family id to default lang scr'
      for family_id, lang_scr in sorted(
          family_id_to_default_lang_scr.iteritems()):
        print '%s: %s' % (family_id, lang_scr)

    region_data = get_region_lat_lng_data(region_to_family_ids.keys())

    lang_scrs = get_named_lang_scrs(family_id_to_lang_scr_to_sample_key)
    lang_scr_sort_order = get_lang_scr_sort_order(lang_scrs)

    # sanity checks
    # all families have languages, and all those have samples.
    # all families have a default language, and that is in the sample list
    error_list = []
    for family in families.values():
      family_id = family.family_id
      if not family_id in family_id_to_lang_scr_to_sample_key:
        error_list.append('no entry for family %s' % family_id)
        continue

      lang_scr_to_sample_key = family_id_to_lang_scr_to_sample_key[family_id]
      if not lang_scr_to_sample_key:
        error_list.append('no langs for family %s' % family_id)
        continue

      for lang_scr in lang_scr_to_sample_key:
        sample_key = lang_scr_to_sample_key[lang_scr]
        if not sample_key:
          error_list.append(
              'no sample key for lang %s in family %s' % (lang_scr, sample_key))
          continue
        if not sample_key in sample_key_to_info:
          error_list.append('no sample for sample key: %s' % sample_key)

      if not family_id in family_id_to_default_lang_scr:
        error_list.append('no default lang for family %s' % family_id)
        continue
      default_lang_scr = family_id_to_default_lang_scr[family_id]
      if not default_lang_scr in lang_scr_to_sample_key:
        error_list.append('default lang %s not in samples for family %s' %
                          (default_lang_scr, family_id))

    if error_list:
      print 'Errors:\n' + '\n  '.join(error_list)

    if error_list or self.no_build:
      print 'skipping build output'
      return

    # build outputs
    # zips are required for data
    if self.no_zips and self.no_data:
      print 'skipping zip output'
    else:
      family_zip_info = self.build_zips(families)
      universal_zip_info = self.build_universal_zips(families)

      # build outputs not used by the json but linked to from the web page
      if not self.no_zips:
        self.build_ttc_zips()

    if self.no_css:
      print 'skipping css output'
    else:
      family_css_info = self.build_css(families)

    if self.no_data:
      print 'skipping data output'
    else:
      self.build_data_json(family_id_to_lang_scr_to_sample_key,
                           families, family_zip_info, universal_zip_info,
                           family_id_to_regions, region_to_family_ids)

      self.build_families_json(family_id_to_lang_scr_to_sample_key,
                               families, family_id_to_default_lang_scr,
                               family_id_to_regions, family_css_info,
                               lang_scr_sort_order)

      self.build_misc_json(sample_key_to_info, region_data)

    if self.no_images:
      print 'skipping image output'
    else:
      self.build_images(family_id_to_lang_scr_to_sample_key,
                        families,  family_id_to_default_lang_scr,
                        sample_key_to_info)