diff --git a/README.md b/README.md index d91743d..c005292 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,7 @@ Check out the [Wiki](https://github.com/DenverCoder1/github-readme-youtube-cards | `commit_message` | The commit message to use for the commit | "docs(readme): Update YouTube cards" | | `readme_path` | The path to the README file | "README.md" | | `output_only` | Whether to skip writing to the readme file | "false" | +| `output_type` | The output syntax to use ("markdown" or "html") | "markdown" | 🔑 YouTube API Key required. See [Setting Up the Action with a YouTube API Key](https://github.com/DenverCoder1/github-readme-youtube-cards/wiki/Setting-Up-the-Action-with-a-YouTube-API-Key) in the wiki for more information. diff --git a/action.py b/action.py index 80891f2..196b994 100644 --- a/action.py +++ b/action.py @@ -24,6 +24,7 @@ def __init__( theme_context_light: Dict[str, str], theme_context_dark: Dict[str, str], show_duration: bool, + output_type: str, ): self._base_url = base_url self._channel_id = channel_id @@ -37,6 +38,7 @@ def __init__( self._theme_context_light = theme_context_light self._theme_context_dark = theme_context_dark self._show_duration = show_duration + self._output_type = output_type self._youtube_data = {} @staticmethod @@ -117,17 +119,33 @@ def parse_video(self, video: Dict[str, Any]) -> str: content_details = self._youtube_data[video_id]["contentDetails"] if self._show_duration: params["duration"] = self.parse_iso8601_duration(content_details["duration"]) - # translate video to standard markdown - backslash_escaped_title = params["title"].replace('"', '\\"') - # if theme context is set, create two versions with theme context specified - if self._theme_context_dark or self._theme_context_light: - dark_params = params | self._theme_context_dark - light_params = params | self._theme_context_light - return ( - f'[![{params["title"]}]({self._base_url}?{urllib.parse.urlencode(dark_params)} "{backslash_escaped_title}")]({video["link"]}#gh-dark-mode-only)' - f'[![{params["title"]}]({self._base_url}?{urllib.parse.urlencode(light_params)} "{backslash_escaped_title}")]({video["link"]}#gh-light-mode-only)' - ) - return f'[![{params["title"]}]({self._base_url}?{urllib.parse.urlencode(params)} "{backslash_escaped_title}")]({video["link"]})' + + dark_params = params | self._theme_context_dark + light_params = params | self._theme_context_light + + if self._output_type == "html": + # translate video to html + html_escaped_title = params["title"].replace('"', """) + if self._theme_context_dark or self._theme_context_light: + return ( + f'\n' + f" \n" + f' \n' + f' {html_escaped_title}\n' + " \n" + "" + ) + return f'{html_escaped_title}' + else: + # translate video to standard markdown + backslash_escaped_title = params["title"].replace('"', '\\"') + # if theme context is set, create two versions with theme context specified + if self._theme_context_dark or self._theme_context_light: + return ( + f'[![{params["title"]}]({self._base_url}?{urllib.parse.urlencode(dark_params)} "{backslash_escaped_title}")]({video["link"]}#gh-dark-mode-only)' + f'[![{params["title"]}]({self._base_url}?{urllib.parse.urlencode(light_params)} "{backslash_escaped_title}")]({video["link"]}#gh-light-mode-only)' + ) + return f'[![{params["title"]}]({self._base_url}?{urllib.parse.urlencode(params)} "{backslash_escaped_title}")]({video["link"]})' def parse_videos(self) -> str: """Parse video feed and return the contents for the readme""" @@ -253,6 +271,13 @@ def update(readme_path: str, comment_tag: str, replace_content: str): default="false", choices=("true", "false"), ) + parser.add_argument( + "--output-type", + dest="output_type", + help="The type of output to be rendered by the action", + default="markdown", + choices=("html", "markdown"), + ) args = parser.parse_args() if args.show_duration == "true" and not args.youtube_api_key: @@ -271,6 +296,7 @@ def update(readme_path: str, comment_tag: str, replace_content: str): theme_context_light=json.loads(args.theme_context_light), theme_context_dark=json.loads(args.theme_context_dark), show_duration=args.show_duration == "true", + output_type=args.output_type, ) video_content = video_parser.parse_videos() diff --git a/action.yml b/action.yml index 8bd6c6f..b5f66e8 100644 --- a/action.yml +++ b/action.yml @@ -77,6 +77,10 @@ inputs: description: "Whether to return the section markdown as output instead of writing to the file" required: false default: "false" + output_type: + description: "The type of output to be rendered by the action ('markdown' or 'html')" + required: false + default: "markdown" outputs: markdown: @@ -118,6 +122,7 @@ runs: --theme-context-dark '${{ inputs.theme_context_dark }}' \ --readme-path "${{ inputs.readme_path }}" \ --output-only "${{ inputs.output_only }}" \ + --output-type "${{ inputs.output_type }}" \ ) || exit 1 echo "::set-output name=markdown::$(echo $UPDATE)" diff --git a/tests/test_action.py b/tests/test_action.py index 0b7d72e..8e70ae6 100644 --- a/tests/test_action.py +++ b/tests/test_action.py @@ -16,6 +16,7 @@ theme_context_light={}, theme_context_dark={}, show_duration=False, + output_type="markdown", ) @@ -65,6 +66,28 @@ def test_parse_videos_with_theme_context(): assert all(re.match(line_regex, line) for line in videos.splitlines()) +def test_parse_videos_html(): + video_parser._output_type = "html" + videos = video_parser.parse_videos() + + assert len(videos.splitlines()) == 36 + + anchor_tag_regex = r"" + picture_tag_regex = r"" + img_tag_regex = f'.*' + assert all(re.match(anchor_tag_regex, line) for line in videos.splitlines()[::6]) + assert all(re.match(picture_tag_regex, line.strip()) for line in videos.splitlines()[1::3]) + assert all(re.match(img_tag_regex, line.strip()) for line in videos.splitlines()[3::6]) + + assert "https://ytcards.demolab.com/?id=" in videos + assert "title=" in videos + assert "timestamp=" in videos + assert "background_color=" in videos + assert "title_color=" in videos + assert "stats_color=" in videos + assert "width=" in videos + + def test_update_file(): path = "./tests/README.md" # create a file to test with