Parse a Coursera on-demand course listing/syllabus page.

        @return: Tuple of (bool, list), where bool indicates whether
            there was at least on error while parsing syllabus, the list
            is a list of parsed modules.
        @rtype: (bool, list)

def _parse_on_demand_syllabus(self, course_name, page, reverse=False,
                                  unrestricted_filenames=False,
                                  subtitle_language='en',
                                  video_resolution=None,
                                  download_quizzes=False,
                                  mathjax_cdn_url=None,
                                  download_notebooks=False
                                  ):
        """
        Parse a Coursera on-demand course listing/syllabus page.

        @return: Tuple of (bool, list), where bool indicates whether
            there was at least on error while parsing syllabus, the list
            is a list of parsed modules.
        @rtype: (bool, list)
        """

        dom = json.loads(page)
        class_id = dom['elements'][0]['id']

        logging.info('Parsing syllabus of on-demand course (id=%s). '
                     'This may take some time, please be patient ...',
                     class_id)
        modules = []

        json_modules = dom['linked']['onDemandCourseMaterialItems.v2']
        course = CourseraOnDemand(
            session=self._session, course_id=class_id,
            course_name=course_name,
            unrestricted_filenames=unrestricted_filenames,
            mathjax_cdn_url=mathjax_cdn_url)
        course.obtain_user_id()
        ondemand_material_items = OnDemandCourseMaterialItemsV1.create(
            session=self._session, course_name=course_name)

        if is_debug_run():
            spit_json(dom, '%s-syllabus-raw.json' % course_name)
            spit_json(json_modules, '%s-material-items-v2.json' % course_name)
            spit_json(ondemand_material_items._items,
                      '%s-course-material-items.json' % course_name)

        error_occurred = False

        all_modules = ModulesV1.from_json(
            dom['linked']['onDemandCourseMaterialModules.v1'])
        all_lessons = LessonsV1.from_json(
            dom['linked']['onDemandCourseMaterialLessons.v1'])
        all_items = ItemsV2.from_json(
            dom['linked']['onDemandCourseMaterialItems.v2'])

        for module in all_modules:
            logging.info('Processing module  %s', module.slug)
            lessons = []
            for section in module.children(all_lessons):
                logging.info('Processing section     %s', section.slug)
                lectures = []
                available_lectures = section.children(all_items)

                # Certain modules may be empty-looking programming assignments
                # e.g. in data-structures, algorithms-on-graphs ondemand
                # courses
                if not available_lectures:
                    lecture = ondemand_material_items.get(section.id)
                    if lecture is not None:
                        available_lectures = [lecture]

                for lecture in available_lectures:
                    typename = lecture.type_name

                    logging.info('Processing lecture         %s (%s)',
                                 lecture.slug, typename)
                    # Empty dictionary means there were no data
                    # None means an error occurred
                    links = {}

                    if typename == 'lecture':
                        # lecture_video_id = lecture['content']['definition']['videoId']
                        # assets = lecture['content']['definition'].get(
                        #     'assets', [])
                        lecture_video_id = lecture.id
                        # assets = []

                        links = course.extract_links_from_lecture(
                            class_id,
                            lecture_video_id, subtitle_language,
                            video_resolution)

                    elif typename == 'supplement':
                        links = course.extract_links_from_supplement(
                            lecture.id)

                    elif typename == 'phasedPeer':
                        links = course.extract_links_from_peer_assignment(
                            lecture.id)

                    elif typename in ('gradedProgramming', 'ungradedProgramming'):
                        links = course.extract_links_from_programming(
                            lecture.id)

                    elif typename == 'quiz':
                        if download_quizzes:
                            links = course.extract_links_from_quiz(
                                lecture.id)

                    elif typename == 'exam':
                        if download_quizzes:
                            links = course.extract_links_from_exam(
                                lecture.id)

                    elif typename == 'programming':
                        if download_quizzes:
                            links = course.extract_links_from_programming_immediate_instructions(
                                lecture.id)

                    elif typename == 'notebook':
                        if download_notebooks and not self._notebook_downloaded:
                            logging.warning(
                                'According to notebooks platform, content will be downloaded first')
                            links = course.extract_links_from_notebook(
                                lecture.id)
                            self._notebook_downloaded = True

                    else:
                        logging.info(
                            'Unsupported typename "%s" in lecture "%s" (lecture id "%s")',
                            typename, lecture.slug, lecture.id)
                        continue

                    if links is None:
                        error_occurred = True
                    elif links:
                        lectures.append((lecture.slug, links))

                if lectures:
                    lessons.append((section.slug, lectures))

            if lessons:
                modules.append((module.slug, lessons))

        if modules and reverse:
            modules.reverse()

        # Processing resources section
        json_references = course.extract_references_poll()
        references = []
        if json_references:
            logging.info('Processing resources')
            for json_reference in json_references:
                reference = []
                reference_slug = json_reference['slug']
                logging.info('Processing resource  %s',
                             reference_slug)

                links = course.extract_links_from_reference(
                    json_reference['shortId'])
                if links is None:
                    error_occurred = True
                elif links:
                    reference.append(('', links))

                if reference:
                    references.append((reference_slug, reference))

        if references:
            modules.append(("Resources", references))

        return error_occurred, modules