docs: def _iter_modules(modules, class_name, path, ignored_formats, args):
      """
      This huge function generates a hierarchy with hopefully more
      clear structure of modules/sections/lectures.
      """
      file_formats = args.file_formats
      lecture_filter = args.lecture_filter
      resource_filter = args.resource_filter
      section_filter = args.section_filter
      verbose_dirs = args.verbose_dirs
      combined_section_lectures_nums = args.combined_section_lectures_nums
  
      class IterModule(object):
          def __init__(self, index, module):
              self.index = index
              self.name = '%02d_%s' % (index + 1, module[0])
              self._module = module
  
          @property
          def sections(self):
              sections = self._module[1]
              for (secnum, (section, lectures)) in enumerate(sections):
                  if section_filter and not re.search(section_filter, section):
                      logging.debug('Skipping b/c of sf: %s %s',
                                    section_filter, section)
                      continue
  
                  yield IterSection(self, secnum, section, lectures)
  
      class IterSection(object):
          def __init__(self, module_iter, secnum, section, lectures):
              self.index = secnum
              self.name = '%02d_%s' % (secnum, section)
              self.dir = os.path.join(
                  path, class_name, module_iter.name,
                  format_section(secnum + 1, section,
                                 class_name, verbose_dirs))
              self._lectures = lectures
  
          @property
          def lectures(self):
              for (lecnum, (lecname, lecture)) in enumerate(self._lectures):
                  if lecture_filter and not re.search(lecture_filter, lecname):
                      logging.debug('Skipping b/c of lf: %s %s',
                                    lecture_filter, lecname)
                      continue
  
                  yield IterLecture(self, lecnum, lecname, lecture)
  
      class IterLecture(object):
          def __init__(self, section_iter, lecnum, lecname, lecture):
              self.index = lecnum
              self.name = lecname
              self._lecture = lecture
              self._section_iter = section_iter
  
          def filename(self, fmt, title):
              lecture_filename = get_lecture_filename(
                  combined_section_lectures_nums,
                  self._section_iter.dir, self._section_iter.index,
                  self.index, self.name, title, fmt)
              return lecture_filename
  
          @property
          def resources(self):
              resources_to_get = find_resources_to_get(
                  self._lecture, file_formats, resource_filter,
                  ignored_formats)
  
              for fmt, url, title in resources_to_get:
                  yield IterResource(fmt, url, title)
  
      class IterResource(object):
          def __init__(self, fmt, url, title):
              self.fmt = fmt
              self.url = url
              self.title = title
  
      for index, module in enumerate(modules):
          yield IterModule(index, module)